diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2023-09-02 21:17:18 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-12-08 17:34:50 +0000 |
commit | 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e (patch) | |
tree | 62f873df87c7c675557a179e0c4c83fe9f3087bc /contrib/llvm-project/lldb/source | |
parent | cf037972ea8863e2bab7461d77345367d2c1e054 (diff) | |
parent | 7fa27ce4a07f19b07799a767fc29416f3b625afb (diff) |
Diffstat (limited to 'contrib/llvm-project/lldb/source')
554 files changed, 18654 insertions, 17427 deletions
diff --git a/contrib/llvm-project/lldb/source/API/SBAttachInfo.cpp b/contrib/llvm-project/lldb/source/API/SBAttachInfo.cpp index edb4f7104d41..8ce1f1d65c49 100644 --- a/contrib/llvm-project/lldb/source/API/SBAttachInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBAttachInfo.cpp @@ -10,8 +10,10 @@ #include "Utils.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBListener.h" +#include "lldb/API/SBStructuredData.h" #include "lldb/Target/Process.h" #include "lldb/Utility/Instrumentation.h" +#include "lldb/Utility/ScriptedMetadata.h" using namespace lldb; using namespace lldb_private; @@ -92,7 +94,7 @@ void SBAttachInfo::SetResumeCount(uint32_t c) { const char *SBAttachInfo::GetProcessPluginName() { LLDB_INSTRUMENT_VA(this); - return m_opaque_sp->GetProcessPluginName(); + return ConstString(m_opaque_sp->GetProcessPluginName()).GetCString(); } void SBAttachInfo::SetProcessPluginName(const char *plugin_name) { @@ -251,3 +253,94 @@ void SBAttachInfo::SetListener(SBListener &listener) { m_opaque_sp->SetListener(listener.GetSP()); } + +SBListener SBAttachInfo::GetShadowListener() { + LLDB_INSTRUMENT_VA(this); + + lldb::ListenerSP shadow_sp = m_opaque_sp->GetShadowListener(); + if (!shadow_sp) + return SBListener(); + return SBListener(shadow_sp); +} + +void SBAttachInfo::SetShadowListener(SBListener &listener) { + LLDB_INSTRUMENT_VA(this, listener); + + ListenerSP listener_sp = listener.GetSP(); + if (listener_sp && listener.IsValid()) + listener_sp->SetShadow(true); + else + listener_sp = nullptr; + + m_opaque_sp->SetShadowListener(listener_sp); +} + +const char *SBAttachInfo::GetScriptedProcessClassName() const { + LLDB_INSTRUMENT_VA(this); + + ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); + + if (!metadata_sp || !*metadata_sp) + return nullptr; + + // Constify this string so that it is saved in the string pool. Otherwise it + // would be freed when this function goes out of scope. + ConstString class_name(metadata_sp->GetClassName().data()); + return class_name.AsCString(); +} + +void SBAttachInfo::SetScriptedProcessClassName(const char *class_name) { + LLDB_INSTRUMENT_VA(this, class_name); + + ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); + + if (!metadata_sp) + metadata_sp = std::make_shared<ScriptedMetadata>(class_name, nullptr); + else + metadata_sp = std::make_shared<ScriptedMetadata>(class_name, + metadata_sp->GetArgsSP()); + + m_opaque_sp->SetScriptedMetadata(metadata_sp); +} + +lldb::SBStructuredData SBAttachInfo::GetScriptedProcessDictionary() const { + LLDB_INSTRUMENT_VA(this); + + ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); + + SBStructuredData data; + if (!metadata_sp) + return data; + + lldb_private::StructuredData::DictionarySP dict_sp = metadata_sp->GetArgsSP(); + data.m_impl_up->SetObjectSP(dict_sp); + + return data; +} + +void SBAttachInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) { + LLDB_INSTRUMENT_VA(this, dict); + + if (!dict.IsValid() || !dict.m_impl_up) + return; + + StructuredData::ObjectSP obj_sp = dict.m_impl_up->GetObjectSP(); + + if (!obj_sp) + return; + + StructuredData::DictionarySP dict_sp = + std::make_shared<StructuredData::Dictionary>(obj_sp); + if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid) + return; + + ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); + + if (!metadata_sp) + metadata_sp = std::make_shared<ScriptedMetadata>("", dict_sp); + else + metadata_sp = std::make_shared<ScriptedMetadata>( + metadata_sp->GetClassName(), dict_sp); + + m_opaque_sp->SetScriptedMetadata(metadata_sp); +} diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp index 19b2a4376cf8..6631afb1483f 100644 --- a/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBreakpoint.cpp @@ -284,12 +284,12 @@ const char *SBBreakpoint::GetCondition() { LLDB_INSTRUMENT_VA(this); BreakpointSP bkpt_sp = GetSP(); - if (bkpt_sp) { - std::lock_guard<std::recursive_mutex> guard( - bkpt_sp->GetTarget().GetAPIMutex()); - return bkpt_sp->GetConditionText(); - } - return nullptr; + if (!bkpt_sp) + return nullptr; + + std::lock_guard<std::recursive_mutex> guard( + bkpt_sp->GetTarget().GetAPIMutex()); + return ConstString(bkpt_sp->GetConditionText()).GetCString(); } void SBBreakpoint::SetAutoContinue(bool auto_continue) { @@ -411,18 +411,17 @@ void SBBreakpoint::SetThreadName(const char *thread_name) { const char *SBBreakpoint::GetThreadName() const { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; BreakpointSP bkpt_sp = GetSP(); - if (bkpt_sp) { - std::lock_guard<std::recursive_mutex> guard( - bkpt_sp->GetTarget().GetAPIMutex()); - const ThreadSpec *thread_spec = - bkpt_sp->GetOptions().GetThreadSpecNoCreate(); - if (thread_spec != nullptr) - name = thread_spec->GetName(); - } + if (!bkpt_sp) + return nullptr; + + std::lock_guard<std::recursive_mutex> guard( + bkpt_sp->GetTarget().GetAPIMutex()); + if (const ThreadSpec *thread_spec = + bkpt_sp->GetOptions().GetThreadSpecNoCreate()) + return ConstString(thread_spec->GetName()).GetCString(); - return name; + return nullptr; } void SBBreakpoint::SetQueueName(const char *queue_name) { @@ -439,18 +438,17 @@ void SBBreakpoint::SetQueueName(const char *queue_name) { const char *SBBreakpoint::GetQueueName() const { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; BreakpointSP bkpt_sp = GetSP(); - if (bkpt_sp) { - std::lock_guard<std::recursive_mutex> guard( - bkpt_sp->GetTarget().GetAPIMutex()); - const ThreadSpec *thread_spec = - bkpt_sp->GetOptions().GetThreadSpecNoCreate(); - if (thread_spec) - name = thread_spec->GetQueueName(); - } + if (!bkpt_sp) + return nullptr; - return name; + std::lock_guard<std::recursive_mutex> guard( + bkpt_sp->GetTarget().GetAPIMutex()); + if (const ThreadSpec *thread_spec = + bkpt_sp->GetOptions().GetThreadSpecNoCreate()) + return ConstString(thread_spec->GetQueueName()).GetCString(); + + return nullptr; } size_t SBBreakpoint::GetNumResolvedLocations() const { @@ -645,7 +643,8 @@ SBError SBBreakpoint::SetScriptCallbackBody(const char *callback_body_text) { bkpt_sp->GetTarget() .GetDebugger() .GetScriptInterpreter() - ->SetBreakpointCommandCallback(bp_options, callback_body_text); + ->SetBreakpointCommandCallback(bp_options, callback_body_text, + /*is_callback=*/false); sb_error.SetError(error); } else sb_error.SetErrorString("invalid breakpoint"); diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp index a253530f5718..3c4aab6175c6 100644 --- a/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBreakpointLocation.cpp @@ -169,12 +169,12 @@ const char *SBBreakpointLocation::GetCondition() { LLDB_INSTRUMENT_VA(this); BreakpointLocationSP loc_sp = GetSP(); - if (loc_sp) { - std::lock_guard<std::recursive_mutex> guard( - loc_sp->GetTarget().GetAPIMutex()); - return loc_sp->GetConditionText(); - } - return nullptr; + if (!loc_sp) + return nullptr; + + std::lock_guard<std::recursive_mutex> guard( + loc_sp->GetTarget().GetAPIMutex()); + return ConstString(loc_sp->GetConditionText()).GetCString(); } void SBBreakpointLocation::SetAutoContinue(bool auto_continue) { @@ -263,7 +263,8 @@ SBBreakpointLocation::SetScriptCallbackBody(const char *callback_body_text) { .GetTarget() .GetDebugger() .GetScriptInterpreter() - ->SetBreakpointCommandCallback(bp_options, callback_body_text); + ->SetBreakpointCommandCallback(bp_options, callback_body_text, + /*is_callback=*/false); sb_error.SetError(error); } else sb_error.SetErrorString("invalid breakpoint"); @@ -365,12 +366,12 @@ const char *SBBreakpointLocation::GetThreadName() const { LLDB_INSTRUMENT_VA(this); BreakpointLocationSP loc_sp = GetSP(); - if (loc_sp) { - std::lock_guard<std::recursive_mutex> guard( - loc_sp->GetTarget().GetAPIMutex()); - return loc_sp->GetThreadName(); - } - return nullptr; + if (!loc_sp) + return nullptr; + + std::lock_guard<std::recursive_mutex> guard( + loc_sp->GetTarget().GetAPIMutex()); + return ConstString(loc_sp->GetThreadName()).GetCString(); } void SBBreakpointLocation::SetQueueName(const char *queue_name) { @@ -388,12 +389,12 @@ const char *SBBreakpointLocation::GetQueueName() const { LLDB_INSTRUMENT_VA(this); BreakpointLocationSP loc_sp = GetSP(); - if (loc_sp) { - std::lock_guard<std::recursive_mutex> guard( - loc_sp->GetTarget().GetAPIMutex()); - return loc_sp->GetQueueName(); - } - return nullptr; + if (!loc_sp) + return nullptr; + + std::lock_guard<std::recursive_mutex> guard( + loc_sp->GetTarget().GetAPIMutex()); + return ConstString(loc_sp->GetQueueName()).GetCString(); } bool SBBreakpointLocation::IsResolved() { diff --git a/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp b/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp index 796229d04ce4..7f63aaf6fa7d 100644 --- a/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBreakpointName.cpp @@ -199,7 +199,7 @@ const char *SBBreakpointName::GetName() const { if (!m_impl_up) return "<Invalid Breakpoint Name Object>"; - return m_impl_up->GetName(); + return ConstString(m_impl_up->GetName()).GetCString(); } void SBBreakpointName::SetEnabled(bool enable) { @@ -315,9 +315,9 @@ const char *SBBreakpointName::GetCondition() { return nullptr; std::lock_guard<std::recursive_mutex> guard( - m_impl_up->GetTarget()->GetAPIMutex()); + m_impl_up->GetTarget()->GetAPIMutex()); - return bp_name->GetOptions().GetConditionText(); + return ConstString(bp_name->GetOptions().GetConditionText()).GetCString(); } void SBBreakpointName::SetAutoContinue(bool auto_continue) { @@ -423,9 +423,10 @@ const char *SBBreakpointName::GetThreadName() const { return nullptr; std::lock_guard<std::recursive_mutex> guard( - m_impl_up->GetTarget()->GetAPIMutex()); + m_impl_up->GetTarget()->GetAPIMutex()); - return bp_name->GetOptions().GetThreadSpec()->GetName(); + return ConstString(bp_name->GetOptions().GetThreadSpec()->GetName()) + .GetCString(); } void SBBreakpointName::SetQueueName(const char *queue_name) { @@ -450,9 +451,10 @@ const char *SBBreakpointName::GetQueueName() const { return nullptr; std::lock_guard<std::recursive_mutex> guard( - m_impl_up->GetTarget()->GetAPIMutex()); + m_impl_up->GetTarget()->GetAPIMutex()); - return bp_name->GetOptions().GetThreadSpec()->GetQueueName(); + return ConstString(bp_name->GetOptions().GetThreadSpec()->GetQueueName()) + .GetCString(); } void SBBreakpointName::SetCommandLineCommands(SBStringList &commands) { @@ -496,7 +498,7 @@ const char *SBBreakpointName::GetHelpString() const { if (!bp_name) return ""; - return bp_name->GetHelp(); + return ConstString(bp_name->GetHelp()).GetCString(); } void SBBreakpointName::SetHelpString(const char *help_string) { @@ -593,11 +595,11 @@ SBBreakpointName::SetScriptCallbackBody(const char *callback_body_text) { m_impl_up->GetTarget()->GetAPIMutex()); BreakpointOptions &bp_options = bp_name->GetOptions(); - Status error = - m_impl_up->GetTarget() - ->GetDebugger() - .GetScriptInterpreter() - ->SetBreakpointCommandCallback(bp_options, callback_body_text); + Status error = m_impl_up->GetTarget() + ->GetDebugger() + .GetScriptInterpreter() + ->SetBreakpointCommandCallback( + bp_options, callback_body_text, /*is_callback=*/false); sb_error.SetError(error); if (!sb_error.Fail()) UpdateName(*bp_name); diff --git a/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp b/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp index 58920931bc5f..6e34b2f71b82 100644 --- a/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp +++ b/contrib/llvm-project/lldb/source/API/SBBroadcaster.cpp @@ -92,7 +92,7 @@ const char *SBBroadcaster::GetName() const { LLDB_INSTRUMENT_VA(this); if (m_opaque_ptr) - return m_opaque_ptr->GetBroadcasterName().GetCString(); + return ConstString(m_opaque_ptr->GetBroadcasterName()).GetCString(); return nullptr; } diff --git a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp index cd6ef3b23fd4..396c0eef0603 100644 --- a/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/API/SBCommandInterpreter.cpp @@ -33,6 +33,7 @@ using namespace lldb; using namespace lldb_private; +namespace lldb_private { class CommandPluginInterfaceImplementation : public CommandObjectParsed { public: CommandPluginInterfaceImplementation(CommandInterpreter &interpreter, @@ -73,13 +74,14 @@ protected: SBCommandReturnObject sb_return(result); SBCommandInterpreter sb_interpreter(&m_interpreter); SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this()); - bool ret = m_backend->DoExecute( - debugger_sb, command.GetArgumentVector(), sb_return); + bool ret = m_backend->DoExecute(debugger_sb, command.GetArgumentVector(), + sb_return); return ret; } std::shared_ptr<lldb::SBCommandPluginInterface> m_backend; std::optional<std::string> m_auto_repeat_command; }; +} // namespace lldb_private SBCommandInterpreter::SBCommandInterpreter(CommandInterpreter *interpreter) : m_opaque_ptr(interpreter) { @@ -118,6 +120,13 @@ bool SBCommandInterpreter::CommandExists(const char *cmd) { : false); } +bool SBCommandInterpreter::UserCommandExists(const char *cmd) { + LLDB_INSTRUMENT_VA(this, cmd); + + return (((cmd != nullptr) && IsValid()) ? m_opaque_ptr->UserCommandExists(cmd) + : false); +} + bool SBCommandInterpreter::AliasExists(const char *cmd) { LLDB_INSTRUMENT_VA(this, cmd); @@ -134,17 +143,24 @@ bool SBCommandInterpreter::IsActive() { bool SBCommandInterpreter::WasInterrupted() const { LLDB_INSTRUMENT_VA(this); - return (IsValid() ? m_opaque_ptr->WasInterrupted() : false); + return (IsValid() ? m_opaque_ptr->GetDebugger().InterruptRequested() : false); +} + +bool SBCommandInterpreter::InterruptCommand() { + LLDB_INSTRUMENT_VA(this); + + return (IsValid() ? m_opaque_ptr->InterruptCommand() : false); } const char *SBCommandInterpreter::GetIOHandlerControlSequence(char ch) { LLDB_INSTRUMENT_VA(this, ch); - return (IsValid() - ? m_opaque_ptr->GetDebugger() - .GetTopIOHandlerControlSequence(ch) - .GetCString() - : nullptr); + if (!IsValid()) + return nullptr; + + return ConstString( + m_opaque_ptr->GetDebugger().GetTopIOHandlerControlSequence(ch)) + .GetCString(); } lldb::ReturnStatus @@ -501,14 +517,16 @@ const char *SBCommandInterpreter::GetArgumentTypeAsCString( const lldb::CommandArgumentType arg_type) { LLDB_INSTRUMENT_VA(arg_type); - return CommandObject::GetArgumentTypeAsCString(arg_type); + return ConstString(CommandObject::GetArgumentTypeAsCString(arg_type)) + .GetCString(); } const char *SBCommandInterpreter::GetArgumentDescriptionAsCString( const lldb::CommandArgumentType arg_type) { LLDB_INSTRUMENT_VA(arg_type); - return CommandObject::GetArgumentDescriptionAsCString(arg_type); + return ConstString(CommandObject::GetArgumentDescriptionAsCString(arg_type)) + .GetCString(); } bool SBCommandInterpreter::EventIsCommandInterpreterEvent( diff --git a/contrib/llvm-project/lldb/source/API/SBData.cpp b/contrib/llvm-project/lldb/source/API/SBData.cpp index 5232bdde1ded..924a4cdb93bf 100644 --- a/contrib/llvm-project/lldb/source/API/SBData.cpp +++ b/contrib/llvm-project/lldb/source/API/SBData.cpp @@ -297,16 +297,19 @@ int64_t SBData::GetSignedInt64(lldb::SBError &error, lldb::offset_t offset) { const char *SBData::GetString(lldb::SBError &error, lldb::offset_t offset) { LLDB_INSTRUMENT_VA(this, error, offset); - const char *value = nullptr; - if (!m_opaque_sp.get()) { + if (!m_opaque_sp) { error.SetErrorString("no value to read from"); - } else { - uint32_t old_offset = offset; - value = m_opaque_sp->GetCStr(&offset); - if (offset == old_offset || (value == nullptr)) - error.SetErrorString("unable to read data"); + return nullptr; } - return value; + + lldb::offset_t old_offset = offset; + const char *value = m_opaque_sp->GetCStr(&offset); + if (offset == old_offset || value == nullptr) { + error.SetErrorString("unable to read data"); + return nullptr; + } + + return ConstString(value).GetCString(); } bool SBData::GetDescription(lldb::SBStream &description, diff --git a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp index 851c80a21d8e..9cf464660648 100644 --- a/contrib/llvm-project/lldb/source/API/SBDebugger.cpp +++ b/contrib/llvm-project/lldb/source/API/SBDebugger.cpp @@ -65,42 +65,6 @@ using namespace lldb; using namespace lldb_private; -static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp, - const FileSpec &spec, - Status &error) { - llvm::sys::DynamicLibrary dynlib = - llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str()); - if (dynlib.isValid()) { - typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger & debugger); - - lldb::SBDebugger debugger_sb(debugger_sp); - // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) - // function. - // TODO: mangle this differently for your system - on OSX, the first - // underscore needs to be removed and the second one stays - LLDBCommandPluginInit init_func = - (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol( - "_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); - if (init_func) { - if (init_func(debugger_sb)) - return dynlib; - else - error.SetErrorString("plug-in refused to load " - "(lldb::PluginInitialize(lldb::SBDebugger) " - "returned false)"); - } else { - error.SetErrorString("plug-in is missing the required initialization: " - "lldb::PluginInitialize(lldb::SBDebugger)"); - } - } else { - if (FileSystem::Instance().Exists(spec)) - error.SetErrorString("this file does not represent a loadable dylib"); - else - error.SetErrorString("no such file"); - } - return llvm::sys::DynamicLibrary(); -} - static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime; SBError SBInputReader::Initialize( @@ -157,6 +121,7 @@ const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event, uint64_t &total, bool &is_debugger_specific) { LLDB_INSTRUMENT_VA(event); + const ProgressEventData *progress_data = ProgressEventData::GetEventDataFromEvent(event.get()); if (progress_data == nullptr) @@ -165,26 +130,37 @@ const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event, completed = progress_data->GetCompleted(); total = progress_data->GetTotal(); is_debugger_specific = progress_data->IsDebuggerSpecific(); - return progress_data->GetMessage().c_str(); + ConstString message(progress_data->GetMessage()); + return message.AsCString(); } lldb::SBStructuredData -SBDebugger::GetDiagnosticFromEvent(const lldb::SBEvent &event) { +SBDebugger::GetProgressDataFromEvent(const lldb::SBEvent &event) { LLDB_INSTRUMENT_VA(event); - const DiagnosticEventData *diagnostic_data = - DiagnosticEventData::GetEventDataFromEvent(event.get()); - if (!diagnostic_data) + StructuredData::DictionarySP dictionary_sp = + ProgressEventData::GetAsStructuredData(event.get()); + + if (!dictionary_sp) 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_sp)); + return data; +} + +lldb::SBStructuredData +SBDebugger::GetDiagnosticFromEvent(const lldb::SBEvent &event) { + LLDB_INSTRUMENT_VA(event); + + StructuredData::DictionarySP dictionary_sp = + DiagnosticEventData::GetAsStructuredData(event.get()); + + if (!dictionary_sp) + return {}; SBStructuredData data; - data.m_impl_up->SetObjectSP(std::move(dictionary)); + data.m_impl_up->SetObjectSP(std::move(dictionary_sp)); return data; } @@ -202,6 +178,42 @@ void SBDebugger::Initialize() { lldb::SBError SBDebugger::InitializeWithErrorHandling() { LLDB_INSTRUMENT(); + auto LoadPlugin = [](const lldb::DebuggerSP &debugger_sp, + const FileSpec &spec, + Status &error) -> llvm::sys::DynamicLibrary { + llvm::sys::DynamicLibrary dynlib = + llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str()); + if (dynlib.isValid()) { + typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger & debugger); + + lldb::SBDebugger debugger_sb(debugger_sp); + // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger) + // function. + // TODO: mangle this differently for your system - on OSX, the first + // underscore needs to be removed and the second one stays + LLDBCommandPluginInit init_func = + (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol( + "_ZN4lldb16PluginInitializeENS_10SBDebuggerE"); + if (init_func) { + if (init_func(debugger_sb)) + return dynlib; + else + error.SetErrorString("plug-in refused to load " + "(lldb::PluginInitialize(lldb::SBDebugger) " + "returned false)"); + } else { + error.SetErrorString("plug-in is missing the required initialization: " + "lldb::PluginInitialize(lldb::SBDebugger)"); + } + } else { + if (FileSystem::Instance().Exists(spec)) + error.SetErrorString("this file does not represent a loadable dylib"); + else + error.SetErrorString("no such file"); + } + return llvm::sys::DynamicLibrary(); + }; + SBError error; if (auto e = g_debugger_lifetime->Initialize( std::make_unique<SystemInitializerFull>(), LoadPlugin)) { @@ -469,8 +481,7 @@ lldb::SBStructuredData SBDebugger::GetSetting(const char *setting) { m_opaque_sp->DumpAllPropertyValues(&exe_ctx, json_strm, /*dump_mask*/ 0, /*is_json*/ true); - data.m_impl_up->SetObjectSP( - StructuredData::ParseJSON(json_strm.GetString().str())); + data.m_impl_up->SetObjectSP(StructuredData::ParseJSON(json_strm.GetString())); return data; } @@ -1315,7 +1326,10 @@ SBDebugger SBDebugger::FindDebuggerWithID(int id) { const char *SBDebugger::GetInstanceName() { LLDB_INSTRUMENT_VA(this); - return (m_opaque_sp ? m_opaque_sp->GetInstanceName().AsCString() : nullptr); + if (!m_opaque_sp) + return nullptr; + + return ConstString(m_opaque_sp->GetInstanceName()).AsCString(); } SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value, @@ -1323,8 +1337,8 @@ SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value, LLDB_INSTRUMENT_VA(var_name, value, debugger_instance_name); SBError sb_error; - DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( - ConstString(debugger_instance_name))); + DebuggerSP debugger_sp( + Debugger::FindDebuggerWithInstanceName(debugger_instance_name)); Status error; if (debugger_sp) { ExecutionContext exe_ctx( @@ -1345,14 +1359,14 @@ SBDebugger::GetInternalVariableValue(const char *var_name, const char *debugger_instance_name) { LLDB_INSTRUMENT_VA(var_name, debugger_instance_name); - DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName( - ConstString(debugger_instance_name))); + DebuggerSP debugger_sp( + Debugger::FindDebuggerWithInstanceName(debugger_instance_name)); Status error; if (debugger_sp) { ExecutionContext exe_ctx( debugger_sp->GetCommandInterpreter().GetExecutionContext()); lldb::OptionValueSP value_sp( - debugger_sp->GetPropertyValue(&exe_ctx, var_name, false, error)); + debugger_sp->GetPropertyValue(&exe_ctx, var_name, error)); if (value_sp) { StreamString value_strm; value_sp->DumpValue(&exe_ctx, value_strm, OptionValue::eDumpOptionValue); @@ -1385,9 +1399,9 @@ const char *SBDebugger::GetPrompt() const { Log *log = GetLog(LLDBLog::API); - LLDB_LOGF(log, "SBDebugger(%p)::GetPrompt () => \"%s\"", - static_cast<void *>(m_opaque_sp.get()), - (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : "")); + LLDB_LOG(log, "SBDebugger({0:x})::GetPrompt () => \"{1}\"", + static_cast<void *>(m_opaque_sp.get()), + (m_opaque_sp ? m_opaque_sp->GetPrompt() : "")); return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString() : nullptr); @@ -1476,7 +1490,7 @@ bool SBDebugger::GetDescription(SBStream &description) { Stream &strm = description.ref(); if (m_opaque_sp) { - const char *name = m_opaque_sp->GetInstanceName().AsCString(); + const char *name = m_opaque_sp->GetInstanceName().c_str(); user_id_t id = m_opaque_sp->GetID(); strm.Printf("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id); } else @@ -1672,9 +1686,39 @@ void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, } } +void SBDebugger::SetDestroyCallback( + lldb::SBDebuggerDestroyCallback destroy_callback, void *baton) { + LLDB_INSTRUMENT_VA(this, destroy_callback, baton); + if (m_opaque_sp) { + return m_opaque_sp->SetDestroyCallback( + destroy_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); } + +void SBDebugger::RequestInterrupt() { + LLDB_INSTRUMENT_VA(this); + + if (m_opaque_sp) + m_opaque_sp->RequestInterrupt(); +} +void SBDebugger::CancelInterruptRequest() { + LLDB_INSTRUMENT_VA(this); + + if (m_opaque_sp) + m_opaque_sp->CancelInterruptRequest(); +} + +bool SBDebugger::InterruptRequested() { + LLDB_INSTRUMENT_VA(this); + + if (m_opaque_sp) + return m_opaque_sp->InterruptRequested(); + return false; +} diff --git a/contrib/llvm-project/lldb/source/API/SBError.cpp b/contrib/llvm-project/lldb/source/API/SBError.cpp index 1a034154955d..2eb9e927514a 100644 --- a/contrib/llvm-project/lldb/source/API/SBError.cpp +++ b/contrib/llvm-project/lldb/source/API/SBError.cpp @@ -25,6 +25,12 @@ SBError::SBError(const SBError &rhs) { m_opaque_up = clone(rhs.m_opaque_up); } +SBError::SBError(const char *message) { + LLDB_INSTRUMENT_VA(this, message); + + SetErrorString(message); +} + SBError::SBError(const lldb_private::Status &status) : m_opaque_up(new Status(status)) { LLDB_INSTRUMENT_VA(this, status); diff --git a/contrib/llvm-project/lldb/source/API/SBEvent.cpp b/contrib/llvm-project/lldb/source/API/SBEvent.cpp index 536680bd1c5e..13ed148e7737 100644 --- a/contrib/llvm-project/lldb/source/API/SBEvent.cpp +++ b/contrib/llvm-project/lldb/source/API/SBEvent.cpp @@ -63,7 +63,7 @@ const char *SBEvent::GetDataFlavor() { if (lldb_event) { EventData *event_data = lldb_event->GetData(); if (event_data) - return lldb_event->GetData()->GetFlavor().AsCString(); + return ConstString(lldb_event->GetData()->GetFlavor()).GetCString(); } return nullptr; } @@ -166,8 +166,9 @@ SBEvent::operator bool() const { const char *SBEvent::GetCStringFromEvent(const SBEvent &event) { LLDB_INSTRUMENT_VA(event); - return static_cast<const char *>( - EventDataBytes::GetBytesFromEvent(event.get())); + return ConstString(static_cast<const char *>( + EventDataBytes::GetBytesFromEvent(event.get()))) + .GetCString(); } bool SBEvent::GetDescription(SBStream &description) { diff --git a/contrib/llvm-project/lldb/source/API/SBExpressionOptions.cpp b/contrib/llvm-project/lldb/source/API/SBExpressionOptions.cpp index 6ae57f24606a..bd81a04596b1 100644 --- a/contrib/llvm-project/lldb/source/API/SBExpressionOptions.cpp +++ b/contrib/llvm-project/lldb/source/API/SBExpressionOptions.cpp @@ -178,19 +178,19 @@ void SBExpressionOptions::SetGenerateDebugInfo(bool b) { bool SBExpressionOptions::GetSuppressPersistentResult() { LLDB_INSTRUMENT_VA(this); - return m_opaque_up->GetResultIsInternal(); + return m_opaque_up->GetSuppressPersistentResult(); } void SBExpressionOptions::SetSuppressPersistentResult(bool b) { LLDB_INSTRUMENT_VA(this, b); - return m_opaque_up->SetResultIsInternal(b); + return m_opaque_up->SetSuppressPersistentResult(b); } const char *SBExpressionOptions::GetPrefix() const { LLDB_INSTRUMENT_VA(this); - return m_opaque_up->GetPrefix(); + return ConstString(m_opaque_up->GetPrefix()).GetCString(); } void SBExpressionOptions::SetPrefix(const char *prefix) { diff --git a/contrib/llvm-project/lldb/source/API/SBFileSpecList.cpp b/contrib/llvm-project/lldb/source/API/SBFileSpecList.cpp index cf81c4234087..74a368a3cabe 100644 --- a/contrib/llvm-project/lldb/source/API/SBFileSpecList.cpp +++ b/contrib/llvm-project/lldb/source/API/SBFileSpecList.cpp @@ -10,9 +10,9 @@ #include "Utils.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBStream.h" -#include "lldb/Core/FileSpecList.h" #include "lldb/Host/PosixApi.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/Instrumentation.h" #include "lldb/Utility/Stream.h" diff --git a/contrib/llvm-project/lldb/source/API/SBFrame.cpp b/contrib/llvm-project/lldb/source/API/SBFrame.cpp index eb7ec3bbf8d6..a19ce63bab15 100644 --- a/contrib/llvm-project/lldb/source/API/SBFrame.cpp +++ b/contrib/llvm-project/lldb/source/API/SBFrame.cpp @@ -16,9 +16,11 @@ #include "Utils.h" #include "lldb/Core/Address.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ValueObjectRegister.h" #include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Expression/ExpressionVariable.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Host/Host.h" @@ -600,7 +602,8 @@ SBValue SBFrame::FindValue(const char *name, ValueType value_type, stop_if_block_is_inlined_function, [frame](Variable *v) { return v->IsInScope(frame); }, &variable_list); - if (value_type == eValueTypeVariableGlobal) { + if (value_type == eValueTypeVariableGlobal + || value_type == eValueTypeVariableStatic) { const bool get_file_globals = true; VariableList *frame_vars = frame->GetVariableList(get_file_globals, nullptr); @@ -706,24 +709,20 @@ SBThread SBFrame::GetThread() const { const char *SBFrame::Disassemble() const { LLDB_INSTRUMENT_VA(this); - const char *disassembly = nullptr; std::unique_lock<std::recursive_mutex> lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - - StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); - if (target && process) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process->GetRunLock())) { - frame = exe_ctx.GetFramePtr(); - if (frame) { - disassembly = frame->Disassemble(); - } - } + if (!target || !process) + return nullptr; + + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) { + if (auto *frame = exe_ctx.GetFramePtr()) + return ConstString(frame->Disassemble()).GetCString(); } - return disassembly; + return nullptr; } SBValueList SBFrame::GetVariables(bool arguments, bool locals, bool statics, @@ -805,6 +804,7 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) { if (stop_locker.TryLock(&process->GetRunLock())) { frame = exe_ctx.GetFramePtr(); if (frame) { + Debugger &dbg = process->GetTarget().GetDebugger(); VariableList *variable_list = nullptr; Status var_error; variable_list = frame->GetVariableList(true, &var_error); @@ -813,7 +813,13 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) { if (variable_list) { const size_t num_variables = variable_list->GetSize(); if (num_variables) { + size_t num_produced = 0; for (const VariableSP &variable_sp : *variable_list) { + if (INTERRUPT_REQUESTED(dbg, + "Interrupted getting frame variables with {0} of {1} " + "produced.", num_produced, num_variables)) + return {}; + if (variable_sp) { bool add_variable = false; switch (variable_sp->GetScope()) { @@ -857,6 +863,7 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) { } } } + num_produced++; } } if (recognized_arguments) { @@ -988,6 +995,12 @@ SBValue SBFrame::EvaluateExpression(const char *expr) { else options.SetLanguage(frame->GetLanguage()); return EvaluateExpression(expr, options); + } else { + Status error; + error.SetErrorString("can't evaluate expressions when the " + "process is running."); + ValueObjectSP error_val_sp = ValueObjectConstResult::Create(nullptr, error); + result.SetSP(error_val_sp, false); } return result; } @@ -1051,7 +1064,6 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr, std::unique_lock<std::recursive_mutex> lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); @@ -1075,13 +1087,30 @@ lldb::SBValue SBFrame::EvaluateExpression(const char *expr, target->EvaluateExpression(expr, frame, expr_value_sp, options.ref()); expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); } + } else { + Status error; + error.SetErrorString("can't evaluate expressions when the " + "process is running."); + expr_value_sp = ValueObjectConstResult::Create(nullptr, error); + expr_result.SetSP(expr_value_sp, false); } + } else { + Status error; + error.SetErrorString("sbframe object is not valid."); + expr_value_sp = ValueObjectConstResult::Create(nullptr, error); + expr_result.SetSP(expr_value_sp, false); } - LLDB_LOGF(expr_log, - "** [SBFrame::EvaluateExpression] Expression result is " - "%s, summary %s **", - expr_result.GetValue(), expr_result.GetSummary()); + if (expr_result.GetError().Success()) + LLDB_LOGF(expr_log, + "** [SBFrame::EvaluateExpression] Expression result is " + "%s, summary %s **", + expr_result.GetValue(), expr_result.GetSummary()); + else + LLDB_LOGF(expr_log, + "** [SBFrame::EvaluateExpression] Expression evaluation failed: " + "%s **", + expr_result.GetError().GetCString()); return expr_result; } diff --git a/contrib/llvm-project/lldb/source/API/SBFunction.cpp b/contrib/llvm-project/lldb/source/API/SBFunction.cpp index 562cae4e8906..a01c7f79bbd3 100644 --- a/contrib/llvm-project/lldb/source/API/SBFunction.cpp +++ b/contrib/llvm-project/lldb/source/API/SBFunction.cpp @@ -54,30 +54,27 @@ SBFunction::operator bool() const { const char *SBFunction::GetName() const { LLDB_INSTRUMENT_VA(this); - const char *cstr = nullptr; if (m_opaque_ptr) - cstr = m_opaque_ptr->GetName().AsCString(); + return m_opaque_ptr->GetName().AsCString(); - return cstr; + return nullptr; } const char *SBFunction::GetDisplayName() const { LLDB_INSTRUMENT_VA(this); - const char *cstr = nullptr; if (m_opaque_ptr) - cstr = m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString(); + return m_opaque_ptr->GetMangled().GetDisplayDemangledName().AsCString(); - return cstr; + return nullptr; } const char *SBFunction::GetMangledName() const { LLDB_INSTRUMENT_VA(this); - const char *cstr = nullptr; if (m_opaque_ptr) - cstr = m_opaque_ptr->GetMangled().GetMangledName().AsCString(); - return cstr; + return m_opaque_ptr->GetMangled().GetMangledName().AsCString(); + return nullptr; } bool SBFunction::operator==(const SBFunction &rhs) const { @@ -166,19 +163,22 @@ SBAddress SBFunction::GetEndAddress() { const char *SBFunction::GetArgumentName(uint32_t arg_idx) { LLDB_INSTRUMENT_VA(this, arg_idx); - if (m_opaque_ptr) { - Block &block = m_opaque_ptr->GetBlock(true); - VariableListSP variable_list_sp = block.GetBlockVariableList(true); - if (variable_list_sp) { - VariableList arguments; - variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, - arguments, true); - lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx); - if (variable_sp) - return variable_sp->GetName().GetCString(); - } - } - return nullptr; + if (!m_opaque_ptr) + return nullptr; + + Block &block = m_opaque_ptr->GetBlock(true); + VariableListSP variable_list_sp = block.GetBlockVariableList(true); + if (!variable_list_sp) + return nullptr; + + VariableList arguments; + variable_list_sp->AppendVariablesWithScope(eValueTypeVariableArgument, + arguments, true); + lldb::VariableSP variable_sp = arguments.GetVariableAtIndex(arg_idx); + if (!variable_sp) + return nullptr; + + return variable_sp->GetName().GetCString(); } uint32_t SBFunction::GetPrologueByteSize() { diff --git a/contrib/llvm-project/lldb/source/API/SBInstruction.cpp b/contrib/llvm-project/lldb/source/API/SBInstruction.cpp index b03d8f73d66e..ea14e90abfd2 100644 --- a/contrib/llvm-project/lldb/source/API/SBInstruction.cpp +++ b/contrib/llvm-project/lldb/source/API/SBInstruction.cpp @@ -111,57 +111,57 @@ const char *SBInstruction::GetMnemonic(SBTarget target) { LLDB_INSTRUMENT_VA(this, target); lldb::InstructionSP inst_sp(GetOpaque()); - if (inst_sp) { - ExecutionContext exe_ctx; - TargetSP target_sp(target.GetSP()); - std::unique_lock<std::recursive_mutex> lock; - if (target_sp) { - lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); + if (!inst_sp) + return nullptr; - target_sp->CalculateExecutionContext(exe_ctx); - exe_ctx.SetProcessSP(target_sp->GetProcessSP()); - } - return inst_sp->GetMnemonic(&exe_ctx); + ExecutionContext exe_ctx; + TargetSP target_sp(target.GetSP()); + std::unique_lock<std::recursive_mutex> lock; + if (target_sp) { + lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); + + target_sp->CalculateExecutionContext(exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); } - return nullptr; + return ConstString(inst_sp->GetMnemonic(&exe_ctx)).GetCString(); } const char *SBInstruction::GetOperands(SBTarget target) { LLDB_INSTRUMENT_VA(this, target); lldb::InstructionSP inst_sp(GetOpaque()); - if (inst_sp) { - ExecutionContext exe_ctx; - TargetSP target_sp(target.GetSP()); - std::unique_lock<std::recursive_mutex> lock; - if (target_sp) { - lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); + if (!inst_sp) + return nullptr; - target_sp->CalculateExecutionContext(exe_ctx); - exe_ctx.SetProcessSP(target_sp->GetProcessSP()); - } - return inst_sp->GetOperands(&exe_ctx); + ExecutionContext exe_ctx; + TargetSP target_sp(target.GetSP()); + std::unique_lock<std::recursive_mutex> lock; + if (target_sp) { + lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); + + target_sp->CalculateExecutionContext(exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); } - return nullptr; + return ConstString(inst_sp->GetOperands(&exe_ctx)).GetCString(); } const char *SBInstruction::GetComment(SBTarget target) { LLDB_INSTRUMENT_VA(this, target); lldb::InstructionSP inst_sp(GetOpaque()); - if (inst_sp) { - ExecutionContext exe_ctx; - TargetSP target_sp(target.GetSP()); - std::unique_lock<std::recursive_mutex> lock; - if (target_sp) { - lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); + if (!inst_sp) + return nullptr; - target_sp->CalculateExecutionContext(exe_ctx); - exe_ctx.SetProcessSP(target_sp->GetProcessSP()); - } - return inst_sp->GetComment(&exe_ctx); + ExecutionContext exe_ctx; + TargetSP target_sp(target.GetSP()); + std::unique_lock<std::recursive_mutex> lock; + if (target_sp) { + lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex()); + + target_sp->CalculateExecutionContext(exe_ctx); + exe_ctx.SetProcessSP(target_sp->GetProcessSP()); } - return nullptr; + return ConstString(inst_sp->GetComment(&exe_ctx)).GetCString(); } lldb::InstructionControlFlowKind SBInstruction::GetControlFlowKind(lldb::SBTarget target) { @@ -345,6 +345,6 @@ bool SBInstruction::TestEmulation(lldb::SBStream &output_stream, lldb::InstructionSP inst_sp(GetOpaque()); if (inst_sp) - return inst_sp->TestEmulation(output_stream.get(), test_file); + return inst_sp->TestEmulation(output_stream.ref(), test_file); return false; } diff --git a/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp b/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp index ae191916b49e..d5f935083e6c 100644 --- a/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBLaunchInfo.cpp @@ -17,6 +17,8 @@ #include "lldb/API/SBStructuredData.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Host/ProcessLaunchInfo.h" +#include "lldb/Utility/Listener.h" +#include "lldb/Utility/ScriptedMetadata.h" using namespace lldb; using namespace lldb_private; @@ -146,7 +148,8 @@ uint32_t SBLaunchInfo::GetNumArguments() { const char *SBLaunchInfo::GetArgumentAtIndex(uint32_t idx) { LLDB_INSTRUMENT_VA(this, idx); - return m_opaque_sp->GetArguments().GetArgumentAtIndex(idx); + return ConstString(m_opaque_sp->GetArguments().GetArgumentAtIndex(idx)) + .GetCString(); } void SBLaunchInfo::SetArguments(const char **argv, bool append) { @@ -174,7 +177,7 @@ const char *SBLaunchInfo::GetEnvironmentEntryAtIndex(uint32_t idx) { if (idx > GetNumEnvironmentEntries()) return nullptr; - return m_opaque_sp->GetEnvp()[idx]; + return ConstString(m_opaque_sp->GetEnvp()[idx]).GetCString(); } void SBLaunchInfo::SetEnvironmentEntries(const char **envp, bool append) { @@ -231,7 +234,7 @@ void SBLaunchInfo::SetLaunchFlags(uint32_t flags) { const char *SBLaunchInfo::GetProcessPluginName() { LLDB_INSTRUMENT_VA(this); - return m_opaque_sp->GetProcessPluginName(); + return ConstString(m_opaque_sp->GetProcessPluginName()).GetCString(); } void SBLaunchInfo::SetProcessPluginName(const char *plugin_name) { @@ -313,7 +316,7 @@ void SBLaunchInfo::SetLaunchEventData(const char *data) { const char *SBLaunchInfo::GetLaunchEventData() const { LLDB_INSTRUMENT_VA(this); - return m_opaque_sp->GetLaunchEventData(); + return ConstString(m_opaque_sp->GetLaunchEventData()).GetCString(); } void SBLaunchInfo::SetDetachOnError(bool enable) { @@ -331,25 +334,36 @@ bool SBLaunchInfo::GetDetachOnError() const { const char *SBLaunchInfo::GetScriptedProcessClassName() const { LLDB_INSTRUMENT_VA(this); + ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); + + if (!metadata_sp || !*metadata_sp) + return nullptr; + // Constify this string so that it is saved in the string pool. Otherwise it // would be freed when this function goes out of scope. - ConstString class_name(m_opaque_sp->GetScriptedProcessClassName().c_str()); + ConstString class_name(metadata_sp->GetClassName().data()); return class_name.AsCString(); } void SBLaunchInfo::SetScriptedProcessClassName(const char *class_name) { LLDB_INSTRUMENT_VA(this, class_name); - - m_opaque_sp->SetScriptedProcessClassName(class_name); + ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); + StructuredData::DictionarySP dict_sp = + metadata_sp ? metadata_sp->GetArgsSP() : nullptr; + metadata_sp = std::make_shared<ScriptedMetadata>(class_name, dict_sp); + m_opaque_sp->SetScriptedMetadata(metadata_sp); } lldb::SBStructuredData SBLaunchInfo::GetScriptedProcessDictionary() const { LLDB_INSTRUMENT_VA(this); - lldb_private::StructuredData::DictionarySP dict_sp = - m_opaque_sp->GetScriptedProcessDictionarySP(); + ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); SBStructuredData data; + if (!metadata_sp) + return data; + + lldb_private::StructuredData::DictionarySP dict_sp = metadata_sp->GetArgsSP(); data.m_impl_up->SetObjectSP(dict_sp); return data; @@ -370,5 +384,29 @@ void SBLaunchInfo::SetScriptedProcessDictionary(lldb::SBStructuredData dict) { if (!dict_sp || dict_sp->GetType() == lldb::eStructuredDataTypeInvalid) return; - m_opaque_sp->SetScriptedProcessDictionarySP(dict_sp); + ScriptedMetadataSP metadata_sp = m_opaque_sp->GetScriptedMetadata(); + llvm::StringRef class_name = metadata_sp ? metadata_sp->GetClassName() : ""; + metadata_sp = std::make_shared<ScriptedMetadata>(class_name, dict_sp); + m_opaque_sp->SetScriptedMetadata(metadata_sp); +} + +SBListener SBLaunchInfo::GetShadowListener() { + LLDB_INSTRUMENT_VA(this); + + lldb::ListenerSP shadow_sp = m_opaque_sp->GetShadowListener(); + if (!shadow_sp) + return SBListener(); + return SBListener(shadow_sp); +} + +void SBLaunchInfo::SetShadowListener(SBListener &listener) { + LLDB_INSTRUMENT_VA(this, listener); + + ListenerSP listener_sp = listener.GetSP(); + if (listener_sp && listener.IsValid()) + listener_sp->SetShadow(true); + else + listener_sp = nullptr; + + m_opaque_sp->SetShadowListener(listener_sp); } diff --git a/contrib/llvm-project/lldb/source/API/SBModule.cpp b/contrib/llvm-project/lldb/source/API/SBModule.cpp index e7c2b451eb9d..b865502228e0 100644 --- a/contrib/llvm-project/lldb/source/API/SBModule.cpp +++ b/contrib/llvm-project/lldb/source/API/SBModule.cpp @@ -173,20 +173,20 @@ const uint8_t *SBModule::GetUUIDBytes() const { const char *SBModule::GetUUIDString() const { LLDB_INSTRUMENT_VA(this); - const char *uuid_cstr = nullptr; ModuleSP module_sp(GetSP()); - if (module_sp) { - // We are going to return a "const char *" value through the public API, so - // we need to constify it so it gets added permanently the string pool and - // then we don't need to worry about the lifetime of the string as it will - // never go away once it has been put into the ConstString string pool - uuid_cstr = ConstString(module_sp->GetUUID().GetAsString()).GetCString(); - } - - if (uuid_cstr && uuid_cstr[0]) { + if (!module_sp) + return nullptr; + + // We are going to return a "const char *" value through the public API, so + // we need to constify it so it gets added permanently the string pool and + // then we don't need to worry about the lifetime of the string as it will + // never go away once it has been put into the ConstString string pool + const char *uuid_cstr = + ConstString(module_sp->GetUUID().GetAsString()).GetCString(); + // Note: SBModule::GetUUIDString's expected behavior is to return nullptr if + // the string we get is empty, so we must perform this check before returning. + if (uuid_cstr && uuid_cstr[0]) return uuid_cstr; - } - return nullptr; } @@ -579,15 +579,15 @@ const char *SBModule::GetTriple() { LLDB_INSTRUMENT_VA(this); ModuleSP module_sp(GetSP()); - if (module_sp) { - std::string triple(module_sp->GetArchitecture().GetTriple().str()); - // Unique the string so we don't run into ownership issues since the const - // strings put the string into the string pool once and the strings never - // comes out - ConstString const_triple(triple.c_str()); - return const_triple.GetCString(); - } - return nullptr; + if (!module_sp) + return nullptr; + + std::string triple(module_sp->GetArchitecture().GetTriple().str()); + // Unique the string so we don't run into ownership issues since the const + // strings put the string into the string pool once and the strings never + // comes out + ConstString const_triple(triple.c_str()); + return const_triple.GetCString(); } uint32_t SBModule::GetAddressByteSize() { diff --git a/contrib/llvm-project/lldb/source/API/SBModuleSpec.cpp b/contrib/llvm-project/lldb/source/API/SBModuleSpec.cpp index 83b1b6b74941..fbbcfeac2017 100644 --- a/contrib/llvm-project/lldb/source/API/SBModuleSpec.cpp +++ b/contrib/llvm-project/lldb/source/API/SBModuleSpec.cpp @@ -29,6 +29,11 @@ SBModuleSpec::SBModuleSpec(const SBModuleSpec &rhs) { m_opaque_up = clone(rhs.m_opaque_up); } +SBModuleSpec::SBModuleSpec(const lldb_private::ModuleSpec &module_spec) + : m_opaque_up(new lldb_private::ModuleSpec(module_spec)) { + LLDB_INSTRUMENT_VA(this, module_spec); +} + const SBModuleSpec &SBModuleSpec::operator=(const SBModuleSpec &rhs) { LLDB_INSTRUMENT_VA(this, rhs); @@ -145,6 +150,30 @@ bool SBModuleSpec::GetDescription(lldb::SBStream &description) { return true; } +uint64_t SBModuleSpec::GetObjectOffset() { + LLDB_INSTRUMENT_VA(this); + + return m_opaque_up->GetObjectOffset(); +} + +void SBModuleSpec::SetObjectOffset(uint64_t object_offset) { + LLDB_INSTRUMENT_VA(this, object_offset); + + m_opaque_up->SetObjectOffset(object_offset); +} + +uint64_t SBModuleSpec::GetObjectSize() { + LLDB_INSTRUMENT_VA(this); + + return m_opaque_up->GetObjectSize(); +} + +void SBModuleSpec::SetObjectSize(uint64_t object_size) { + LLDB_INSTRUMENT_VA(this, object_size); + + m_opaque_up->SetObjectSize(object_size); +} + SBModuleSpecList::SBModuleSpecList() : m_opaque_up(new ModuleSpecList()) { LLDB_INSTRUMENT_VA(this); } diff --git a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp index 807d0085c7bc..f8300a5bab30 100644 --- a/contrib/llvm-project/lldb/source/API/SBPlatform.cpp +++ b/contrib/llvm-project/lldb/source/API/SBPlatform.cpp @@ -11,6 +11,7 @@ #include "lldb/API/SBError.h" #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBLaunchInfo.h" +#include "lldb/API/SBModuleSpec.h" #include "lldb/API/SBPlatform.h" #include "lldb/API/SBUnixSignals.h" #include "lldb/Host/File.h" @@ -100,7 +101,7 @@ const char *SBPlatformConnectOptions::GetURL() { if (m_opaque_ptr->m_url.empty()) return nullptr; - return m_opaque_ptr->m_url.c_str(); + return ConstString(m_opaque_ptr->m_url.c_str()).GetCString(); } void SBPlatformConnectOptions::SetURL(const char *url) { @@ -203,7 +204,7 @@ const char *SBPlatformShellCommand::GetShell() { if (m_opaque_ptr->m_shell.empty()) return nullptr; - return m_opaque_ptr->m_shell.c_str(); + return ConstString(m_opaque_ptr->m_shell.c_str()).GetCString(); } void SBPlatformShellCommand::SetShell(const char *shell_interpreter) { @@ -220,7 +221,7 @@ const char *SBPlatformShellCommand::GetCommand() { if (m_opaque_ptr->m_command.empty()) return nullptr; - return m_opaque_ptr->m_command.c_str(); + return ConstString(m_opaque_ptr->m_command.c_str()).GetCString(); } void SBPlatformShellCommand::SetCommand(const char *shell_command) { @@ -237,7 +238,7 @@ const char *SBPlatformShellCommand::GetWorkingDirectory() { if (m_opaque_ptr->m_working_dir.empty()) return nullptr; - return m_opaque_ptr->m_working_dir.c_str(); + return ConstString(m_opaque_ptr->m_working_dir.c_str()).GetCString(); } void SBPlatformShellCommand::SetWorkingDirectory(const char *path) { @@ -283,7 +284,7 @@ const char *SBPlatformShellCommand::GetOutput() { if (m_opaque_ptr->m_output.empty()) return nullptr; - return m_opaque_ptr->m_output.c_str(); + return ConstString(m_opaque_ptr->m_output.c_str()).GetCString(); } // SBPlatform @@ -454,7 +455,7 @@ const char *SBPlatform::GetHostname() { PlatformSP platform_sp(GetSP()); if (platform_sp) - return platform_sp->GetHostname(); + return ConstString(platform_sp->GetHostname()).GetCString(); return nullptr; } @@ -488,7 +489,7 @@ uint32_t SBPlatform::GetOSUpdateVersion() { void SBPlatform::SetSDKRoot(const char *sysroot) { LLDB_INSTRUMENT_VA(this, sysroot); if (PlatformSP platform_sp = GetSP()) - platform_sp->SetSDKRootDirectory(ConstString(sysroot)); + platform_sp->SetSDKRootDirectory(llvm::StringRef(sysroot).str()); } SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) { @@ -655,3 +656,41 @@ SBEnvironment SBPlatform::GetEnvironment() { return SBEnvironment(); } + +SBError SBPlatform::SetLocateModuleCallback( + lldb::SBPlatformLocateModuleCallback callback, void *callback_baton) { + LLDB_INSTRUMENT_VA(this, callback, callback_baton); + PlatformSP platform_sp(GetSP()); + if (!platform_sp) + return SBError("invalid platform"); + + if (!callback) { + // Clear the callback. + platform_sp->SetLocateModuleCallback(nullptr); + return SBError(); + } + + // Platform.h does not accept lldb::SBPlatformLocateModuleCallback directly + // because of the SBModuleSpec and SBFileSpec dependencies. Use a lambda to + // convert ModuleSpec/FileSpec <--> SBModuleSpec/SBFileSpec for the callback + // arguments. + platform_sp->SetLocateModuleCallback( + [callback, callback_baton](const ModuleSpec &module_spec, + FileSpec &module_file_spec, + FileSpec &symbol_file_spec) { + SBModuleSpec module_spec_sb(module_spec); + SBFileSpec module_file_spec_sb; + SBFileSpec symbol_file_spec_sb; + + SBError error = callback(callback_baton, module_spec_sb, + module_file_spec_sb, symbol_file_spec_sb); + + if (error.Success()) { + module_file_spec = module_file_spec_sb.ref(); + symbol_file_spec = symbol_file_spec_sb.ref(); + } + + return error.ref(); + }); + return SBError(); +} diff --git a/contrib/llvm-project/lldb/source/API/SBProcess.cpp b/contrib/llvm-project/lldb/source/API/SBProcess.cpp index 27593559bb3d..67d08f1f02be 100644 --- a/contrib/llvm-project/lldb/source/API/SBProcess.cpp +++ b/contrib/llvm-project/lldb/source/API/SBProcess.cpp @@ -38,6 +38,7 @@ #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBMemoryRegionInfo.h" #include "lldb/API/SBMemoryRegionInfoList.h" +#include "lldb/API/SBScriptObject.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" #include "lldb/API/SBStructuredData.h" @@ -466,6 +467,16 @@ SBEvent SBProcess::GetStopEventForStopID(uint32_t stop_id) { return sb_event; } +void SBProcess::ForceScriptedState(StateType new_state) { + LLDB_INSTRUMENT_VA(this, new_state); + + if (ProcessSP process_sp = GetSP()) { + std::lock_guard<std::recursive_mutex> guard( + process_sp->GetTarget().GetAPIMutex()); + process_sp->ForceScriptedState(new_state); + } +} + StateType SBProcess::GetState() { LLDB_INSTRUMENT_VA(this); @@ -497,14 +508,13 @@ int SBProcess::GetExitStatus() { const char *SBProcess::GetExitDescription() { LLDB_INSTRUMENT_VA(this); - const char *exit_desc = nullptr; ProcessSP process_sp(GetSP()); - if (process_sp) { - std::lock_guard<std::recursive_mutex> guard( - process_sp->GetTarget().GetAPIMutex()); - exit_desc = process_sp->GetExitDescription(); - } - return exit_desc; + if (!process_sp) + return nullptr; + + std::lock_guard<std::recursive_mutex> guard( + process_sp->GetTarget().GetAPIMutex()); + return ConstString(process_sp->GetExitDescription()).GetCString(); } lldb::pid_t SBProcess::GetProcessID() { @@ -737,7 +747,9 @@ SBProcess::GetRestartedReasonAtIndexFromEvent(const lldb::SBEvent &event, size_t idx) { LLDB_INSTRUMENT_VA(event, idx); - return Process::ProcessEventData::GetRestartedReasonAtIndex(event.get(), idx); + return ConstString(Process::ProcessEventData::GetRestartedReasonAtIndex( + event.get(), idx)) + .GetCString(); } SBProcess SBProcess::GetProcessFromEvent(const SBEvent &event) { @@ -769,8 +781,8 @@ SBProcess::GetStructuredDataFromEvent(const lldb::SBEvent &event) { bool SBProcess::EventIsProcessEvent(const SBEvent &event) { LLDB_INSTRUMENT_VA(event); - return (event.GetBroadcasterClass() == SBProcess::GetBroadcasterClass()) && - !EventIsStructuredDataEvent(event); + return Process::ProcessEventData::GetEventDataFromEvent(event.get()) != + nullptr; } bool SBProcess::EventIsStructuredDataEvent(const lldb::SBEvent &event) { @@ -802,8 +814,13 @@ size_t SBProcess::ReadMemory(addr_t addr, void *dst, size_t dst_len, SBError &sb_error) { LLDB_INSTRUMENT_VA(this, addr, dst, dst_len, sb_error); - size_t bytes_read = 0; + if (!dst) { + sb_error.SetErrorStringWithFormat( + "no buffer provided to read %zu bytes into", dst_len); + return 0; + } + size_t bytes_read = 0; ProcessSP process_sp(GetSP()); @@ -967,7 +984,12 @@ SBProcess::GetNumSupportedHardwareWatchpoints(lldb::SBError &sb_error) const { if (process_sp) { std::lock_guard<std::recursive_mutex> guard( process_sp->GetTarget().GetAPIMutex()); - sb_error.SetError(process_sp->GetWatchpointSupportInfo(num)); + std::optional<uint32_t> actual_num = process_sp->GetWatchpointSlotCount(); + if (actual_num) { + num = *actual_num; + } else { + sb_error.SetErrorString("Unable to determine number of watchpoints"); + } } else { sb_error.SetErrorString("SBProcess is invalid"); } @@ -1162,6 +1184,7 @@ lldb::SBError SBProcess::SaveCore(const char *file_name, } FileSpec core_file(file_name); + FileSystem::Instance().Resolve(core_file); error.ref() = PluginManager::SaveCore(process_sp, core_file, core_style, flavor); @@ -1262,3 +1285,11 @@ lldb::SBError SBProcess::DeallocateMemory(lldb::addr_t ptr) { } return sb_error; } + +lldb::SBScriptObject SBProcess::GetScriptedImplementation() { + LLDB_INSTRUMENT_VA(this); + ProcessSP process_sp(GetSP()); + return lldb::SBScriptObject((process_sp) ? process_sp->GetImplementation() + : nullptr, + eScriptLanguageDefault); +} diff --git a/contrib/llvm-project/lldb/source/API/SBProcessInfo.cpp b/contrib/llvm-project/lldb/source/API/SBProcessInfo.cpp index da3db75ff47e..895fba95afba 100644 --- a/contrib/llvm-project/lldb/source/API/SBProcessInfo.cpp +++ b/contrib/llvm-project/lldb/source/API/SBProcessInfo.cpp @@ -57,11 +57,10 @@ SBProcessInfo::operator bool() const { const char *SBProcessInfo::GetName() { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; - if (m_opaque_up) { - name = m_opaque_up->GetName(); - } - return name; + if (!m_opaque_up) + return nullptr; + + return ConstString(m_opaque_up->GetName()).GetCString(); } SBFileSpec SBProcessInfo::GetExecutableFile() { @@ -177,14 +176,12 @@ lldb::pid_t SBProcessInfo::GetParentProcessID() { const char *SBProcessInfo::GetTriple() { LLDB_INSTRUMENT_VA(this); - const char *triple = nullptr; - if (m_opaque_up) { - const auto &arch = m_opaque_up->GetArchitecture(); - if (arch.IsValid()) { - // Const-ify the string so we don't need to worry about the lifetime of - // the string - triple = ConstString(arch.GetTriple().getTriple().c_str()).GetCString(); - } - } - return triple; + if (!m_opaque_up) + return nullptr; + + const auto &arch = m_opaque_up->GetArchitecture(); + if (!arch.IsValid()) + return nullptr; + + return ConstString(arch.GetTriple().getTriple().c_str()).GetCString(); } diff --git a/contrib/llvm-project/lldb/source/API/SBQueue.cpp b/contrib/llvm-project/lldb/source/API/SBQueue.cpp index b97da3ef02ed..968d3b77538c 100644 --- a/contrib/llvm-project/lldb/source/API/SBQueue.cpp +++ b/contrib/llvm-project/lldb/source/API/SBQueue.cpp @@ -77,12 +77,10 @@ public: } const char *GetName() const { - const char *name = nullptr; lldb::QueueSP queue_sp = m_queue_wp.lock(); - if (queue_sp.get()) { - name = queue_sp->GetName(); - } - return name; + if (!queue_sp) + return nullptr; + return ConstString(queue_sp->GetName()).GetCString(); } void FetchThreads() { diff --git a/contrib/llvm-project/lldb/source/API/SBScriptObject.cpp b/contrib/llvm-project/lldb/source/API/SBScriptObject.cpp new file mode 100644 index 000000000000..3e067d0ab1ee --- /dev/null +++ b/contrib/llvm-project/lldb/source/API/SBScriptObject.cpp @@ -0,0 +1,84 @@ +//===-- SBScriptObject.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBScriptObject.h" + +#include "Utils.h" + +#include "lldb/Interpreter/ScriptObject.h" +#include "lldb/Utility/Instrumentation.h" + +using namespace lldb; +using namespace lldb_private; + +SBScriptObject::SBScriptObject(const ScriptObjectPtr ptr, + lldb::ScriptLanguage lang) + : m_opaque_up(std::make_unique<lldb_private::ScriptObject>(ptr, lang)) { + LLDB_INSTRUMENT_VA(this, ptr, lang); +} + +SBScriptObject::SBScriptObject(const SBScriptObject &rhs) + : m_opaque_up(new ScriptObject(nullptr, eScriptLanguageNone)) { + LLDB_INSTRUMENT_VA(this, rhs); + + m_opaque_up = clone(rhs.m_opaque_up); +} +SBScriptObject::~SBScriptObject() = default; + +const SBScriptObject &SBScriptObject::operator=(const SBScriptObject &rhs) { + LLDB_INSTRUMENT_VA(this, rhs); + + if (this != &rhs) + m_opaque_up = clone(rhs.m_opaque_up); + return *this; +} + +bool SBScriptObject::operator!=(const SBScriptObject &rhs) const { + LLDB_INSTRUMENT_VA(this, rhs); + + return !(m_opaque_up == rhs.m_opaque_up); +} + +bool SBScriptObject::IsValid() const { + LLDB_INSTRUMENT_VA(this); + + return this->operator bool(); +} + +SBScriptObject::operator bool() const { + LLDB_INSTRUMENT_VA(this); + + return m_opaque_up != nullptr && m_opaque_up->operator bool(); +} + +lldb::ScriptObjectPtr SBScriptObject::GetPointer() const { + LLDB_INSTRUMENT_VA(this); + + return m_opaque_up ? const_cast<void *>(m_opaque_up->GetPointer()) : nullptr; +} + +lldb::ScriptLanguage SBScriptObject::GetLanguage() const { + LLDB_INSTRUMENT_VA(this); + + return m_opaque_up ? m_opaque_up->GetLanguage() : eScriptLanguageNone; +} + +ScriptObject &SBScriptObject::ref() { + if (m_opaque_up == nullptr) + m_opaque_up = std::make_unique<ScriptObject>(nullptr, eScriptLanguageNone); + return *m_opaque_up; +} + +const ScriptObject &SBScriptObject::ref() const { + // This object should already have checked with "IsValid()" prior to calling + // this function. In case you didn't we will assert and die to let you know. + assert(m_opaque_up.get()); + return *m_opaque_up; +} + +ScriptObject *SBScriptObject::get() { return m_opaque_up.get(); } diff --git a/contrib/llvm-project/lldb/source/API/SBSection.cpp b/contrib/llvm-project/lldb/source/API/SBSection.cpp index 3a9cf20e484a..b7b94f3ece1a 100644 --- a/contrib/llvm-project/lldb/source/API/SBSection.cpp +++ b/contrib/llvm-project/lldb/source/API/SBSection.cpp @@ -182,35 +182,10 @@ SBData SBSection::GetSectionData(uint64_t offset, uint64_t size) { SBData sb_data; SectionSP section_sp(GetSP()); if (section_sp) { - const uint64_t sect_file_size = section_sp->GetFileSize(); - if (sect_file_size > 0) { - ModuleSP module_sp(section_sp->GetModule()); - if (module_sp) { - ObjectFile *objfile = module_sp->GetObjectFile(); - if (objfile) { - const uint64_t sect_file_offset = - objfile->GetFileOffset() + section_sp->GetFileOffset(); - const uint64_t file_offset = sect_file_offset + offset; - uint64_t file_size = size; - if (file_size == UINT64_MAX) { - file_size = section_sp->GetByteSize(); - if (file_size > offset) - file_size -= offset; - else - file_size = 0; - } - auto data_buffer_sp = FileSystem::Instance().CreateDataBuffer( - objfile->GetFileSpec().GetPath(), file_size, file_offset); - if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) { - DataExtractorSP data_extractor_sp( - new DataExtractor(data_buffer_sp, objfile->GetByteOrder(), - objfile->GetAddressByteSize())); - - sb_data.SetOpaque(data_extractor_sp); - } - } - } - } + DataExtractor section_data; + section_sp->GetSectionData(section_data); + sb_data.SetOpaque( + std::make_shared<DataExtractor>(section_data, offset, size)); } return sb_data; } diff --git a/contrib/llvm-project/lldb/source/API/SBStream.cpp b/contrib/llvm-project/lldb/source/API/SBStream.cpp index 870cbb9e14d5..9275a02bb62c 100644 --- a/contrib/llvm-project/lldb/source/API/SBStream.cpp +++ b/contrib/llvm-project/lldb/source/API/SBStream.cpp @@ -47,7 +47,8 @@ const char *SBStream::GetData() { if (m_is_file || m_opaque_up == nullptr) return nullptr; - return static_cast<StreamString *>(m_opaque_up.get())->GetData(); + return ConstString(static_cast<StreamString *>(m_opaque_up.get())->GetData()) + .GetCString(); } // If this stream is not redirected to a file, it will maintain a local cache diff --git a/contrib/llvm-project/lldb/source/API/SBStringList.cpp b/contrib/llvm-project/lldb/source/API/SBStringList.cpp index dfb77b1ab32f..350c58b61634 100644 --- a/contrib/llvm-project/lldb/source/API/SBStringList.cpp +++ b/contrib/llvm-project/lldb/source/API/SBStringList.cpp @@ -37,6 +37,13 @@ const SBStringList &SBStringList::operator=(const SBStringList &rhs) { SBStringList::~SBStringList() = default; +lldb_private::StringList *SBStringList::operator->() { + if (!IsValid()) + m_opaque_up = std::make_unique<lldb_private::StringList>(); + + return m_opaque_up.get(); +} + const lldb_private::StringList *SBStringList::operator->() const { return m_opaque_up.get(); } @@ -106,7 +113,7 @@ const char *SBStringList::GetStringAtIndex(size_t idx) { LLDB_INSTRUMENT_VA(this, idx); if (IsValid()) { - return m_opaque_up->GetStringAtIndex(idx); + return ConstString(m_opaque_up->GetStringAtIndex(idx)).GetCString(); } return nullptr; } @@ -115,7 +122,7 @@ const char *SBStringList::GetStringAtIndex(size_t idx) const { LLDB_INSTRUMENT_VA(this, idx); if (IsValid()) { - return m_opaque_up->GetStringAtIndex(idx); + return ConstString(m_opaque_up->GetStringAtIndex(idx)).GetCString(); } return nullptr; } diff --git a/contrib/llvm-project/lldb/source/API/SBStructuredData.cpp b/contrib/llvm-project/lldb/source/API/SBStructuredData.cpp index 498bcdd39e44..b18fc5655fc8 100644 --- a/contrib/llvm-project/lldb/source/API/SBStructuredData.cpp +++ b/contrib/llvm-project/lldb/source/API/SBStructuredData.cpp @@ -7,15 +7,20 @@ //===----------------------------------------------------------------------===// #include "lldb/API/SBStructuredData.h" -#include "lldb/Utility/Instrumentation.h" +#include "lldb/API/SBDebugger.h" +#include "lldb/API/SBScriptObject.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Utility/Event.h" +#include "lldb/Utility/Instrumentation.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/Utility/StringList.h" #include "lldb/Utility/StructuredData.h" using namespace lldb; @@ -33,6 +38,25 @@ SBStructuredData::SBStructuredData(const lldb::SBStructuredData &rhs) LLDB_INSTRUMENT_VA(this, rhs); } +SBStructuredData::SBStructuredData(const lldb::SBScriptObject obj, + const lldb::SBDebugger &debugger) { + LLDB_INSTRUMENT_VA(this, obj, debugger); + + if (!obj.IsValid()) + return; + + ScriptInterpreter *interpreter = + debugger.m_opaque_sp->GetScriptInterpreter(true, obj.GetLanguage()); + + if (!interpreter) + return; + + StructuredDataImplUP impl_up = std::make_unique<StructuredDataImpl>( + interpreter->CreateStructuredDataFromScriptObject(obj.ref())); + if (impl_up && impl_up->IsValid()) + m_impl_up.reset(impl_up.release()); +} + SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp) : m_impl_up(new StructuredDataImpl(event_sp)) { LLDB_INSTRUMENT_VA(this, event_sp); @@ -57,9 +81,9 @@ lldb::SBError SBStructuredData::SetFromJSON(lldb::SBStream &stream) { LLDB_INSTRUMENT_VA(this, stream); lldb::SBError error; - std::string json_str(stream.GetData()); - StructuredData::ObjectSP json_obj = StructuredData::ParseJSON(json_str); + StructuredData::ObjectSP json_obj = + StructuredData::ParseJSON(stream.GetData()); m_impl_up->SetObjectSP(json_obj); if (!json_obj || json_obj->GetType() != eStructuredDataTypeDictionary) @@ -138,9 +162,9 @@ bool SBStructuredData::GetKeys(lldb::SBStringList &keys) const { StructuredData::Array *key_arr = array_sp->GetAsArray(); assert(key_arr); - key_arr->ForEach([&keys] (StructuredData::Object *object) -> bool { + key_arr->ForEach([&keys](StructuredData::Object *object) -> bool { llvm::StringRef key = object->GetStringValue(""); - keys.AppendString(key.str().c_str()); + keys->AppendString(key); return true; }); return true; @@ -165,6 +189,18 @@ lldb::SBStructuredData SBStructuredData::GetItemAtIndex(size_t idx) const { uint64_t SBStructuredData::GetIntegerValue(uint64_t fail_value) const { LLDB_INSTRUMENT_VA(this, fail_value); + return GetUnsignedIntegerValue(fail_value); +} + +uint64_t SBStructuredData::GetUnsignedIntegerValue(uint64_t fail_value) const { + LLDB_INSTRUMENT_VA(this, fail_value); + + return m_impl_up->GetIntegerValue(fail_value); +} + +int64_t SBStructuredData::GetSignedIntegerValue(int64_t fail_value) const { + LLDB_INSTRUMENT_VA(this, fail_value); + return m_impl_up->GetIntegerValue(fail_value); } @@ -185,3 +221,9 @@ size_t SBStructuredData::GetStringValue(char *dst, size_t dst_len) const { return m_impl_up->GetStringValue(dst, dst_len); } + +lldb::SBScriptObject SBStructuredData::GetGenericValue() const { + LLDB_INSTRUMENT_VA(this); + + return {m_impl_up->GetGenericValue(), eScriptLanguageDefault}; +} diff --git a/contrib/llvm-project/lldb/source/API/SBTarget.cpp b/contrib/llvm-project/lldb/source/API/SBTarget.cpp index cadaeb472e28..3fef7428abe2 100644 --- a/contrib/llvm-project/lldb/source/API/SBTarget.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTarget.cpp @@ -434,7 +434,8 @@ lldb::SBProcess SBTarget::Attach(SBAttachInfo &sb_attach_info, SBError &error) { if (target_sp) { ProcessAttachInfo &attach_info = sb_attach_info.ref(); - if (attach_info.ProcessIDIsValid() && !attach_info.UserIDIsValid()) { + if (attach_info.ProcessIDIsValid() && !attach_info.UserIDIsValid() && + !attach_info.IsScriptedProcess()) { PlatformSP platform_sp = target_sp->GetPlatform(); // See if we can pre-verify if a process exists or not if (platform_sp && platform_sp->IsConnected()) { @@ -1116,8 +1117,8 @@ bool SBTarget::FindBreakpointsByName(const char *name, llvm::Expected<std::vector<BreakpointSP>> expected_vector = target_sp->GetBreakpointList().FindBreakpointsByName(name); if (!expected_vector) { - LLDB_LOG(GetLog(LLDBLog::Breakpoints), "invalid breakpoint name: {}", - llvm::toString(expected_vector.takeError())); + LLDB_LOG_ERROR(GetLog(LLDBLog::Breakpoints), expected_vector.takeError(), + "invalid breakpoint name: {0}"); return false; } for (BreakpointSP bkpt_sp : *expected_vector) { @@ -1577,27 +1578,47 @@ const char *SBTarget::GetTriple() { LLDB_INSTRUMENT_VA(this); TargetSP target_sp(GetSP()); - if (target_sp) { - std::string triple(target_sp->GetArchitecture().GetTriple().str()); - // Unique the string so we don't run into ownership issues since the const - // strings put the string into the string pool once and the strings never - // comes out - ConstString const_triple(triple.c_str()); - return const_triple.GetCString(); - } - return nullptr; + if (!target_sp) + return nullptr; + + std::string triple(target_sp->GetArchitecture().GetTriple().str()); + // Unique the string so we don't run into ownership issues since the const + // strings put the string into the string pool once and the strings never + // comes out + ConstString const_triple(triple.c_str()); + return const_triple.GetCString(); } 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; + if (!target_sp) + return nullptr; + + std::string abi_name(target_sp->GetABIName().str()); + ConstString const_name(abi_name.c_str()); + return const_name.GetCString(); +} + +const char *SBTarget::GetLabel() const { + LLDB_INSTRUMENT_VA(this); + + TargetSP target_sp(GetSP()); + if (!target_sp) + return nullptr; + + return ConstString(target_sp->GetLabel().data()).AsCString(); +} + +SBError SBTarget::SetLabel(const char *label) { + LLDB_INSTRUMENT_VA(this, label); + + TargetSP target_sp(GetSP()); + if (!target_sp) + return Status("Couldn't get internal target object."); + + return Status(target_sp->SetLabel(label)); } uint32_t SBTarget::GetDataByteSize() { @@ -1891,7 +1912,7 @@ SBValueList SBTarget::FindGlobalVariables(const char *name, max_matches, variable_list); break; case eMatchTypeStartsWith: - regexstr = llvm::Regex::escape(name) + ".*"; + regexstr = "^" + llvm::Regex::escape(name) + ".*"; target_sp->GetImages().FindGlobalVariables(RegularExpression(regexstr), max_matches, variable_list); break; @@ -2092,6 +2113,18 @@ SBError SBTarget::SetModuleLoadAddress(lldb::SBModule module, int64_t slide_offset) { LLDB_INSTRUMENT_VA(this, module, slide_offset); + if (slide_offset < 0) { + SBError sb_error; + sb_error.SetErrorStringWithFormat("slide must be positive"); + return sb_error; + } + + return SetModuleLoadAddress(module, static_cast<uint64_t>(slide_offset)); +} + +SBError SBTarget::SetModuleLoadAddress(lldb::SBModule module, + uint64_t slide_offset) { + SBError sb_error; TargetSP target_sp(GetSP()); @@ -2219,12 +2252,25 @@ lldb::SBValue SBTarget::EvaluateExpression(const char *expr, std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex()); ExecutionContext exe_ctx(m_opaque_sp.get()); - frame = exe_ctx.GetFramePtr(); Target *target = exe_ctx.GetTargetPtr(); + Process *process = exe_ctx.GetProcessPtr(); if (target) { - target->EvaluateExpression(expr, frame, expr_value_sp, options.ref()); + // If we have a process, make sure to lock the runlock: + if (process) { + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&process->GetRunLock())) { + target->EvaluateExpression(expr, frame, expr_value_sp, options.ref()); + } else { + Status error; + error.SetErrorString("can't evaluate expressions when the " + "process is running."); + expr_value_sp = ValueObjectConstResult::Create(nullptr, error); + } + } else { + target->EvaluateExpression(expr, frame, expr_value_sp, options.ref()); + } expr_result.SetSP(expr_value_sp, options.GetFetchDynamicValue()); } diff --git a/contrib/llvm-project/lldb/source/API/SBThread.cpp b/contrib/llvm-project/lldb/source/API/SBThread.cpp index 616f047f6888..bd316ddf54a9 100644 --- a/contrib/llvm-project/lldb/source/API/SBThread.cpp +++ b/contrib/llvm-project/lldb/source/API/SBThread.cpp @@ -394,35 +394,33 @@ uint32_t SBThread::GetIndexID() const { const char *SBThread::GetName() const { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; std::unique_lock<std::recursive_mutex> lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - name = exe_ctx.GetThreadPtr()->GetName(); - } - } + if (!exe_ctx.HasThreadScope()) + return nullptr; + + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + return ConstString(exe_ctx.GetThreadPtr()->GetName()).GetCString(); - return name; + return nullptr; } const char *SBThread::GetQueueName() const { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; std::unique_lock<std::recursive_mutex> lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - if (exe_ctx.HasThreadScope()) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - name = exe_ctx.GetThreadPtr()->GetQueueName(); - } - } + if (!exe_ctx.HasThreadScope()) + return nullptr; - return name; + Process::StopLocker stop_locker; + if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) + return ConstString(exe_ctx.GetThreadPtr()->GetQueueName()).GetCString(); + + return nullptr; } lldb::queue_id_t SBThread::GetQueueID() const { @@ -459,11 +457,11 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { info_root_sp->GetObjectForDotSeparatedPath(path); if (node) { if (node->GetType() == eStructuredDataTypeString) { - strm.Printf("%s", node->GetAsString()->GetValue().str().c_str()); + strm.ref() << node->GetAsString()->GetValue(); success = true; } if (node->GetType() == eStructuredDataTypeInteger) { - strm.Printf("0x%" PRIx64, node->GetAsInteger()->GetValue()); + strm.Printf("0x%" PRIx64, node->GetUnsignedIntegerValue()); success = true; } if (node->GetType() == eStructuredDataTypeFloat) { @@ -789,7 +787,11 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, } if (!frame_sp) { - frame_sp = thread->GetSelectedFrame(); + // We don't want to run SelectMostRelevantFrame here, for instance if + // you called a sequence of StepOverUntil's you wouldn't want the + // frame changed out from under you because you stepped into a + // recognized frame. + frame_sp = thread->GetSelectedFrame(DoNoSelectMostRelevantFrame); if (!frame_sp) frame_sp = thread->GetStackFrameAtIndex(0); } @@ -843,20 +845,14 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, SymbolContextList sc_list; frame_sc.comp_unit->ResolveSymbolContext(location_spec, eSymbolContextLineEntry, sc_list); - const uint32_t num_matches = sc_list.GetSize(); - if (num_matches > 0) { - SymbolContext sc; - for (uint32_t i = 0; i < num_matches; ++i) { - if (sc_list.GetContextAtIndex(i, sc)) { - addr_t step_addr = - sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); - if (step_addr != LLDB_INVALID_ADDRESS) { - if (fun_range.ContainsLoadAddress(step_addr, target)) - step_over_until_addrs.push_back(step_addr); - else - all_in_function = false; - } - } + for (const SymbolContext &sc : sc_list) { + addr_t step_addr = + sc.line_entry.range.GetBaseAddress().GetLoadAddress(target); + if (step_addr != LLDB_INVALID_ADDRESS) { + if (fun_range.ContainsLoadAddress(step_addr, target)) + step_over_until_addrs.push_back(step_addr); + else + all_in_function = false; } } @@ -1133,7 +1129,8 @@ lldb::SBFrame SBThread::GetSelectedFrame() { if (exe_ctx.HasThreadScope()) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&exe_ctx.GetProcessPtr()->GetRunLock())) { - frame_sp = exe_ctx.GetThreadPtr()->GetSelectedFrame(); + frame_sp = + exe_ctx.GetThreadPtr()->GetSelectedFrame(SelectMostRelevantFrame); sb_frame.SetFrameSP(frame_sp); } } diff --git a/contrib/llvm-project/lldb/source/API/SBTrace.cpp b/contrib/llvm-project/lldb/source/API/SBTrace.cpp index 5e9d53e3d186..da31d173425e 100644 --- a/contrib/llvm-project/lldb/source/API/SBTrace.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTrace.cpp @@ -84,7 +84,10 @@ SBFileSpec SBTrace::SaveToDisk(SBError &error, const SBFileSpec &bundle_dir, const char *SBTrace::GetStartConfigurationHelp() { LLDB_INSTRUMENT_VA(this); - return m_opaque_sp ? m_opaque_sp->GetStartConfigurationHelp() : nullptr; + if (!m_opaque_sp) + return nullptr; + + return ConstString(m_opaque_sp->GetStartConfigurationHelp()).GetCString(); } SBError SBTrace::Start(const SBStructuredData &configuration) { diff --git a/contrib/llvm-project/lldb/source/API/SBTraceCursor.cpp b/contrib/llvm-project/lldb/source/API/SBTraceCursor.cpp index f4ae31f616af..c3dacd0d4b3d 100644 --- a/contrib/llvm-project/lldb/source/API/SBTraceCursor.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTraceCursor.cpp @@ -85,7 +85,7 @@ bool SBTraceCursor::IsError() const { const char *SBTraceCursor::GetError() const { LLDB_INSTRUMENT_VA(this); - return m_opaque_sp->GetError(); + return ConstString(m_opaque_sp->GetError()).GetCString(); } bool SBTraceCursor::IsEvent() const { @@ -103,7 +103,7 @@ lldb::TraceEvent SBTraceCursor::GetEventType() const { const char *SBTraceCursor::GetEventTypeAsString() const { LLDB_INSTRUMENT_VA(this); - return m_opaque_sp->GetEventTypeAsString(); + return ConstString(m_opaque_sp->GetEventTypeAsString()).GetCString(); } bool SBTraceCursor::IsInstruction() const { diff --git a/contrib/llvm-project/lldb/source/API/SBType.cpp b/contrib/llvm-project/lldb/source/API/SBType.cpp index 1ccc3b0c2dc9..ee5b64474280 100644 --- a/contrib/llvm-project/lldb/source/API/SBType.cpp +++ b/contrib/llvm-project/lldb/source/API/SBType.cpp @@ -809,14 +809,15 @@ const char *SBTypeMemberFunction::GetName() { const char *SBTypeMemberFunction::GetDemangledName() { LLDB_INSTRUMENT_VA(this); - if (m_opaque_sp) { - ConstString mangled_str = m_opaque_sp->GetMangledName(); - if (mangled_str) { - Mangled mangled(mangled_str); - return mangled.GetDemangledName().GetCString(); - } - } - return nullptr; + if (!m_opaque_sp) + return nullptr; + + ConstString mangled_str = m_opaque_sp->GetMangledName(); + if (!mangled_str) + return nullptr; + + Mangled mangled(mangled_str); + return mangled.GetDemangledName().GetCString(); } const char *SBTypeMemberFunction::GetMangledName() { diff --git a/contrib/llvm-project/lldb/source/API/SBTypeCategory.cpp b/contrib/llvm-project/lldb/source/API/SBTypeCategory.cpp index e2911a4c50f6..3521a30c64c5 100644 --- a/contrib/llvm-project/lldb/source/API/SBTypeCategory.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTypeCategory.cpp @@ -73,7 +73,7 @@ const char *SBTypeCategory::GetName() { if (!IsValid()) return nullptr; - return m_opaque_sp->GetName(); + return ConstString(m_opaque_sp->GetName()).GetCString(); } lldb::LanguageType SBTypeCategory::GetLanguageAtIndex(uint32_t idx) { diff --git a/contrib/llvm-project/lldb/source/API/SBTypeFilter.cpp b/contrib/llvm-project/lldb/source/API/SBTypeFilter.cpp index 94f222b254b2..8bbf3a8b526f 100644 --- a/contrib/llvm-project/lldb/source/API/SBTypeFilter.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTypeFilter.cpp @@ -85,13 +85,13 @@ uint32_t SBTypeFilter::GetNumberOfExpressionPaths() { const char *SBTypeFilter::GetExpressionPathAtIndex(uint32_t i) { LLDB_INSTRUMENT_VA(this, i); - if (IsValid()) { - const char *item = m_opaque_sp->GetExpressionPathAtIndex(i); - if (item && *item == '.') - item++; - return item; - } - return nullptr; + if (!IsValid()) + return nullptr; + + const char *item = m_opaque_sp->GetExpressionPathAtIndex(i); + if (item && *item == '.') + item++; + return ConstString(item).GetCString(); } bool SBTypeFilter::ReplaceExpressionPathAtIndex(uint32_t i, const char *item) { diff --git a/contrib/llvm-project/lldb/source/API/SBTypeNameSpecifier.cpp b/contrib/llvm-project/lldb/source/API/SBTypeNameSpecifier.cpp index 8a6eb086a9b1..308b1cd6b2be 100644 --- a/contrib/llvm-project/lldb/source/API/SBTypeNameSpecifier.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTypeNameSpecifier.cpp @@ -65,7 +65,7 @@ const char *SBTypeNameSpecifier::GetName() { if (!IsValid()) return nullptr; - return m_opaque_sp->GetName(); + return ConstString(m_opaque_sp->GetName()).GetCString(); } SBType SBTypeNameSpecifier::GetType() { diff --git a/contrib/llvm-project/lldb/source/API/SBTypeSummary.cpp b/contrib/llvm-project/lldb/source/API/SBTypeSummary.cpp index a65dfc987ad2..be43aeb48261 100644 --- a/contrib/llvm-project/lldb/source/API/SBTypeSummary.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTypeSummary.cpp @@ -222,11 +222,11 @@ const char *SBTypeSummary::GetData() { const char *fname = script_summary_ptr->GetFunctionName(); const char *ftext = script_summary_ptr->GetPythonScript(); if (ftext && *ftext) - return ftext; - return fname; + return ConstString(ftext).GetCString(); + return ConstString(fname).GetCString(); } else if (StringSummaryFormat *string_summary_ptr = llvm::dyn_cast<StringSummaryFormat>(m_opaque_sp.get())) - return string_summary_ptr->GetSummaryString(); + return ConstString(string_summary_ptr->GetSummaryString()).GetCString(); return nullptr; } diff --git a/contrib/llvm-project/lldb/source/API/SBTypeSynthetic.cpp b/contrib/llvm-project/lldb/source/API/SBTypeSynthetic.cpp index 7258ff04745d..e2441eea7e10 100644 --- a/contrib/llvm-project/lldb/source/API/SBTypeSynthetic.cpp +++ b/contrib/llvm-project/lldb/source/API/SBTypeSynthetic.cpp @@ -78,9 +78,9 @@ const char *SBTypeSynthetic::GetData() { if (!IsValid()) return nullptr; if (IsClassCode()) - return m_opaque_sp->GetPythonCode(); - else - return m_opaque_sp->GetPythonClassName(); + return ConstString(m_opaque_sp->GetPythonCode()).GetCString(); + + return ConstString(m_opaque_sp->GetPythonClassName()).GetCString(); } void SBTypeSynthetic::SetClassName(const char *data) { diff --git a/contrib/llvm-project/lldb/source/API/SBUnixSignals.cpp b/contrib/llvm-project/lldb/source/API/SBUnixSignals.cpp index dc7a68255d13..7cccbaff1d2f 100644 --- a/contrib/llvm-project/lldb/source/API/SBUnixSignals.cpp +++ b/contrib/llvm-project/lldb/source/API/SBUnixSignals.cpp @@ -66,7 +66,7 @@ const char *SBUnixSignals::GetSignalAsCString(int32_t signo) const { LLDB_INSTRUMENT_VA(this, signo); if (auto signals_sp = GetSP()) - return signals_sp->GetSignalAsCString(signo); + return ConstString(signals_sp->GetSignalAsCString(signo)).GetCString(); return nullptr; } diff --git a/contrib/llvm-project/lldb/source/API/SBValue.cpp b/contrib/llvm-project/lldb/source/API/SBValue.cpp index f9e03172a4d0..e8ed36380d37 100644 --- a/contrib/llvm-project/lldb/source/API/SBValue.cpp +++ b/contrib/llvm-project/lldb/source/API/SBValue.cpp @@ -114,6 +114,10 @@ public: lldb::ValueObjectSP value_sp = m_valobj_sp; Target *target = value_sp->GetTargetSP().get(); + // If this ValueObject holds an error, then it is valuable for that. + if (value_sp->GetError().Fail()) + return value_sp; + if (!target) return ValueObjectSP(); @@ -287,39 +291,34 @@ user_id_t SBValue::GetID() { const char *SBValue::GetName() { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); - if (value_sp) - name = value_sp->GetName().GetCString(); + if (!value_sp) + return nullptr; - return name; + return value_sp->GetName().GetCString(); } const char *SBValue::GetTypeName() { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); - if (value_sp) { - name = value_sp->GetQualifiedTypeName().GetCString(); - } + if (!value_sp) + return nullptr; - return name; + return value_sp->GetQualifiedTypeName().GetCString(); } const char *SBValue::GetDisplayTypeName() { LLDB_INSTRUMENT_VA(this); - const char *name = nullptr; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); - if (value_sp) { - name = value_sp->GetDisplayTypeName().GetCString(); - } + if (!value_sp) + return nullptr; - return name; + return value_sp->GetDisplayTypeName().GetCString(); } size_t SBValue::GetByteSize() { @@ -353,14 +352,11 @@ bool SBValue::IsInScope() { const char *SBValue::GetValue() { LLDB_INSTRUMENT_VA(this); - const char *cstr = nullptr; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); - if (value_sp) { - cstr = value_sp->GetValueAsCString(); - } - - return cstr; + if (!value_sp) + return nullptr; + return ConstString(value_sp->GetValueAsCString()).GetCString(); } ValueType SBValue::GetValueType() { @@ -378,14 +374,12 @@ ValueType SBValue::GetValueType() { const char *SBValue::GetObjectDescription() { LLDB_INSTRUMENT_VA(this); - const char *cstr = nullptr; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); - if (value_sp) { - cstr = value_sp->GetObjectDescription(); - } + if (!value_sp) + return nullptr; - return cstr; + return ConstString(value_sp->GetObjectDescription()).GetCString(); } SBType SBValue::GetType() { @@ -420,14 +414,12 @@ bool SBValue::GetValueDidChange() { const char *SBValue::GetSummary() { LLDB_INSTRUMENT_VA(this); - const char *cstr = nullptr; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); - if (value_sp) { - cstr = value_sp->GetSummaryAsCString(); - } + if (!value_sp) + return nullptr; - return cstr; + return ConstString(value_sp->GetSummaryAsCString()).GetCString(); } const char *SBValue::GetSummary(lldb::SBStream &stream, @@ -441,20 +433,18 @@ const char *SBValue::GetSummary(lldb::SBStream &stream, if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty()) stream.Printf("%s", buffer.c_str()); } - const char *cstr = stream.GetData(); - return cstr; + return ConstString(stream.GetData()).GetCString(); } const char *SBValue::GetLocation() { LLDB_INSTRUMENT_VA(this); - const char *cstr = nullptr; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); - if (value_sp) { - cstr = value_sp->GetLocationAsCString(); - } - return cstr; + if (!value_sp) + return nullptr; + + return ConstString(value_sp->GetLocationAsCString()).GetCString(); } // Deprecated - use the one that takes an lldb::SBError @@ -678,7 +668,7 @@ SBValue SBValue::GetChildAtIndex(uint32_t idx, lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { const bool can_create = true; - child_sp = value_sp->GetChildAtIndex(idx, can_create); + child_sp = value_sp->GetChildAtIndex(idx); if (can_create_synthetic && !child_sp) { child_sp = value_sp->GetSyntheticArrayMember(idx, can_create); } @@ -697,7 +687,7 @@ uint32_t SBValue::GetIndexOfChildWithName(const char *name) { ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { - idx = value_sp->GetIndexOfChildWithName(ConstString(name)); + idx = value_sp->GetIndexOfChildWithName(name); } return idx; } @@ -721,12 +711,11 @@ SBValue::GetChildMemberWithName(const char *name, LLDB_INSTRUMENT_VA(this, name, use_dynamic_value); lldb::ValueObjectSP child_sp; - const ConstString str_name(name); ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { - child_sp = value_sp->GetChildMemberWithName(str_name, true); + child_sp = value_sp->GetChildMemberWithName(name); } SBValue sb_value; @@ -1047,7 +1036,12 @@ lldb::SBFrame SBValue::GetFrame() { } lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const { - if (!m_opaque_sp || !m_opaque_sp->IsValid()) { + // IsValid means that the SBValue has a value in it. But that's not the + // only time that ValueObjects are useful. We also want to return the value + // if there's an error state in it. + if (!m_opaque_sp || (!m_opaque_sp->IsValid() + && (m_opaque_sp->GetRootSP() + && !m_opaque_sp->GetRootSP()->GetError().Fail()))) { locker.GetError().SetErrorString("No value"); return ValueObjectSP(); } diff --git a/contrib/llvm-project/lldb/source/API/SBWatchpoint.cpp b/contrib/llvm-project/lldb/source/API/SBWatchpoint.cpp index f5bd9cd1a946..f5a7f53a8b30 100644 --- a/contrib/llvm-project/lldb/source/API/SBWatchpoint.cpp +++ b/contrib/llvm-project/lldb/source/API/SBWatchpoint.cpp @@ -17,6 +17,7 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Breakpoint/WatchpointList.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Symbol/CompilerType.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Stream.h" @@ -209,12 +210,12 @@ const char *SBWatchpoint::GetCondition() { LLDB_INSTRUMENT_VA(this); lldb::WatchpointSP watchpoint_sp(GetSP()); - if (watchpoint_sp) { - std::lock_guard<std::recursive_mutex> guard( - watchpoint_sp->GetTarget().GetAPIMutex()); - return watchpoint_sp->GetConditionText(); - } - return nullptr; + if (!watchpoint_sp) + return nullptr; + + std::lock_guard<std::recursive_mutex> guard( + watchpoint_sp->GetTarget().GetAPIMutex()); + return ConstString(watchpoint_sp->GetConditionText()).GetCString(); } void SBWatchpoint::SetCondition(const char *condition) { @@ -290,3 +291,72 @@ SBWatchpoint SBWatchpoint::GetWatchpointFromEvent(const lldb::SBEvent &event) { Watchpoint::WatchpointEventData::GetWatchpointFromEvent(event.GetSP()); return sb_watchpoint; } + +lldb::SBType SBWatchpoint::GetType() { + LLDB_INSTRUMENT_VA(this); + + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) { + std::lock_guard<std::recursive_mutex> guard( + watchpoint_sp->GetTarget().GetAPIMutex()); + const CompilerType &type = watchpoint_sp->GetCompilerType(); + return lldb::SBType(type); + } + return lldb::SBType(); +} + +WatchpointValueKind SBWatchpoint::GetWatchValueKind() { + LLDB_INSTRUMENT_VA(this); + + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) { + std::lock_guard<std::recursive_mutex> guard( + watchpoint_sp->GetTarget().GetAPIMutex()); + if (watchpoint_sp->IsWatchVariable()) + return WatchpointValueKind::eWatchPointValueKindVariable; + return WatchpointValueKind::eWatchPointValueKindExpression; + } + return WatchpointValueKind::eWatchPointValueKindInvalid; +} + +const char *SBWatchpoint::GetWatchSpec() { + LLDB_INSTRUMENT_VA(this); + + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (!watchpoint_sp) + return nullptr; + + std::lock_guard<std::recursive_mutex> guard( + watchpoint_sp->GetTarget().GetAPIMutex()); + // Store the result of `GetWatchSpec()` as a ConstString + // so that the C string we return has a sufficiently long + // lifetime. Note this a memory leak but should be fairly + // low impact. + return ConstString(watchpoint_sp->GetWatchSpec()).AsCString(); +} + +bool SBWatchpoint::IsWatchingReads() { + LLDB_INSTRUMENT_VA(this); + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) { + std::lock_guard<std::recursive_mutex> guard( + watchpoint_sp->GetTarget().GetAPIMutex()); + + return watchpoint_sp->WatchpointRead(); + } + + return false; +} + +bool SBWatchpoint::IsWatchingWrites() { + LLDB_INSTRUMENT_VA(this); + lldb::WatchpointSP watchpoint_sp(GetSP()); + if (watchpoint_sp) { + std::lock_guard<std::recursive_mutex> guard( + watchpoint_sp->GetTarget().GetAPIMutex()); + + return watchpoint_sp->WatchpointWrite(); + } + + return false; +} diff --git a/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp b/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp index 521aecf36fd8..27319debc858 100644 --- a/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp +++ b/contrib/llvm-project/lldb/source/API/SystemInitializerFull.cpp @@ -78,6 +78,9 @@ llvm::Error SystemInitializerFull::Initialize() { // Settings must be initialized AFTER PluginManager::Initialize is called. Debugger::SettingsInitialize(); + // Use the Debugger's LLDBAssert callback. + SetLLDBAssertCallback(Debugger::AssertCallback); + return llvm::Error::success(); } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp index aad01a2e6fb6..9f00c967be43 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/Breakpoint.cpp @@ -37,11 +37,6 @@ using namespace lldb; using namespace lldb_private; using namespace llvm; -ConstString Breakpoint::GetEventIdentifier() { - static ConstString g_identifier("event-identifier.breakpoint.changed"); - return g_identifier; -} - const char *Breakpoint::g_option_names[static_cast<uint32_t>( Breakpoint::OptionNames::LastOptionName)]{"Names", "Hardware"}; @@ -532,12 +527,12 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load, locations_with_no_section.Add(break_loc_sp); continue; } - + if (!break_loc_sp->IsEnabled()) continue; - + SectionSP section_sp(section_addr.GetSection()); - + // If we don't have a Section, that means this location is a raw // address that we haven't resolved to a section yet. So we'll have to // look in all the new modules to resolve this location. Otherwise, if @@ -554,9 +549,9 @@ void Breakpoint::ModulesChanged(ModuleList &module_list, bool load, } } } - + size_t num_to_delete = locations_with_no_section.GetSize(); - + for (size_t i = 0; i < num_to_delete; i++) m_locations.RemoveLocation(locations_with_no_section.GetByIndex(i)); @@ -847,7 +842,7 @@ bool Breakpoint::HasResolvedLocations() const { size_t Breakpoint::GetNumLocations() const { return m_locations.GetSize(); } bool Breakpoint::AddName(llvm::StringRef new_name) { - m_name_list.insert(new_name.str().c_str()); + m_name_list.insert(new_name.str()); return true; } @@ -1044,12 +1039,11 @@ Breakpoint::BreakpointEventData::BreakpointEventData( Breakpoint::BreakpointEventData::~BreakpointEventData() = default; -ConstString Breakpoint::BreakpointEventData::GetFlavorString() { - static ConstString g_flavor("Breakpoint::BreakpointEventData"); - return g_flavor; +llvm::StringRef Breakpoint::BreakpointEventData::GetFlavorString() { + return "Breakpoint::BreakpointEventData"; } -ConstString Breakpoint::BreakpointEventData::GetFlavor() const { +llvm::StringRef Breakpoint::BreakpointEventData::GetFlavor() const { return BreakpointEventData::GetFlavorString(); } @@ -1132,12 +1126,13 @@ json::Value Breakpoint::GetStatistics() { bp.try_emplace("resolveTime", m_resolve_time.get().count()); bp.try_emplace("numLocations", (int64_t)GetNumLocations()); bp.try_emplace("numResolvedLocations", (int64_t)GetNumResolvedLocations()); + bp.try_emplace("hitCount", (int64_t)GetHitCount()); bp.try_emplace("internal", IsInternal()); if (!m_kind_description.empty()) bp.try_emplace("kindDescription", m_kind_description); // Put the full structured data for reproducing this breakpoint in a key/value // pair named "details". This allows the breakpoint's details to be visible - // in the stats in case we need to reproduce a breakpoint that has long + // in the stats in case we need to reproduce a breakpoint that has long // resolve times StructuredData::ObjectSP bp_data_sp = SerializeToStructuredData(); if (bp_data_sp) { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp index 0ee8bcf491ea..3ead1eca6913 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -290,7 +290,7 @@ bool BreakpointLocation::ConditionSaysStop(ExecutionContext &exe_ctx, options.SetUnwindOnError(true); options.SetIgnoreBreakpoints(true); options.SetTryAllThreads(true); - options.SetResultIsInternal( + options.SetSuppressPersistentResult( true); // Don't generate a user variable for condition expressions. Status expr_error; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp index 31779fbf693a..268c52341dfe 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -230,7 +230,7 @@ std::unique_ptr<BreakpointOptions> BreakpointOptions::CreateFromStructuredData( bool enabled = true; bool one_shot = false; bool auto_continue = false; - int32_t ignore_count = 0; + uint32_t ignore_count = 0; llvm::StringRef condition_ref(""); Flags set_options; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp index 5c03798a7427..c1e77d3c70da 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -102,7 +102,7 @@ BreakpointResolverSP BreakpointResolver::CreateFromStructuredData( return result_sp; } - lldb::addr_t offset; + lldb::offset_t offset; success = subclass_options->GetValueForKeyAsInteger( GetKey(OptionNames::Offset), offset); if (!success) { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp index c173fc0c2a7a..26f289103bb8 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverAddress.cpp @@ -34,7 +34,7 @@ BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData( const BreakpointSP &bkpt, const StructuredData::Dictionary &options_dict, Status &error) { llvm::StringRef module_name; - lldb::addr_t addr_offset; + lldb::offset_t addr_offset; FileSpec module_filespec; bool success; diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index 890b38af5c88..04374decd363 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -192,7 +192,7 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list) { } void BreakpointResolverFileLine::DeduceSourceMapping( - SymbolContextList &sc_list) { + const SymbolContextList &sc_list) { Target &target = GetBreakpoint()->GetTarget(); if (!target.GetAutoSourceMapRelative()) return; @@ -223,13 +223,10 @@ void BreakpointResolverFileLine::DeduceSourceMapping( return; const bool case_sensitive = request_file.IsCaseSensitive(); - for (uint32_t i = 0; i < sc_list.GetSize(); ++i) { - SymbolContext sc; - sc_list.GetContextAtIndex(i, sc); - + for (const SymbolContext &sc : sc_list) { FileSpec sc_file = sc.line_entry.file; - if (FileSpec::Equal(sc_file, request_file, /*full*/true)) + if (FileSpec::Equal(sc_file, request_file, /*full*/ true)) continue; llvm::StringRef sc_file_dir = sc_file.GetDirectory().GetStringRef(); diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp index dbaeec9c9afb..b533bdfb9c11 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -104,7 +104,7 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData( } } - lldb::addr_t offset = 0; + lldb::offset_t offset = 0; success = options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset); if (!success) { @@ -197,8 +197,8 @@ StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() { for (auto lookup : m_lookups) { names_sp->AddItem(StructuredData::StringSP( new StructuredData::String(lookup.GetName().GetStringRef()))); - name_masks_sp->AddItem(StructuredData::IntegerSP( - new StructuredData::Integer(lookup.GetNameTypeMask()))); + name_masks_sp->AddItem(StructuredData::UnsignedIntegerSP( + new StructuredData::UnsignedInteger(lookup.GetNameTypeMask()))); } options_dict_sp->AddItem(GetKey(OptionNames::SymbolNameArray), names_sp); options_dict_sp->AddItem(GetKey(OptionNames::NameMaskArray), name_masks_sp); @@ -331,14 +331,7 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, Address break_addr; // Remove any duplicates between the function list and the symbol list - SymbolContext sc; - if (!func_list.GetSize()) - return Searcher::eCallbackReturnContinue; - - for (uint32_t i = 0; i < func_list.GetSize(); i++) { - if (!func_list.GetContextAtIndex(i, sc)) - continue; - + for (const SymbolContext &sc : func_list) { bool is_reexported = false; if (sc.block && sc.block->GetInlinedFunctionInfo()) { diff --git a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp index 32a2f24d411a..ab15da82ea45 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/BreakpointSiteList.cpp @@ -48,15 +48,8 @@ bool BreakpointSiteList::ShouldStop(StoppointCallbackContext *context, return true; } lldb::break_id_t BreakpointSiteList::FindIDByAddress(lldb::addr_t addr) { - BreakpointSiteSP bp = FindByAddress(addr); - if (bp) { - // DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8" - // PRIx64 " ) => %u", __FUNCTION__, (uint64_t)addr, bp->GetID()); + if (BreakpointSiteSP bp = FindByAddress(addr)) return bp.get()->GetID(); - } - // DBLogIf(PD_LOG_BREAKPOINTS, "BreakpointSiteList::%s ( addr = 0x%8.8" - // PRIx64 - // " ) => NONE", __FUNCTION__, (uint64_t)addr); return LLDB_INVALID_BREAK_ID; } diff --git a/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp b/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp index 0ad3498dac54..a20a4ad98c5a 100644 --- a/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Breakpoint/Watchpoint.cpp @@ -29,8 +29,7 @@ Watchpoint::Watchpoint(Target &target, lldb::addr_t addr, uint32_t size, : StoppointSite(0, addr, size, hardware), m_target(target), 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_being_created(true) { + m_watch_write(0), m_ignore_count(0), m_being_created(true) { if (type && type->IsValid()) m_type = *type; @@ -41,14 +40,14 @@ Watchpoint::Watchpoint(Target &target, lldb::addr_t addr, uint32_t size, target.GetScratchTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Watchpoints), std::move(err), - "Failed to set type."); + "Failed to set type: {0}"); } else { if (auto ts = *type_system_or_err) m_type = ts->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8 * size); else LLDB_LOG_ERROR(GetLog(LLDBLog::Watchpoints), std::move(err), - "Failed to set type. Typesystem is no longer live."); + "Failed to set type: Typesystem is no longer live: {0}"); } } @@ -83,6 +82,94 @@ void Watchpoint::SetCallback(WatchpointHitCallback callback, SendWatchpointChangedEvent(eWatchpointEventTypeCommandChanged); } +bool Watchpoint::SetupVariableWatchpointDisabler(StackFrameSP frame_sp) const { + if (!frame_sp) + return false; + + ThreadSP thread_sp = frame_sp->GetThread(); + if (!thread_sp) + return false; + + uint32_t return_frame_index = + thread_sp->GetSelectedFrameIndex(DoNoSelectMostRelevantFrame) + 1; + if (return_frame_index >= LLDB_INVALID_FRAME_ID) + return false; + + StackFrameSP return_frame_sp( + thread_sp->GetStackFrameAtIndex(return_frame_index)); + if (!return_frame_sp) + return false; + + ExecutionContext exe_ctx(return_frame_sp); + TargetSP target_sp = exe_ctx.GetTargetSP(); + if (!target_sp) + return false; + + Address return_address(return_frame_sp->GetFrameCodeAddress()); + lldb::addr_t return_addr = return_address.GetLoadAddress(target_sp.get()); + if (return_addr == LLDB_INVALID_ADDRESS) + return false; + + BreakpointSP bp_sp = target_sp->CreateBreakpoint( + return_addr, /*internal=*/true, /*request_hardware=*/false); + if (!bp_sp || !bp_sp->HasResolvedLocations()) + return false; + + auto wvc_up = std::make_unique<WatchpointVariableContext>(GetID(), exe_ctx); + auto baton_sp = std::make_shared<WatchpointVariableBaton>(std::move(wvc_up)); + bp_sp->SetCallback(VariableWatchpointDisabler, baton_sp); + bp_sp->SetOneShot(true); + bp_sp->SetBreakpointKind("variable watchpoint disabler"); + return true; +} + +bool Watchpoint::VariableWatchpointDisabler(void *baton, + StoppointCallbackContext *context, + user_id_t break_id, + user_id_t break_loc_id) { + assert(baton && "null baton"); + if (!baton || !context) + return false; + + Log *log = GetLog(LLDBLog::Watchpoints); + + WatchpointVariableContext *wvc = + static_cast<WatchpointVariableContext *>(baton); + + LLDB_LOGF(log, "called by breakpoint %" PRIu64 ".%" PRIu64, break_id, + break_loc_id); + + if (wvc->watch_id == LLDB_INVALID_WATCH_ID) + return false; + + TargetSP target_sp = context->exe_ctx_ref.GetTargetSP(); + if (!target_sp) + return false; + + ProcessSP process_sp = target_sp->GetProcessSP(); + if (!process_sp) + return false; + + WatchpointSP watch_sp = + target_sp->GetWatchpointList().FindByID(wvc->watch_id); + if (!watch_sp) + return false; + + if (wvc->exe_ctx == context->exe_ctx_ref) { + LLDB_LOGF(log, + "callback for watchpoint %" PRId32 + " matched internal breakpoint execution context", + watch_sp->GetID()); + process_sp->DisableWatchpoint(watch_sp.get()); + return false; + } + LLDB_LOGF(log, + "callback for watchpoint %" PRId32 + " didn't match internal breakpoint execution context", + watch_sp->GetID()); + return false; +} + void Watchpoint::ClearCallback() { m_options.ClearCallback(); SendWatchpointChangedEvent(eWatchpointEventTypeCommandChanged); @@ -124,19 +211,6 @@ bool Watchpoint::CaptureWatchedValue(const ExecutionContext &exe_ctx) { return (m_new_value_sp && m_new_value_sp->GetError().Success()); } -void Watchpoint::IncrementFalseAlarmsAndReviseHitCount() { - ++m_false_alarms; - if (m_false_alarms) { - if (m_hit_counter.GetValue() >= m_false_alarms) { - m_hit_counter.Decrement(m_false_alarms); - m_false_alarms = 0; - } else { - m_false_alarms -= m_hit_counter.GetValue(); - m_hit_counter.Reset(); - } - } -} - // RETURNS - true if we should stop at this breakpoint, false if we // should continue. @@ -337,12 +411,11 @@ Watchpoint::WatchpointEventData::WatchpointEventData( Watchpoint::WatchpointEventData::~WatchpointEventData() = default; -ConstString Watchpoint::WatchpointEventData::GetFlavorString() { - static ConstString g_flavor("Watchpoint::WatchpointEventData"); - return g_flavor; +llvm::StringRef Watchpoint::WatchpointEventData::GetFlavorString() { + return "Watchpoint::WatchpointEventData"; } -ConstString Watchpoint::WatchpointEventData::GetFlavor() const { +llvm::StringRef Watchpoint::WatchpointEventData::GetFlavor() const { return WatchpointEventData::GetFlavorString(); } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp index ae1ee1fdd30b..4d7e3d7f2497 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandCompletions.cpp @@ -10,7 +10,6 @@ #include "llvm/ADT/StringSet.h" #include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/DataFormatters/DataVisualization.h" @@ -27,6 +26,7 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/TildeExpressionResolver.h" @@ -54,37 +54,41 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks( bool handled = false; const CommonCompletionElement common_completions[] = { - {eSourceFileCompletion, CommandCompletions::SourceFiles}, - {eDiskFileCompletion, CommandCompletions::DiskFiles}, - {eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, - {eSymbolCompletion, CommandCompletions::Symbols}, - {eModuleCompletion, CommandCompletions::Modules}, - {eModuleUUIDCompletion, CommandCompletions::ModuleUUIDs}, - {eSettingsNameCompletion, CommandCompletions::SettingsNames}, - {ePlatformPluginCompletion, CommandCompletions::PlatformPluginNames}, - {eArchitectureCompletion, CommandCompletions::ArchitectureNames}, - {eVariablePathCompletion, CommandCompletions::VariablePath}, - {eRegisterCompletion, CommandCompletions::Registers}, - {eBreakpointCompletion, CommandCompletions::Breakpoints}, - {eProcessPluginCompletion, CommandCompletions::ProcessPluginNames}, - {eDisassemblyFlavorCompletion, CommandCompletions::DisassemblyFlavors}, - {eTypeLanguageCompletion, CommandCompletions::TypeLanguages}, - {eFrameIndexCompletion, CommandCompletions::FrameIndexes}, - {eStopHookIDCompletion, CommandCompletions::StopHookIDs}, - {eThreadIndexCompletion, CommandCompletions::ThreadIndexes}, - {eWatchPointIDCompletion, CommandCompletions::WatchPointIDs}, - {eBreakpointNameCompletion, CommandCompletions::BreakpointNames}, - {eProcessIDCompletion, CommandCompletions::ProcessIDs}, - {eProcessNameCompletion, CommandCompletions::ProcessNames}, - {eRemoteDiskFileCompletion, CommandCompletions::RemoteDiskFiles}, - {eRemoteDiskDirectoryCompletion, + {lldb::eSourceFileCompletion, CommandCompletions::SourceFiles}, + {lldb::eDiskFileCompletion, CommandCompletions::DiskFiles}, + {lldb::eDiskDirectoryCompletion, CommandCompletions::DiskDirectories}, + {lldb::eSymbolCompletion, CommandCompletions::Symbols}, + {lldb::eModuleCompletion, CommandCompletions::Modules}, + {lldb::eModuleUUIDCompletion, CommandCompletions::ModuleUUIDs}, + {lldb::eSettingsNameCompletion, CommandCompletions::SettingsNames}, + {lldb::ePlatformPluginCompletion, + CommandCompletions::PlatformPluginNames}, + {lldb::eArchitectureCompletion, CommandCompletions::ArchitectureNames}, + {lldb::eVariablePathCompletion, CommandCompletions::VariablePath}, + {lldb::eRegisterCompletion, CommandCompletions::Registers}, + {lldb::eBreakpointCompletion, CommandCompletions::Breakpoints}, + {lldb::eProcessPluginCompletion, CommandCompletions::ProcessPluginNames}, + {lldb::eDisassemblyFlavorCompletion, + CommandCompletions::DisassemblyFlavors}, + {lldb::eTypeLanguageCompletion, CommandCompletions::TypeLanguages}, + {lldb::eFrameIndexCompletion, CommandCompletions::FrameIndexes}, + {lldb::eStopHookIDCompletion, CommandCompletions::StopHookIDs}, + {lldb::eThreadIndexCompletion, CommandCompletions::ThreadIndexes}, + {lldb::eWatchpointIDCompletion, CommandCompletions::WatchPointIDs}, + {lldb::eBreakpointNameCompletion, CommandCompletions::BreakpointNames}, + {lldb::eProcessIDCompletion, CommandCompletions::ProcessIDs}, + {lldb::eProcessNameCompletion, CommandCompletions::ProcessNames}, + {lldb::eRemoteDiskFileCompletion, CommandCompletions::RemoteDiskFiles}, + {lldb::eRemoteDiskDirectoryCompletion, CommandCompletions::RemoteDiskDirectories}, - {eTypeCategoryNameCompletion, CommandCompletions::TypeCategoryNames}, - {eNoCompletion, nullptr} // This one has to be last in the list. + {lldb::eTypeCategoryNameCompletion, + CommandCompletions::TypeCategoryNames}, + {lldb::CompletionType::eNoCompletion, + nullptr} // This one has to be last in the list. }; for (int i = 0;; i++) { - if (common_completions[i].type == eNoCompletion) + if (common_completions[i].type == lldb::eNoCompletion) break; else if ((common_completions[i].type & completion_mask) == common_completions[i].type && @@ -220,18 +224,15 @@ public: function_options.include_inlines = true; context.module_sp->FindFunctions(m_regex, function_options, sc_list); - SymbolContext sc; // Now add the functions & symbols to the list - only add if unique: - for (uint32_t i = 0; i < sc_list.GetSize(); i++) { - if (sc_list.GetContextAtIndex(i, sc)) { - ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled); - // Ensure that the function name matches the regex. This is more than - // a sanity check. It is possible that the demangled function name - // does not start with the prefix, for example when it's in an - // anonymous namespace. - if (!func_name.IsEmpty() && m_regex.Execute(func_name.GetStringRef())) - m_match_set.insert(func_name); - } + for (const SymbolContext &sc : sc_list) { + ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled); + // Ensure that the function name matches the regex. This is more than + // a sanity check. It is possible that the demangled function name + // does not start with the prefix, for example when it's in an + // anonymous namespace. + if (!func_name.IsEmpty() && m_regex.Execute(func_name.GetStringRef())) + m_match_set.insert(func_name); } } return Searcher::eCallbackReturnContinue; @@ -380,6 +381,8 @@ static void DiskFilesOrDirectories(const llvm::Twine &partial_name, Storage.append(RemainderDir); } SearchDir = Storage; + } else if (CompletionBuffer == path::root_directory(CompletionBuffer)) { + SearchDir = CompletionBuffer; } else { SearchDir = path::parent_path(CompletionBuffer); } @@ -389,9 +392,11 @@ static void DiskFilesOrDirectories(const llvm::Twine &partial_name, PartialItem = path::filename(CompletionBuffer); // path::filename() will return "." when the passed path ends with a - // directory separator. We have to filter those out, but only when the - // "." doesn't come from the completion request itself. - if (PartialItem == "." && path::is_separator(CompletionBuffer.back())) + // directory separator or the separator when passed the disk root directory. + // We have to filter those out, but only when the "." doesn't come from the + // completion request itself. + if ((PartialItem == "." || PartialItem == path::get_separator()) && + path::is_separator(CompletionBuffer.back())) PartialItem = llvm::StringRef(); if (SearchDir.empty()) { @@ -606,6 +611,9 @@ void CommandCompletions::Registers(CommandInterpreter &interpreter, RegisterContext *reg_ctx = interpreter.GetExecutionContext().GetRegisterContext(); + if (!reg_ctx) + return; + const size_t reg_num = reg_ctx->GetRegisterCount(); for (size_t reg_idx = 0; reg_idx < reg_num; ++reg_idx) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx); @@ -721,10 +729,14 @@ void CommandCompletions::FrameIndexes(CommandInterpreter &interpreter, return; lldb::ThreadSP thread_sp = exe_ctx.GetThreadSP(); + Debugger &dbg = interpreter.GetDebugger(); const uint32_t frame_num = thread_sp->GetStackFrameCount(); for (uint32_t i = 0; i < frame_num; ++i) { lldb::StackFrameSP frame_sp = thread_sp->GetStackFrameAtIndex(i); StreamString strm; + // Dumping frames can be slow, allow interruption. + if (INTERRUPT_REQUESTED(dbg, "Interrupted in frame completion")) + break; frame_sp->Dump(&strm, false, true); request.TryCompleteCurrentArg(std::to_string(i), strm.GetString()); } @@ -745,7 +757,7 @@ void CommandCompletions::StopHookIDs(CommandInterpreter &interpreter, // neater. strm.SetIndentLevel(11); const Target::StopHookSP stophook_sp = target_sp->GetStopHookAtIndex(idx); - stophook_sp->GetDescription(&strm, lldb::eDescriptionLevelInitial); + stophook_sp->GetDescription(strm, lldb::eDescriptionLevelInitial); request.TryCompleteCurrentArg(std::to_string(stophook_sp->GetID()), strm.GetString()); } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp index 8c31630231b5..327dae4fd2af 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -828,9 +828,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eBreakpointCompletion, request, nullptr); } Options *GetOptions() override { return &m_options; } @@ -902,9 +901,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eBreakpointCompletion, request, nullptr); } protected: @@ -1017,9 +1015,8 @@ the second re-enables the first location."); void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eBreakpointCompletion, request, nullptr); } protected: @@ -1394,9 +1391,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eBreakpointCompletion, request, nullptr); } Options *GetOptions() override { return &m_options; } @@ -1739,7 +1735,8 @@ protected: // check the error: BreakpointSP bp_sp; if (m_bp_id.m_breakpoint.OptionWasSet()) { - lldb::break_id_t bp_id = m_bp_id.m_breakpoint.GetUInt64Value(); + lldb::break_id_t bp_id = + m_bp_id.m_breakpoint.GetValueAs<uint64_t>().value_or(0); bp_sp = target.GetBreakpointByID(bp_id); if (!bp_sp) { result.AppendErrorWithFormatv("Could not find specified breakpoint {0}", @@ -1755,7 +1752,10 @@ protected: if (!bp_name) continue; if (m_bp_id.m_help_string.OptionWasSet()) - bp_name->SetHelp(m_bp_id.m_help_string.GetStringValue().str().c_str()); + bp_name->SetHelp(m_bp_id.m_help_string.GetValueAs<llvm::StringRef>() + .value_or("") + .str() + .c_str()); if (bp_sp) target.ConfigureBreakpointName(*bp_name, bp_sp->GetOptions(), @@ -1799,9 +1799,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eBreakpointCompletion, request, nullptr); } Options *GetOptions() override { return &m_option_group; } @@ -1883,9 +1882,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eBreakpointCompletion, request, nullptr); } Options *GetOptions() override { return &m_option_group; } @@ -2199,9 +2197,8 @@ public: switch (GetDefinitions()[opt_defs_index].short_option) { case 'f': - CommandCompletions::InvokeCommonCompletionCallbacks( - interpreter, CommandCompletions::eDiskFileCompletion, request, - nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + interpreter, lldb::eDiskFileCompletion, request, nullptr); break; case 'N': @@ -2339,9 +2336,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eBreakpointCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eBreakpointCompletion, request, nullptr); } Options *GetOptions() override { return &m_options; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp index 7a5755d8d235..656ace223b5f 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectCommands.cpp @@ -66,9 +66,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } Options *GetOptions() override { return &m_options; } @@ -880,7 +879,7 @@ protected: Status error; auto name = command[0].ref(); m_regex_cmd_up = std::make_unique<CommandObjectRegexCommand>( - m_interpreter, name, m_options.GetHelp(), m_options.GetSyntax(), 10, 0, + m_interpreter, name, m_options.GetHelp(), m_options.GetSyntax(), 0, true); if (argc == 1) { @@ -1080,9 +1079,10 @@ class CommandObjectPythonFunction : public CommandObjectRaw { public: CommandObjectPythonFunction(CommandInterpreter &interpreter, std::string name, std::string funct, std::string help, - ScriptedCommandSynchronicity synch) + ScriptedCommandSynchronicity synch, + CompletionType completion_type) : CommandObjectRaw(interpreter, name), m_function_name(funct), - m_synchro(synch) { + m_synchro(synch), m_completion_type(completion_type) { if (!help.empty()) SetHelp(help); else { @@ -1116,6 +1116,15 @@ public: return CommandObjectRaw::GetHelpLong(); } + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), m_completion_type, request, nullptr); + } + + bool WantsCompletion() override { return true; } + protected: bool DoExecute(llvm::StringRef raw_command_line, CommandReturnObject &result) override { @@ -1146,6 +1155,7 @@ private: std::string m_function_name; ScriptedCommandSynchronicity m_synchro; bool m_fetched_help_long = false; + CompletionType m_completion_type = eNoCompletion; }; class CommandObjectScriptingObject : public CommandObjectRaw { @@ -1153,10 +1163,11 @@ public: CommandObjectScriptingObject(CommandInterpreter &interpreter, std::string name, StructuredData::GenericSP cmd_obj_sp, - ScriptedCommandSynchronicity synch) + ScriptedCommandSynchronicity synch, + CompletionType completion_type) : CommandObjectRaw(interpreter, name), m_cmd_obj_sp(cmd_obj_sp), m_synchro(synch), m_fetched_help_short(false), - m_fetched_help_long(false) { + m_fetched_help_long(false), m_completion_type(completion_type) { StreamString stream; stream.Printf("For more information run 'help %s'", name.c_str()); SetHelp(stream.GetString()); @@ -1166,6 +1177,15 @@ public: ~CommandObjectScriptingObject() override = default; + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), m_completion_type, request, nullptr); + } + + bool WantsCompletion() override { return true; } + bool IsRemovable() const override { return true; } ScriptedCommandSynchronicity GetSynchronicity() { return m_synchro; } @@ -1232,6 +1252,7 @@ private: ScriptedCommandSynchronicity m_synchro; bool m_fetched_help_short : 1; bool m_fetched_help_long : 1; + CompletionType m_completion_type = eNoCompletion; }; // CommandObjectCommandsScriptImport @@ -1263,9 +1284,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } Options *GetOptions() override { return &m_options; } @@ -1439,6 +1459,18 @@ protected: "unrecognized value for synchronicity '%s'", option_arg.str().c_str()); break; + case 'C': { + Status error; + OptionDefinition definition = GetDefinitions()[option_idx]; + lldb::CompletionType completion_type = + static_cast<lldb::CompletionType>(OptionArgParser::ToOptionEnum( + option_arg, definition.enum_values, eNoCompletion, error)); + if (!error.Success()) + error.SetErrorStringWithFormat( + "unrecognized value for command completion type '%s'", + option_arg.str().c_str()); + m_completion_type = completion_type; + } break; default: llvm_unreachable("Unimplemented option"); } @@ -1450,6 +1482,7 @@ protected: m_class_name.clear(); m_funct_name.clear(); m_short_help.clear(); + m_completion_type = eNoCompletion; m_overwrite_lazy = eLazyBoolCalculate; m_synchronicity = eScriptedCommandSynchronicitySynchronous; } @@ -1466,6 +1499,7 @@ protected: LazyBool m_overwrite_lazy = eLazyBoolCalculate; ScriptedCommandSynchronicity m_synchronicity = eScriptedCommandSynchronicitySynchronous; + CompletionType m_completion_type = eNoCompletion; }; void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { @@ -1496,7 +1530,7 @@ protected: CommandObjectSP command_obj_sp(new CommandObjectPythonFunction( m_interpreter, m_cmd_name, funct_name_str, m_short_help, - m_synchronicity)); + m_synchronicity, m_completion_type)); if (!m_container) { Status error = m_interpreter.AddUserCommand( m_cmd_name, command_obj_sp, m_overwrite); @@ -1577,6 +1611,7 @@ protected: m_short_help.assign(m_options.m_short_help); m_synchronicity = m_options.m_synchronicity; + m_completion_type = m_options.m_completion_type; // Handle the case where we prompt for the script code first: if (m_options.m_class_name.empty() && m_options.m_funct_name.empty()) { @@ -1589,7 +1624,7 @@ protected: if (m_options.m_class_name.empty()) { new_cmd_sp.reset(new CommandObjectPythonFunction( m_interpreter, m_cmd_name, m_options.m_funct_name, - m_options.m_short_help, m_synchronicity)); + m_options.m_short_help, m_synchronicity, m_completion_type)); } else { ScriptInterpreter *interpreter = GetDebugger().GetScriptInterpreter(); if (!interpreter) { @@ -1600,12 +1635,14 @@ protected: auto cmd_obj_sp = interpreter->CreateScriptCommandObject( m_options.m_class_name.c_str()); if (!cmd_obj_sp) { - result.AppendError("cannot create helper object"); + result.AppendErrorWithFormatv("cannot create helper object for: " + "'{0}'", m_options.m_class_name); return false; } new_cmd_sp.reset(new CommandObjectScriptingObject( - m_interpreter, m_cmd_name, cmd_obj_sp, m_synchronicity)); + m_interpreter, m_cmd_name, cmd_obj_sp, m_synchronicity, + m_completion_type)); } // Assume we're going to succeed... @@ -1633,6 +1670,7 @@ protected: bool m_overwrite = false; ScriptedCommandSynchronicity m_synchronicity = eScriptedCommandSynchronicitySynchronous; + CompletionType m_completion_type = eNoCompletion; }; // CommandObjectCommandsScriptList @@ -1705,8 +1743,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::CompleteModifiableCmdPathArgs(m_interpreter, request, - opt_element_vector); + lldb_private::CommandCompletions::CompleteModifiableCmdPathArgs( + m_interpreter, request, opt_element_vector); } protected: @@ -1856,8 +1894,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::CompleteModifiableCmdPathArgs(m_interpreter, request, - opt_element_vector); + lldb_private::CommandCompletions::CompleteModifiableCmdPathArgs( + m_interpreter, request, opt_element_vector); } protected: @@ -1996,8 +2034,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::CompleteModifiableCmdPathArgs(m_interpreter, request, - opt_element_vector); + lldb_private::CommandCompletions::CompleteModifiableCmdPathArgs( + m_interpreter, request, opt_element_vector); } protected: diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectDWIMPrint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectDWIMPrint.cpp index e15e723de588..b2b7f201a5ad 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectDWIMPrint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectDWIMPrint.cpp @@ -9,13 +9,21 @@ #include "CommandObjectDWIMPrint.h" #include "lldb/Core/ValueObject.h" +#include "lldb/DataFormatters/DumpValueObjectOptions.h" +#include "lldb/Expression/ExpressionVariable.h" +#include "lldb/Expression/UserExpression.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionGroupFormat.h" +#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" #include "lldb/Target/StackFrame.h" #include "lldb/Utility/ConstString.h" +#include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/FormatVariadic.h" using namespace llvm; using namespace lldb; @@ -26,12 +34,33 @@ CommandObjectDWIMPrint::CommandObjectDWIMPrint(CommandInterpreter &interpreter) "Print a variable or expression.", "dwim-print [<variable-name> | <expression>]", eCommandProcessMustBePaused | eCommandTryTargetAPILock) { + + CommandArgumentData var_name_arg(eArgTypeVarName, eArgRepeatPlain); + m_arguments.push_back({var_name_arg}); + + m_option_group.Append(&m_format_options, + OptionGroupFormat::OPTION_GROUP_FORMAT | + OptionGroupFormat::OPTION_GROUP_GDB_FMT, + LLDB_OPT_SET_1); + StringRef exclude_expr_options[] = {"debug", "top-level"}; + m_option_group.Append(&m_expr_options, exclude_expr_options); + m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Finalize(); +} + +Options *CommandObjectDWIMPrint::GetOptions() { return &m_option_group; } + +void CommandObjectDWIMPrint::HandleArgumentCompletion( + CompletionRequest &request, OptionElementVector &opt_element_vector) { + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eVariablePathCompletion, request, nullptr); } -bool CommandObjectDWIMPrint::DoExecute(StringRef expr, +bool CommandObjectDWIMPrint::DoExecute(StringRef command, CommandReturnObject &result) { - // Ignore leading and trailing whitespace. - expr = expr.trim(); + m_option_group.NotifyOptionParsingStarting(&m_exe_ctx); + OptionsWithRaw args{command}; + StringRef expr = args.GetRawPart(); if (expr.empty()) { result.AppendErrorWithFormatv("'{0}' takes a variable or expression", @@ -39,15 +68,53 @@ bool CommandObjectDWIMPrint::DoExecute(StringRef expr, return false; } + if (args.HasArgs()) { + if (!ParseOptionsAndNotify(args.GetArgs(), result, m_option_group, + m_exe_ctx)) + return false; + } + + // If the user has not specified, default to disabling persistent results. + if (m_expr_options.suppress_persistent_result == eLazyBoolCalculate) + m_expr_options.suppress_persistent_result = eLazyBoolYes; + bool suppress_result = m_expr_options.ShouldSuppressResult(m_varobj_options); + auto verbosity = GetDebugger().GetDWIMPrintVerbosity(); + Target *target_ptr = m_exe_ctx.GetTargetPtr(); + // Fallback to the dummy target, which can allow for expression evaluation. + Target &target = target_ptr ? *target_ptr : GetDummyTarget(); + + EvaluateExpressionOptions eval_options = + m_expr_options.GetEvaluateExpressionOptions(target, m_varobj_options); + // This command manually removes the result variable, make sure expression + // evaluation doesn't do it first. + eval_options.SetSuppressPersistentResult(false); + + DumpValueObjectOptions dump_options = m_varobj_options.GetAsDumpOptions( + m_expr_options.m_verbosity, m_format_options.GetFormat()); + dump_options.SetHideRootName(suppress_result); + + StackFrame *frame = m_exe_ctx.GetFramePtr(); + // First, try `expr` as the name of a frame variable. - if (StackFrame *frame = m_exe_ctx.GetFramePtr()) { + if (frame) { auto valobj_sp = frame->FindVariable(ConstString(expr)); if (valobj_sp && valobj_sp->GetError().Success()) { - if (verbosity == eDWIMPrintVerbosityFull) - result.AppendMessageWithFormatv("note: ran `frame variable {0}`", expr); - valobj_sp->Dump(result.GetOutputStream()); + if (!suppress_result) { + if (auto persisted_valobj = valobj_sp->Persist()) + valobj_sp = persisted_valobj; + } + + if (verbosity == eDWIMPrintVerbosityFull) { + StringRef flags; + if (args.HasArgs()) + flags = args.GetArgString(); + result.AppendMessageWithFormatv("note: ran `frame variable {0}{1}`", + flags, expr); + } + + valobj_sp->Dump(result.GetOutputStream(), dump_options); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -55,17 +122,31 @@ bool CommandObjectDWIMPrint::DoExecute(StringRef expr, // Second, also lastly, try `expr` as a source expression to evaluate. { - Target *target_ptr = m_exe_ctx.GetTargetPtr(); - // Fallback to the dummy target, which can allow for expression evaluation. - Target &target = target_ptr ? *target_ptr : GetDummyTarget(); - auto *exe_scope = m_exe_ctx.GetBestExecutionContextScope(); ValueObjectSP valobj_sp; - if (target.EvaluateExpression(expr, exe_scope, valobj_sp) == - eExpressionCompleted) { - if (verbosity != eDWIMPrintVerbosityNone) - result.AppendMessageWithFormatv("note: ran `expression -- {0}`", expr); - valobj_sp->Dump(result.GetOutputStream()); + ExpressionResults expr_result = + target.EvaluateExpression(expr, exe_scope, valobj_sp, eval_options); + if (expr_result == eExpressionCompleted) { + if (verbosity != eDWIMPrintVerbosityNone) { + StringRef flags; + if (args.HasArgs()) + flags = args.GetArgStringWithDelimiter(); + result.AppendMessageWithFormatv("note: ran `expression {0}{1}`", flags, + expr); + } + + if (valobj_sp->GetError().GetError() != UserExpression::kNoResult) + valobj_sp->Dump(result.GetOutputStream(), dump_options); + + if (suppress_result) + if (auto result_var_sp = + target.GetPersistentVariable(valobj_sp->GetName())) { + auto language = valobj_sp->GetPreferredDisplayLanguage(); + if (auto *persistent_state = + target.GetPersistentExpressionStateForLanguage(language)) + persistent_state->RemovePersistentVariable(result_var_sp); + } + result.SetStatus(eReturnStatusSuccessFinishResult); return true; } else { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectDWIMPrint.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectDWIMPrint.h index 1284949aed3a..3fc6c01d4729 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectDWIMPrint.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectDWIMPrint.h @@ -9,7 +9,11 @@ #ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTDWIMPRINT_H #define LLDB_SOURCE_COMMANDS_COMMANDOBJECTDWIMPRINT_H +#include "CommandObjectExpression.h" #include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/OptionGroupFormat.h" +#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" +#include "lldb/Interpreter/OptionValueFormat.h" namespace lldb_private { @@ -31,8 +35,21 @@ public: ~CommandObjectDWIMPrint() override = default; + Options *GetOptions() override; + + bool WantsCompletion() override { return true; } + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override; + private: bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override; + + OptionGroupOptions m_option_group; + OptionGroupFormat m_format_options = lldb::eFormatDefault; + OptionGroupValueObjectDisplay m_varobj_options; + CommandObjectExpression::CommandOptions m_expr_options; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp index 9cce009f853e..e7e6e3820b99 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.cpp @@ -10,6 +10,7 @@ #include "CommandObjectExpression.h" #include "lldb/Core/Debugger.h" +#include "lldb/Expression/ExpressionVariable.h" #include "lldb/Expression/REPL.h" #include "lldb/Expression/UserExpression.h" #include "lldb/Host/OptionParser.h" @@ -21,6 +22,8 @@ #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -145,6 +148,19 @@ Status CommandObjectExpression::CommandOptions::SetOptionValue( break; } + case '\x01': { + bool success; + bool persist_result = + OptionArgParser::ToBoolean(option_arg, true, &success); + if (success) + suppress_persistent_result = !persist_result ? eLazyBoolYes : eLazyBoolNo; + else + error.SetErrorStringWithFormat( + "could not convert \"%s\" to a boolean value.", + option_arg.str().c_str()); + break; + } + default: llvm_unreachable("Unimplemented option"); } @@ -173,6 +189,7 @@ void CommandObjectExpression::CommandOptions::OptionParsingStarting( auto_apply_fixits = eLazyBoolCalculate; top_level = false; allow_jit = true; + suppress_persistent_result = eLazyBoolCalculate; } llvm::ArrayRef<OptionDefinition> @@ -180,6 +197,57 @@ CommandObjectExpression::CommandOptions::GetDefinitions() { return llvm::ArrayRef(g_expression_options); } +EvaluateExpressionOptions +CommandObjectExpression::CommandOptions::GetEvaluateExpressionOptions( + const Target &target, const OptionGroupValueObjectDisplay &display_opts) { + EvaluateExpressionOptions options; + options.SetCoerceToId(display_opts.use_objc); + options.SetUnwindOnError(unwind_on_error); + options.SetIgnoreBreakpoints(ignore_breakpoints); + options.SetKeepInMemory(true); + options.SetUseDynamic(display_opts.use_dynamic); + options.SetTryAllThreads(try_all_threads); + options.SetDebug(debug); + options.SetLanguage(language); + options.SetExecutionPolicy( + allow_jit ? EvaluateExpressionOptions::default_execution_policy + : lldb_private::eExecutionPolicyNever); + + bool auto_apply_fixits; + if (this->auto_apply_fixits == eLazyBoolCalculate) + auto_apply_fixits = target.GetEnableAutoApplyFixIts(); + else + auto_apply_fixits = this->auto_apply_fixits == eLazyBoolYes; + + options.SetAutoApplyFixIts(auto_apply_fixits); + options.SetRetriesWithFixIts(target.GetNumberOfRetriesWithFixits()); + + if (top_level) + options.SetExecutionPolicy(eExecutionPolicyTopLevel); + + // If there is any chance we are going to stop and want to see what went + // wrong with our expression, we should generate debug info + if (!ignore_breakpoints || !unwind_on_error) + options.SetGenerateDebugInfo(true); + + if (timeout > 0) + options.SetTimeout(std::chrono::microseconds(timeout)); + else + options.SetTimeout(std::nullopt); + return options; +} + +bool CommandObjectExpression::CommandOptions::ShouldSuppressResult( + const OptionGroupValueObjectDisplay &display_opts) const { + // Explicitly disabling persistent results takes precedence over the + // m_verbosity/use_objc logic. + if (suppress_persistent_result != eLazyBoolCalculate) + return suppress_persistent_result == eLazyBoolYes; + + return display_opts.use_objc && + m_verbosity == eLanguageRuntimeDescriptionDisplayVerbosityCompact; +} + CommandObjectExpression::CommandObjectExpression( CommandInterpreter &interpreter) : CommandObjectRaw(interpreter, "expression", @@ -342,47 +410,6 @@ CanBeUsedForElementCountPrinting(ValueObject &valobj) { return Status(); } -EvaluateExpressionOptions -CommandObjectExpression::GetEvalOptions(const Target &target) { - EvaluateExpressionOptions options; - options.SetCoerceToId(m_varobj_options.use_objc); - options.SetUnwindOnError(m_command_options.unwind_on_error); - options.SetIgnoreBreakpoints(m_command_options.ignore_breakpoints); - options.SetKeepInMemory(true); - options.SetUseDynamic(m_varobj_options.use_dynamic); - options.SetTryAllThreads(m_command_options.try_all_threads); - options.SetDebug(m_command_options.debug); - options.SetLanguage(m_command_options.language); - options.SetExecutionPolicy( - m_command_options.allow_jit - ? EvaluateExpressionOptions::default_execution_policy - : lldb_private::eExecutionPolicyNever); - - bool auto_apply_fixits; - if (m_command_options.auto_apply_fixits == eLazyBoolCalculate) - auto_apply_fixits = target.GetEnableAutoApplyFixIts(); - else - auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes; - - options.SetAutoApplyFixIts(auto_apply_fixits); - options.SetRetriesWithFixIts(target.GetNumberOfRetriesWithFixits()); - - if (m_command_options.top_level) - options.SetExecutionPolicy(eExecutionPolicyTopLevel); - - // If there is any chance we are going to stop and want to see what went - // wrong with our expression, we should generate debug info - if (!m_command_options.ignore_breakpoints || - !m_command_options.unwind_on_error) - options.SetGenerateDebugInfo(true); - - if (m_command_options.timeout > 0) - options.SetTimeout(std::chrono::microseconds(m_command_options.timeout)); - else - options.SetTimeout(std::nullopt); - return options; -} - bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, Stream &output_stream, Stream &error_stream, @@ -403,9 +430,14 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, return false; } - const EvaluateExpressionOptions options = GetEvalOptions(target); + EvaluateExpressionOptions eval_options = + m_command_options.GetEvaluateExpressionOptions(target, m_varobj_options); + // This command manually removes the result variable, make sure expression + // evaluation doesn't do it first. + eval_options.SetSuppressPersistentResult(false); + ExpressionResults success = target.EvaluateExpression( - expr, frame, result_valobj_sp, options, &m_fixed_expression); + expr, frame, result_valobj_sp, eval_options, &m_fixed_expression); // We only tell you about the FixIt if we applied it. The compiler errors // will suggest the FixIt if it parsed. @@ -432,13 +464,25 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, } } + bool suppress_result = + m_command_options.ShouldSuppressResult(m_varobj_options); + DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions( m_command_options.m_verbosity, format)); + options.SetHideRootName(suppress_result); options.SetVariableFormatDisplayLanguage( result_valobj_sp->GetPreferredDisplayLanguage()); result_valobj_sp->Dump(output_stream, options); + if (suppress_result) + if (auto result_var_sp = + target.GetPersistentVariable(result_valobj_sp->GetName())) { + auto language = result_valobj_sp->GetPreferredDisplayLanguage(); + if (auto *persistent_state = + target.GetPersistentExpressionStateForLanguage(language)) + persistent_state->RemovePersistentVariable(result_var_sp); + } result.SetStatus(eReturnStatusSuccessFinishResult); } } else { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.h index 1e59cbc14528..b2b8fc73a1ee 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectExpression.h @@ -35,6 +35,15 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override; + /// Return the appropriate expression options used for evaluating the + /// expression in the given target. + EvaluateExpressionOptions GetEvaluateExpressionOptions( + const Target &target, + const OptionGroupValueObjectDisplay &display_opts); + + bool ShouldSuppressResult( + const OptionGroupValueObjectDisplay &display_opts) const; + bool top_level; bool unwind_on_error; bool ignore_breakpoints; @@ -47,6 +56,7 @@ public: lldb::LanguageType language; LanguageRuntimeDescriptionDisplayVerbosity m_verbosity; LazyBool auto_apply_fixits; + LazyBool suppress_persistent_result; }; CommandObjectExpression(CommandInterpreter &interpreter); @@ -67,10 +77,6 @@ protected: bool DoExecute(llvm::StringRef command, CommandReturnObject &result) override; - /// Return the appropriate expression options used for evaluating the - /// expression in the given target. - EvaluateExpressionOptions GetEvalOptions(const Target &target); - /// Evaluates the given expression. /// \param output_stream The stream to which the evaluation result will be /// printed. diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp index 4a0d75202797..1390fd8748df 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectFrame.cpp @@ -135,7 +135,7 @@ public: protected: bool DoExecute(Args &command, CommandReturnObject &result) override { Thread *thread = m_exe_ctx.GetThreadPtr(); - StackFrameSP frame_sp = thread->GetSelectedFrame(); + StackFrameSP frame_sp = thread->GetSelectedFrame(SelectMostRelevantFrame); ValueObjectSP valobj_sp; @@ -292,9 +292,8 @@ public: if (request.GetCursorIndex() != 0) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eFrameIndexCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eFrameIndexCompletion, request, nullptr); } Options *GetOptions() override { return &m_options; } @@ -308,7 +307,7 @@ protected: uint32_t frame_idx = UINT32_MAX; if (m_options.relative_frame_offset) { // The one and only argument is a signed relative frame index - frame_idx = thread->GetSelectedFrameIndex(); + frame_idx = thread->GetSelectedFrameIndex(SelectMostRelevantFrame); if (frame_idx == UINT32_MAX) frame_idx = 0; @@ -327,21 +326,29 @@ protected: } } else if (*m_options.relative_frame_offset > 0) { // I don't want "up 20" where "20" takes you past the top of the stack - // to produce - // an error, but rather to just go to the top. So I have to count the - // stack here... - const uint32_t num_frames = thread->GetStackFrameCount(); - if (static_cast<int32_t>(num_frames - frame_idx) > - *m_options.relative_frame_offset) - frame_idx += *m_options.relative_frame_offset; + // to produce an error, but rather to just go to the top. OTOH, start + // by seeing if the requested frame exists, in which case we can avoid + // counting the stack here... + const uint32_t frame_requested = frame_idx + + *m_options.relative_frame_offset; + StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_requested); + if (frame_sp) + frame_idx = frame_requested; else { - if (frame_idx == num_frames - 1) { - // If we are already at the top of the stack, just warn and don't - // reset the frame. - result.AppendError("Already at the top of the stack."); - return false; - } else - frame_idx = num_frames - 1; + // The request went past the stack, so handle that case: + const uint32_t num_frames = thread->GetStackFrameCount(); + if (static_cast<int32_t>(num_frames - frame_idx) > + *m_options.relative_frame_offset) + frame_idx += *m_options.relative_frame_offset; + else { + if (frame_idx == num_frames - 1) { + // If we are already at the top of the stack, just warn and don't + // reset the frame. + result.AppendError("Already at the top of the stack."); + return false; + } else + frame_idx = num_frames - 1; + } } } } else { @@ -362,7 +369,7 @@ protected: return false; } } else if (command.GetArgumentCount() == 0) { - frame_idx = thread->GetSelectedFrameIndex(); + frame_idx = thread->GetSelectedFrameIndex(SelectMostRelevantFrame); if (frame_idx == UINT32_MAX) { frame_idx = 0; } @@ -372,7 +379,7 @@ protected: bool success = thread->SetSelectedFrameByIndexNoisily( frame_idx, result.GetOutputStream()); if (success) { - m_exe_ctx.SetFrameSP(thread->GetSelectedFrame()); + m_exe_ctx.SetFrameSP(thread->GetSelectedFrame(SelectMostRelevantFrame)); result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendErrorWithFormat("Frame index (%u) out of range.\n", @@ -445,9 +452,9 @@ may even involve JITing and running code in the target program.)"); HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { // Arguments are the standard source file completer. - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eVariablePathCompletion, request, + nullptr); } protected: @@ -473,6 +480,50 @@ protected: return llvm::StringRef(); } + /// Returns true if `scope` matches any of the options in `m_option_variable`. + bool ScopeRequested(lldb::ValueType scope) { + switch (scope) { + case eValueTypeVariableGlobal: + case eValueTypeVariableStatic: + return m_option_variable.show_globals; + case eValueTypeVariableArgument: + return m_option_variable.show_args; + case eValueTypeVariableLocal: + return m_option_variable.show_locals; + case eValueTypeInvalid: + case eValueTypeRegister: + case eValueTypeRegisterSet: + case eValueTypeConstResult: + case eValueTypeVariableThreadLocal: + return false; + } + } + + /// Finds all the variables in `all_variables` whose name matches `regex`, + /// inserting them into `matches`. Variables already contained in `matches` + /// are not inserted again. + /// Nullopt is returned in case of no matches. + /// A sub-range of `matches` with all newly inserted variables is returned. + /// This may be empty if all matches were already contained in `matches`. + std::optional<llvm::ArrayRef<VariableSP>> + findUniqueRegexMatches(RegularExpression ®ex, + VariableList &matches, + const VariableList &all_variables) { + bool any_matches = false; + const size_t previous_num_vars = matches.GetSize(); + + for (const VariableSP &var : all_variables) { + if (!var->NameMatches(regex) || !ScopeRequested(var->GetScope())) + continue; + any_matches = true; + matches.AddVariableIfUnique(var); + } + + if (any_matches) + return matches.toArrayRef().drop_front(previous_num_vars); + return std::nullopt; + } + bool DoExecute(Args &command, CommandReturnObject &result) override { // No need to check "frame" for validity as eCommandRequiresFrame ensures // it is valid @@ -480,6 +531,10 @@ protected: Stream &s = result.GetOutputStream(); + // Using a regex should behave like looking for an exact name match: it + // also finds globals. + m_option_variable.show_globals |= m_option_variable.use_regex; + // Be careful about the stack frame, if any summary formatter runs code, it // might clear the StackFrameList for the thread. So hold onto a shared // pointer to the frame so it stays alive. @@ -492,7 +547,6 @@ protected: result.AppendError(error.AsCString()); } - VariableSP var_sp; ValueObjectSP valobj_sp; TypeSummaryImplSP summary_format_sp; @@ -525,46 +579,38 @@ protected: // objects from them... for (auto &entry : command) { if (m_option_variable.use_regex) { - const size_t regex_start_index = regex_var_list.GetSize(); llvm::StringRef name_str = entry.ref(); RegularExpression regex(name_str); if (regex.IsValid()) { - size_t num_matches = 0; - const size_t num_new_regex_vars = - variable_list->AppendVariablesIfUnique(regex, regex_var_list, - num_matches); - if (num_new_regex_vars > 0) { - for (size_t regex_idx = regex_start_index, - end_index = regex_var_list.GetSize(); - regex_idx < end_index; ++regex_idx) { - var_sp = regex_var_list.GetVariableAtIndex(regex_idx); - if (var_sp) { - valobj_sp = frame->GetValueObjectForFrameVariable( - var_sp, m_varobj_options.use_dynamic); - if (valobj_sp) { - std::string scope_string; - if (m_option_variable.show_scope) - scope_string = GetScopeString(var_sp).str(); - - if (!scope_string.empty()) - s.PutCString(scope_string); - - if (m_option_variable.show_decl && - var_sp->GetDeclaration().GetFile()) { - bool show_fullpaths = false; - bool show_module = true; - if (var_sp->DumpDeclaration(&s, show_fullpaths, - show_module)) - s.PutCString(": "); - } - valobj_sp->Dump(result.GetOutputStream(), options); - } - } - } - } else if (num_matches == 0) { + std::optional<llvm::ArrayRef<VariableSP>> results = + findUniqueRegexMatches(regex, regex_var_list, *variable_list); + if (!results) { result.AppendErrorWithFormat( "no variables matched the regular expression '%s'.", entry.c_str()); + continue; + } + for (const VariableSP &var_sp : *results) { + valobj_sp = frame->GetValueObjectForFrameVariable( + var_sp, m_varobj_options.use_dynamic); + if (valobj_sp) { + std::string scope_string; + if (m_option_variable.show_scope) + scope_string = GetScopeString(var_sp).str(); + + if (!scope_string.empty()) + s.PutCString(scope_string); + + if (m_option_variable.show_decl && + var_sp->GetDeclaration().GetFile()) { + bool show_fullpaths = false; + bool show_module = true; + if (var_sp->DumpDeclaration(&s, show_fullpaths, + show_module)) + s.PutCString(": "); + } + valobj_sp->Dump(result.GetOutputStream(), options); + } } } else { if (llvm::Error err = regex.GetError()) @@ -622,28 +668,9 @@ protected: const size_t num_variables = variable_list->GetSize(); if (num_variables > 0) { for (size_t i = 0; i < num_variables; i++) { - var_sp = variable_list->GetVariableAtIndex(i); - switch (var_sp->GetScope()) { - case eValueTypeVariableGlobal: - if (!m_option_variable.show_globals) - continue; - break; - case eValueTypeVariableStatic: - if (!m_option_variable.show_globals) + VariableSP var_sp = variable_list->GetVariableAtIndex(i); + if (!ScopeRequested(var_sp->GetScope())) continue; - break; - case eValueTypeVariableArgument: - if (!m_option_variable.show_args) - continue; - break; - case eValueTypeVariableLocal: - if (!m_option_variable.show_locals) - continue; - break; - default: - continue; - break; - } std::string scope_string; if (m_option_variable.show_scope) scope_string = GetScopeString(var_sp).str(); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp index c63d8ce4f9e4..5dd6f8989837 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectLog.cpp @@ -177,6 +177,20 @@ protected: return false; } + if ((m_options.handler != eLogHandlerCircular && + m_options.handler != eLogHandlerStream) && + m_options.buffer_size.GetCurrentValue() != 0) { + result.AppendError("a buffer size can only be specified for the circular " + "and stream buffer handler.\n"); + return false; + } + + if (m_options.handler != eLogHandlerStream && m_options.log_file) { + result.AppendError( + "a file name can only be specified for the stream handler.\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 @@ -490,7 +504,7 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { - Timer::DumpCategoryTimes(&result.GetOutputStream()); + Timer::DumpCategoryTimes(result.GetOutputStream()); Timer::SetDisplayDepth(0); result.SetStatus(eReturnStatusSuccessFinishResult); @@ -513,7 +527,7 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { - Timer::DumpCategoryTimes(&result.GetOutputStream()); + Timer::DumpCategoryTimes(result.GetOutputStream()); result.SetStatus(eReturnStatusSuccessFinishResult); if (!result.Succeeded()) { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp index 6606f4564dc8..ba5aad3d4ad5 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp @@ -594,18 +594,9 @@ protected: return false; } - ABISP abi; - if (Process *proc = m_exe_ctx.GetProcessPtr()) - abi = proc->GetABI(); - - if (abi) - addr = abi->FixDataAddress(addr); - if (argc == 2) { lldb::addr_t end_addr = OptionArgParser::ToAddress( &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, nullptr); - if (end_addr != LLDB_INVALID_ADDRESS && abi) - end_addr = abi->FixDataAddress(end_addr); if (end_addr == LLDB_INVALID_ADDRESS) { result.AppendError("invalid end address expression."); @@ -1045,12 +1036,6 @@ protected: return false; } - ABISP abi = m_exe_ctx.GetProcessPtr()->GetABI(); - if (abi) { - low_addr = abi->FixDataAddress(low_addr); - high_addr = abi->FixDataAddress(high_addr); - } - if (high_addr <= low_addr) { result.AppendError( "starting address must be smaller than ending address"); @@ -1062,7 +1047,8 @@ protected: DataBufferHeap buffer; if (m_memory_options.m_string.OptionWasSet()) { - llvm::StringRef str = m_memory_options.m_string.GetStringValue(); + llvm::StringRef str = + m_memory_options.m_string.GetValueAs<llvm::StringRef>().value_or(""); if (str.empty()) { result.AppendError("search string must have non-zero length."); return false; @@ -1073,7 +1059,9 @@ protected: ValueObjectSP result_sp; if ((eExpressionCompleted == process->GetTarget().EvaluateExpression( - m_memory_options.m_expr.GetStringValue(), frame, result_sp)) && + m_memory_options.m_expr.GetValueAs<llvm::StringRef>().value_or( + ""), + frame, result_sp)) && result_sp) { uint64_t value = result_sp->GetValueAsUnsigned(0); std::optional<uint64_t> size = @@ -1783,7 +1771,6 @@ protected: } 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, LLDB_INVALID_ADDRESS, &error); if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp index fd0fd2919c95..b436a185cd14 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMemoryTag.cpp @@ -51,7 +51,7 @@ protected: } Status error; - addr_t start_addr = OptionArgParser::ToAddress( + addr_t start_addr = OptionArgParser::ToRawAddress( &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error); if (start_addr == LLDB_INVALID_ADDRESS) { result.AppendErrorWithFormatv("Invalid address expression, {0}", @@ -63,8 +63,8 @@ protected: addr_t end_addr = start_addr + 1; if (command.GetArgumentCount() > 1) { - end_addr = OptionArgParser::ToAddress(&m_exe_ctx, command[1].ref(), - LLDB_INVALID_ADDRESS, &error); + end_addr = OptionArgParser::ToRawAddress(&m_exe_ctx, command[1].ref(), + LLDB_INVALID_ADDRESS, &error); if (end_addr == LLDB_INVALID_ADDRESS) { result.AppendErrorWithFormatv("Invalid end address expression, {0}", error.AsCString()); @@ -155,8 +155,8 @@ public: switch (short_option) { case 'e': - m_end_addr = OptionArgParser::ToAddress(execution_context, option_value, - LLDB_INVALID_ADDRESS, &status); + m_end_addr = OptionArgParser::ToRawAddress( + execution_context, option_value, LLDB_INVALID_ADDRESS, &status); break; default: llvm_unreachable("Unimplemented option"); @@ -203,7 +203,7 @@ protected: } Status error; - addr_t start_addr = OptionArgParser::ToAddress( + addr_t start_addr = OptionArgParser::ToRawAddress( &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error); if (start_addr == LLDB_INVALID_ADDRESS) { result.AppendErrorWithFormatv("Invalid address expression, {0}", diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp index bae2717ffe68..7ef829afaab6 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectMultiword.cpp @@ -274,10 +274,10 @@ void CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { StringList new_matches; CommandObject *sub_command_object = GetSubcommandObject(arg0, &new_matches); - if (sub_command_object == nullptr) { - request.AddCompletions(new_matches); + + // The subcommand is ambiguous. The completion isn't meaningful. + if (!sub_command_object) return; - } // Remove the one match that we got from calling GetSubcommandObject. new_matches.DeleteStringAtIndex(0); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp index 1ab218fa6fb2..54115b51be78 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlatform.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "CommandObjectPlatform.h" +#include "CommandOptionsProcessAttach.h" #include "CommandOptionsProcessLaunch.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -18,10 +19,13 @@ #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupFile.h" #include "lldb/Interpreter/OptionGroupPlatform.h" +#include "lldb/Interpreter/OptionGroupPythonClassWithDict.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/ScriptedMetadata.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/SmallString.h" @@ -158,8 +162,8 @@ public: ~CommandObjectPlatformSelect() override = default; void HandleCompletion(CompletionRequest &request) override { - CommandCompletions::PlatformPluginNames(GetCommandInterpreter(), request, - nullptr); + lldb_private::CommandCompletions::PlatformPluginNames( + GetCommandInterpreter(), request, nullptr); } Options *GetOptions() override { return &m_option_group; } @@ -382,8 +386,7 @@ public: "Set settings for the current target's platform.", "platform settings", 0), m_option_working_dir(LLDB_OPT_SET_1, false, "working-dir", 'w', - CommandCompletions::eRemoteDiskDirectoryCompletion, - eArgTypePath, + lldb::eRemoteDiskDirectoryCompletion, eArgTypePath, "The working directory for the platform.") { m_options.Append(&m_option_working_dir, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); } @@ -481,9 +484,9 @@ public: HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex() == 0) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), - CommandCompletions::eRemoteDiskFileCompletion, request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, + nullptr); } bool DoExecute(Args &args, CommandReturnObject &result) override { @@ -828,13 +831,12 @@ public: HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex() == 0) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), - CommandCompletions::eRemoteDiskFileCompletion, request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, + nullptr); else if (request.GetCursorIndex() == 1) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } bool DoExecute(Args &args, CommandReturnObject &result) override { @@ -904,9 +906,9 @@ public: if (request.GetCursorIndex() != 0) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, + nullptr); } bool DoExecute(Args &args, CommandReturnObject &result) override { @@ -975,9 +977,9 @@ public: if (request.GetCursorIndex() != 0) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, + nullptr); } bool DoExecute(Args &args, CommandReturnObject &result) override { @@ -1045,9 +1047,9 @@ public: if (request.GetCursorIndex() != 0) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eRemoteDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, + nullptr); } bool DoExecute(Args &args, CommandReturnObject &result) override { @@ -1104,13 +1106,12 @@ public: HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex() == 0) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); else if (request.GetCursorIndex() == 1) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), - CommandCompletions::eRemoteDiskFileCompletion, request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRemoteDiskFileCompletion, request, + nullptr); } bool DoExecute(Args &args, CommandReturnObject &result) override { @@ -1144,8 +1145,11 @@ public: : CommandObjectParsed(interpreter, "platform process launch", "Launch a new process on a remote platform.", "platform process launch program", - eCommandRequiresTarget | eCommandTryTargetAPILock) { + eCommandRequiresTarget | eCommandTryTargetAPILock), + m_class_options("scripted process", true, 'C', 'k', 'v', 0) { m_all_options.Append(&m_options); + m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2, + LLDB_OPT_SET_ALL); m_all_options.Finalize(); CommandArgumentData run_arg_arg{eArgTypeRunArgs, eArgRepeatStar}; m_arguments.push_back({run_arg_arg}); @@ -1180,6 +1184,14 @@ protected: m_options.launch_info.GetArchitecture() = exe_module->GetArchitecture(); } + if (!m_class_options.GetName().empty()) { + m_options.launch_info.SetProcessPluginName("ScriptedProcess"); + ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>( + m_class_options.GetName(), m_class_options.GetStructuredData()); + m_options.launch_info.SetScriptedMetadata(metadata_sp); + target->SetProcessLaunchInfo(m_options.launch_info); + } + if (argc > 0) { if (m_options.launch_info.GetExecutableFile()) { // We already have an executable file, so we will use this and all @@ -1196,20 +1208,72 @@ protected: if (m_options.launch_info.GetExecutableFile()) { Debugger &debugger = GetDebugger(); - if (argc == 0) - target->GetRunArguments(m_options.launch_info.GetArguments()); + if (argc == 0) { + // If no arguments were given to the command, use target.run-args. + Args target_run_args; + target->GetRunArguments(target_run_args); + m_options.launch_info.GetArguments().AppendArguments(target_run_args); + } ProcessSP process_sp(platform_sp->DebugProcess( m_options.launch_info, debugger, *target, error)); + + if (!process_sp && error.Success()) { + result.AppendError("failed to launch or debug process"); + return false; + } else if (!error.Success()) { + result.AppendError(error.AsCString()); + return false; + } + + const bool synchronous_execution = + debugger.GetCommandInterpreter().GetSynchronous(); + auto launch_info = m_options.launch_info; + bool rebroadcast_first_stop = + !synchronous_execution && + launch_info.GetFlags().Test(eLaunchFlagStopAtEntry); + + EventSP first_stop_event_sp; + StateType state = process_sp->WaitForProcessToStop( + std::nullopt, &first_stop_event_sp, rebroadcast_first_stop, + launch_info.GetHijackListener()); + process_sp->RestoreProcessEvents(); + + if (rebroadcast_first_stop) { + assert(first_stop_event_sp); + process_sp->BroadcastEvent(first_stop_event_sp); + return true; + } + + switch (state) { + case eStateStopped: { + if (launch_info.GetFlags().Test(eLaunchFlagStopAtEntry)) + break; + 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. + process_sp->ResumeSynchronous(&result.GetOutputStream()); + } else { + error = process_sp->Resume(); + if (!error.Success()) { + result.AppendErrorWithFormat( + "process resume at entry point failed: %s", + error.AsCString()); + } + } + } break; + default: + result.AppendErrorWithFormat( + "initial process state wasn't stopped: %s", + StateAsCString(state)); + break; + } + if (process_sp && process_sp->IsAlive()) { result.SetStatus(eReturnStatusSuccessFinishNoResult); return true; } - - if (error.Success()) - result.AppendError("process launch failed"); - else - result.AppendError(error.AsCString()); } else { result.AppendError("'platform process launch' uses the current target " "file and arguments, or the executable and its " @@ -1223,6 +1287,7 @@ protected: } CommandOptionsProcessLaunch m_options; + OptionGroupPythonClassWithDict m_class_options; OptionGroupOptions m_all_options; }; @@ -1508,9 +1573,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eProcessIDCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eProcessIDCompletion, request, nullptr); } protected: @@ -1572,71 +1636,16 @@ protected: class CommandObjectPlatformProcessAttach : public CommandObjectParsed { public: - class CommandOptions : public Options { - public: - CommandOptions() { - // Keep default values of all options in one place: OptionParsingStarting - // () - OptionParsingStarting(nullptr); - } - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *execution_context) override { - Status error; - char short_option = (char)m_getopt_table[option_idx].val; - switch (short_option) { - case 'p': { - lldb::pid_t pid = LLDB_INVALID_PROCESS_ID; - if (option_arg.getAsInteger(0, pid)) { - error.SetErrorStringWithFormat("invalid process ID '%s'", - option_arg.str().c_str()); - } else { - attach_info.SetProcessID(pid); - } - } break; - - case 'P': - attach_info.SetProcessPluginName(option_arg); - break; - - case 'n': - attach_info.GetExecutableFile().SetFile(option_arg, - FileSpec::Style::native); - break; - - case 'w': - attach_info.SetWaitForLaunch(true); - break; - - default: - llvm_unreachable("Unimplemented option"); - } - return error; - } - - void OptionParsingStarting(ExecutionContext *execution_context) override { - attach_info.Clear(); - } - - llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::ArrayRef(g_platform_process_attach_options); - } - - // Options table: Required for subclasses of Options. - - static OptionDefinition g_option_table[]; - - // Instance variables to hold the values for command options. - - ProcessAttachInfo attach_info; - }; - CommandObjectPlatformProcessAttach(CommandInterpreter &interpreter) : CommandObjectParsed(interpreter, "platform process attach", "Attach to a process.", - "platform process attach <cmd-options>") {} + "platform process attach <cmd-options>"), + m_class_options("scripted process", true, 'C', 'k', 'v', 0) { + m_all_options.Append(&m_options); + m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2, + LLDB_OPT_SET_ALL); + m_all_options.Finalize(); + } ~CommandObjectPlatformProcessAttach() override = default; @@ -1644,6 +1653,14 @@ public: PlatformSP platform_sp( GetDebugger().GetPlatformList().GetSelectedPlatform()); if (platform_sp) { + + if (!m_class_options.GetName().empty()) { + m_options.attach_info.SetProcessPluginName("ScriptedProcess"); + ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>( + m_class_options.GetName(), m_class_options.GetStructuredData()); + m_options.attach_info.SetScriptedMetadata(metadata_sp); + } + Status err; ProcessSP remote_process_sp = platform_sp->Attach( m_options.attach_info, GetDebugger(), nullptr, err); @@ -1659,10 +1676,12 @@ public: return result.Succeeded(); } - Options *GetOptions() override { return &m_options; } + Options *GetOptions() override { return &m_all_options; } protected: - CommandOptions m_options; + CommandOptionsProcessAttach m_options; + OptionGroupPythonClassWithDict m_class_options; + OptionGroupOptions m_all_options; }; class CommandObjectPlatformProcess : public CommandObjectMultiword { @@ -1864,9 +1883,8 @@ public: OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex()) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } bool DoExecute(Args &args, CommandReturnObject &result) override { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp index 881415a49472..8661ebb5022b 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectPlugin.cpp @@ -39,9 +39,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } protected: diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp index a45371f824b1..ab047ee926c9 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectProcess.cpp @@ -9,6 +9,7 @@ #include "CommandObjectProcess.h" #include "CommandObjectBreakpoint.h" #include "CommandObjectTrace.h" +#include "CommandOptionsProcessAttach.h" #include "CommandOptionsProcessLaunch.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointIDList.h" @@ -31,6 +32,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/ScriptedMetadata.h" #include "lldb/Utility/State.h" #include "llvm/ADT/ScopeExit.h" @@ -145,9 +147,8 @@ public: HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } Options *GetOptions() override { return &m_all_options; } @@ -199,10 +200,9 @@ protected: if (!m_class_options.GetName().empty()) { m_options.launch_info.SetProcessPluginName("ScriptedProcess"); - m_options.launch_info.SetScriptedProcessClassName( - m_class_options.GetName()); - m_options.launch_info.SetScriptedProcessDictionarySP( - m_class_options.GetStructuredData()); + ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>( + m_class_options.GetName(), m_class_options.GetStructuredData()); + m_options.launch_info.SetScriptedMetadata(metadata_sp); target->SetProcessLaunchInfo(m_options.launch_info); } @@ -304,77 +304,20 @@ protected: #pragma mark CommandObjectProcessAttach class CommandObjectProcessAttach : public CommandObjectProcessLaunchOrAttach { public: - class CommandOptions : public Options { - public: - CommandOptions() { - // Keep default values of all options in one place: OptionParsingStarting - // () - OptionParsingStarting(nullptr); - } - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *execution_context) override { - Status error; - const int short_option = m_getopt_table[option_idx].val; - switch (short_option) { - case 'c': - attach_info.SetContinueOnceAttached(true); - break; - - case 'p': { - lldb::pid_t pid; - if (option_arg.getAsInteger(0, pid)) { - error.SetErrorStringWithFormat("invalid process ID '%s'", - option_arg.str().c_str()); - } else { - attach_info.SetProcessID(pid); - } - } break; - - case 'P': - attach_info.SetProcessPluginName(option_arg); - break; - - case 'n': - attach_info.GetExecutableFile().SetFile(option_arg, - FileSpec::Style::native); - break; - - case 'w': - attach_info.SetWaitForLaunch(true); - break; - - case 'i': - attach_info.SetIgnoreExisting(false); - break; - - default: - llvm_unreachable("Unimplemented option"); - } - return error; - } - - void OptionParsingStarting(ExecutionContext *execution_context) override { - attach_info.Clear(); - } - - llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::ArrayRef(g_process_attach_options); - } - - ProcessAttachInfo attach_info; - }; - CommandObjectProcessAttach(CommandInterpreter &interpreter) : CommandObjectProcessLaunchOrAttach( interpreter, "process attach", "Attach to a process.", - "process attach <cmd-options>", 0, "attach") {} + "process attach <cmd-options>", 0, "attach"), + m_class_options("scripted process", true, 'C', 'k', 'v', 0) { + m_all_options.Append(&m_options); + m_all_options.Append(&m_class_options, LLDB_OPT_SET_1 | LLDB_OPT_SET_2, + LLDB_OPT_SET_ALL); + m_all_options.Finalize(); + } ~CommandObjectProcessAttach() override = default; - Options *GetOptions() override { return &m_options; } + Options *GetOptions() override { return &m_all_options; } protected: bool DoExecute(Args &command, CommandReturnObject &result) override { @@ -409,6 +352,13 @@ protected: } } + if (!m_class_options.GetName().empty()) { + m_options.attach_info.SetProcessPluginName("ScriptedProcess"); + ScriptedMetadataSP metadata_sp = std::make_shared<ScriptedMetadata>( + m_class_options.GetName(), m_class_options.GetStructuredData()); + m_options.attach_info.SetScriptedMetadata(metadata_sp); + } + // Record the old executable module, we want to issue a warning if the // process of attaching changed the current executable (like somebody said // "file foo" then attached to a PID whose executable was bar.) @@ -483,7 +433,9 @@ protected: return result.Succeeded(); } - CommandOptions m_options; + CommandOptionsProcessAttach m_options; + OptionGroupPythonClassWithDict m_class_options; + OptionGroupOptions m_all_options; }; // CommandObjectProcessContinue @@ -1073,9 +1025,8 @@ public: if (!m_exe_ctx.HasProcessScope()) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } Options *GetOptions() override { return &m_options; } @@ -1355,6 +1306,13 @@ public: Options *GetOptions() override { return &m_options; } + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); + } + class CommandOptions : public Options { public: CommandOptions() = default; @@ -1403,6 +1361,7 @@ protected: if (process_sp) { if (command.GetArgumentCount() == 1) { FileSpec output_file(command.GetArgumentAtIndex(0)); + FileSystem::Instance().Resolve(output_file); SaveCoreStyle corefile_style = m_options.m_requested_save_core_style; Status error = PluginManager::SaveCore(process_sp, output_file, corefile_style, diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp index 857193036e39..6ff1d281504a 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.cpp @@ -19,10 +19,9 @@ using namespace lldb_private; // CommandObjectRegexCommand constructor CommandObjectRegexCommand::CommandObjectRegexCommand( CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help, - llvm::StringRef syntax, uint32_t max_matches, uint32_t completion_type_mask, - bool is_removable) + llvm::StringRef syntax, uint32_t completion_type_mask, bool is_removable) : CommandObjectRaw(interpreter, name, help, syntax), - m_max_matches(max_matches), m_completion_type_mask(completion_type_mask), + m_completion_type_mask(completion_type_mask), m_is_removable(is_removable) {} // Destructor @@ -73,8 +72,9 @@ bool CommandObjectRegexCommand::DoExecute(llvm::StringRef command, 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); + bool force_repeat_command = true; + return m_interpreter.HandleCommand(new_command->c_str(), eLazyBoolNo, + result, force_repeat_command); } } result.SetStatus(eReturnStatusFailed); @@ -104,7 +104,7 @@ bool CommandObjectRegexCommand::AddRegexCommand(llvm::StringRef re_cstr, void CommandObjectRegexCommand::HandleCompletion(CompletionRequest &request) { if (m_completion_type_mask) { - CommandCompletions::InvokeCommonCompletionCallbacks( + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( GetCommandInterpreter(), m_completion_type_mask, request, nullptr); } } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h index b2a375c63a76..47d493a8fdd7 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegexCommand.h @@ -23,7 +23,7 @@ class CommandObjectRegexCommand : public CommandObjectRaw { public: CommandObjectRegexCommand(CommandInterpreter &interpreter, llvm::StringRef name, llvm::StringRef help, - llvm::StringRef syntax, uint32_t max_matches, + llvm::StringRef syntax, uint32_t completion_type_mask, bool is_removable); ~CommandObjectRegexCommand() override; @@ -50,7 +50,6 @@ protected: }; typedef std::list<Entry> EntryCollection; - const uint32_t m_max_matches; const uint32_t m_completion_type_mask; EntryCollection m_entries; bool m_is_removable; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp index c61a1f6e865a..a0e88f6ab4ba 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectRegister.cpp @@ -8,8 +8,10 @@ #include "CommandObjectRegister.h" #include "lldb/Core/Debugger.h" +#include "lldb/Core/DumpRegisterInfo.h" #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Host/OptionParser.h" +#include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandOptionArgumentTable.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupFormat.h" @@ -44,7 +46,10 @@ public: nullptr, eCommandRequiresFrame | eCommandRequiresRegContext | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused), - m_format_options(eFormatDefault) { + m_format_options(eFormatDefault, UINT64_MAX, UINT64_MAX, + {{CommandArgumentType::eArgTypeFormat, + "Specify a format to be used for display. If this " + "is set, register fields will not be displayed."}}) { CommandArgumentEntry arg; CommandArgumentData register_arg; @@ -76,48 +81,45 @@ public: if (!m_exe_ctx.HasProcessScope()) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eRegisterCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRegisterCompletion, request, nullptr); } Options *GetOptions() override { return &m_option_group; } bool DumpRegister(const ExecutionContext &exe_ctx, Stream &strm, - RegisterContext *reg_ctx, const RegisterInfo *reg_info) { - if (reg_info) { - RegisterValue reg_value; - - if (reg_ctx->ReadRegister(reg_info, reg_value)) { - strm.Indent(); - - bool prefix_with_altname = (bool)m_command_options.alternate_name; - bool prefix_with_name = !prefix_with_altname; - DumpRegisterValue(reg_value, &strm, reg_info, prefix_with_name, - prefix_with_altname, m_format_options.GetFormat(), 8, - exe_ctx.GetBestExecutionContextScope()); - if ((reg_info->encoding == eEncodingUint) || - (reg_info->encoding == eEncodingSint)) { - Process *process = exe_ctx.GetProcessPtr(); - if (process && reg_info->byte_size == process->GetAddressByteSize()) { - addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS); - if (reg_addr != LLDB_INVALID_ADDRESS) { - Address so_reg_addr; - if (exe_ctx.GetTargetRef() - .GetSectionLoadList() - .ResolveLoadAddress(reg_addr, so_reg_addr)) { - strm.PutCString(" "); - so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), - Address::DumpStyleResolvedDescription); - } - } + RegisterContext ®_ctx, const RegisterInfo ®_info, + bool print_flags) { + RegisterValue reg_value; + if (!reg_ctx.ReadRegister(®_info, reg_value)) + return false; + + strm.Indent(); + + bool prefix_with_altname = (bool)m_command_options.alternate_name; + bool prefix_with_name = !prefix_with_altname; + DumpRegisterValue(reg_value, strm, reg_info, prefix_with_name, + prefix_with_altname, m_format_options.GetFormat(), 8, + exe_ctx.GetBestExecutionContextScope(), print_flags, + exe_ctx.GetTargetSP()); + if ((reg_info.encoding == eEncodingUint) || + (reg_info.encoding == eEncodingSint)) { + Process *process = exe_ctx.GetProcessPtr(); + if (process && reg_info.byte_size == process->GetAddressByteSize()) { + addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS); + if (reg_addr != LLDB_INVALID_ADDRESS) { + Address so_reg_addr; + if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress( + reg_addr, so_reg_addr)) { + strm.PutCString(" "); + so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), + Address::DumpStyleResolvedDescription); } } - strm.EOL(); - return true; } } - return false; + strm.EOL(); + return true; } bool DumpRegisterSet(const ExecutionContext &exe_ctx, Stream &strm, @@ -142,7 +144,8 @@ public: if (primitive_only && reg_info && reg_info->value_regs) continue; - if (DumpRegister(exe_ctx, strm, reg_ctx, reg_info)) + if (reg_info && DumpRegister(exe_ctx, strm, *reg_ctx, *reg_info, + /*print_flags=*/false)) ++available_count; else ++unavailable_count; @@ -162,7 +165,6 @@ protected: Stream &strm = result.GetOutputStream(); RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext(); - const RegisterInfo *reg_info = nullptr; if (command.GetArgumentCount() == 0) { size_t set_idx; @@ -170,8 +172,9 @@ protected: const size_t set_array_size = m_command_options.set_indexes.GetSize(); if (set_array_size > 0) { for (size_t i = 0; i < set_array_size; ++i) { - set_idx = m_command_options.set_indexes[i]->GetUInt64Value(UINT32_MAX, - nullptr); + set_idx = + m_command_options.set_indexes[i]->GetValueAs<uint64_t>().value_or( + UINT32_MAX); if (set_idx < reg_ctx->GetRegisterSetCount()) { if (!DumpRegisterSet(m_exe_ctx, strm, reg_ctx, set_idx)) { if (errno) @@ -215,10 +218,14 @@ protected: auto arg_str = entry.ref(); arg_str.consume_front("$"); - reg_info = reg_ctx->GetRegisterInfoByName(arg_str); - - if (reg_info) { - if (!DumpRegister(m_exe_ctx, strm, reg_ctx, reg_info)) + if (const RegisterInfo *reg_info = + reg_ctx->GetRegisterInfoByName(arg_str)) { + // If they have asked for a specific format don't obscure that by + // printing flags afterwards. + bool print_flags = + !m_format_options.GetFormatValue().OptionWasSet(); + if (!DumpRegister(m_exe_ctx, strm, *reg_ctx, *reg_info, + print_flags)) strm.Printf("%-12s = error: unavailable\n", reg_info->name); } else { result.AppendErrorWithFormat("Invalid register name '%s'.\n", @@ -336,9 +343,8 @@ public: if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eRegisterCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRegisterCompletion, request, nullptr); } protected: @@ -394,16 +400,86 @@ protected: } }; +// "register info" +class CommandObjectRegisterInfo : public CommandObjectParsed { +public: + CommandObjectRegisterInfo(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "register info", + "View information about a register.", nullptr, + eCommandRequiresRegContext | + eCommandProcessMustBeLaunched) { + SetHelpLong(R"( +Name The name lldb uses for the register, optionally with an alias. +Size The size of the register in bytes and again in bits. +Invalidates (*) The registers that would be changed if you wrote this + register. For example, writing to a narrower alias of a wider + register would change the value of the wider register. +Read from (*) The registers that the value of this register is constructed + from. For example, a narrower alias of a wider register will be + read from the wider register. +In sets (*) The register sets that contain this register. For example the + PC will be in the "General Purpose Register" set. +Fields (*) A table of the names and bit positions of the values contained + in this register. + +Fields marked with (*) may not always be present. Some information may be +different for the same register when connected to different debug servers.)"); + + CommandArgumentData register_arg; + register_arg.arg_type = eArgTypeRegisterName; + register_arg.arg_repetition = eArgRepeatPlain; + + CommandArgumentEntry arg1; + arg1.push_back(register_arg); + m_arguments.push_back(arg1); + } + + ~CommandObjectRegisterInfo() override = default; + + void + HandleArgumentCompletion(CompletionRequest &request, + OptionElementVector &opt_element_vector) override { + if (!m_exe_ctx.HasProcessScope() || request.GetCursorIndex() != 0) + return; + CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eRegisterCompletion, request, nullptr); + } + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (command.GetArgumentCount() != 1) { + result.AppendError("register info takes exactly 1 argument: <reg-name>"); + return result.Succeeded(); + } + + llvm::StringRef reg_name = command[0].ref(); + RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext(); + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); + if (reg_info) { + DumpRegisterInfo( + result.GetOutputStream(), *reg_ctx, *reg_info, + GetCommandInterpreter().GetDebugger().GetTerminalWidth()); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else + result.AppendErrorWithFormat("No register found with name '%s'.\n", + reg_name.str().c_str()); + + return result.Succeeded(); + } +}; + // CommandObjectRegister constructor CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : CommandObjectMultiword(interpreter, "register", "Commands to access registers for the current " "thread and stack frame.", - "register [read|write] ...") { + "register [read|write|info] ...") { LoadSubCommand("read", CommandObjectSP(new CommandObjectRegisterRead(interpreter))); LoadSubCommand("write", CommandObjectSP(new CommandObjectRegisterWrite(interpreter))); + LoadSubCommand("info", + CommandObjectSP(new CommandObjectRegisterInfo(interpreter))); } CommandObjectRegister::~CommandObjectRegister() = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp index 7c7236e9793b..6bf1ec99c888 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSession.cpp @@ -31,9 +31,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } protected: diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp index d658e137a4fd..7069cb1d8399 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSettings.cpp @@ -143,9 +143,9 @@ insert-before or insert-after."); } if (request.GetCursorIndex() == setting_var_idx) { // Attempting to complete setting variable name - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); return; } arg = request.GetParsedLine().GetArgumentAtIndex(request.GetCursorIndex()); @@ -161,8 +161,8 @@ insert-before or insert-after."); const char *setting_var_name = request.GetParsedLine().GetArgumentAtIndex(setting_var_idx); Status error; - lldb::OptionValueSP value_sp(GetDebugger().GetPropertyValue( - &m_exe_ctx, setting_var_name, false, error)); + lldb::OptionValueSP value_sp( + GetDebugger().GetPropertyValue(&m_exe_ctx, setting_var_name, error)); if (!value_sp) return; value_sp->AutoComplete(m_interpreter, request); @@ -267,9 +267,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); } protected: @@ -511,16 +511,15 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); } protected: bool DoExecute(Args &args, CommandReturnObject &result) override { result.SetStatus(eReturnStatusSuccessFinishResult); - const bool will_modify = false; const size_t argc = args.GetArgumentCount(); if (argc > 0) { const bool dump_qualified_name = true; @@ -530,7 +529,7 @@ protected: const Property *property = GetDebugger().GetValueProperties()->GetPropertyAtPath( - &m_exe_ctx, will_modify, property_path); + &m_exe_ctx, property_path); if (property) { property->DumpDescription(m_interpreter, result.GetOutputStream(), 0, @@ -596,9 +595,9 @@ public: HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex() < 2) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); } protected: @@ -704,9 +703,9 @@ public: OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); } protected: @@ -796,9 +795,9 @@ public: OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); } protected: @@ -892,9 +891,9 @@ public: OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); } protected: @@ -977,9 +976,9 @@ public: OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); } protected: @@ -1052,9 +1051,9 @@ public: OptionElementVector &opt_element_vector) override { // Attempting to complete variable name if (request.GetCursorIndex() < 2) - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSettingsNameCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSettingsNameCompletion, request, + nullptr); } Options *GetOptions() override { return &m_options; } diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp index 44561cfd736e..16452c1784bd 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectSource.cpp @@ -22,6 +22,7 @@ #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" +#include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Utility/FileSpec.h" @@ -146,10 +147,7 @@ protected: uint32_t num_matches = 0; // Dump all the line entries for the file in the list. ConstString last_module_file_name; - uint32_t num_scs = sc_list.GetSize(); - for (uint32_t i = 0; i < num_scs; ++i) { - SymbolContext sc; - sc_list.GetContextAtIndex(i, sc); + for (const SymbolContext &sc : sc_list) { if (sc.comp_unit) { Module *module = sc.module_sp.get(); CompileUnit *cu = sc.comp_unit; @@ -393,10 +391,7 @@ protected: SymbolContextList sc_list_symbols; module_list.FindFunctionSymbols(name, eFunctionNameTypeAuto, sc_list_symbols); - size_t num_symbol_matches = sc_list_symbols.GetSize(); - for (size_t i = 0; i < num_symbol_matches; i++) { - SymbolContext sc; - sc_list_symbols.GetContextAtIndex(i, sc); + for (const SymbolContext &sc : sc_list_symbols) { if (sc.symbol && sc.symbol->ValueIsAddress()) { const Address &base_address = sc.symbol->GetAddressRef(); Function *function = base_address.CalculateSymbolContextFunction(); @@ -412,9 +407,7 @@ protected: m_options.symbol_name.c_str()); return false; } - for (size_t i = 0; i < num_matches; i++) { - SymbolContext sc; - sc_list_funcs.GetContextAtIndex(i, sc); + for (const SymbolContext &sc : sc_list_funcs) { bool context_found_for_symbol = false; // Loop through all the ranges in the function. AddressRange range; @@ -926,69 +919,45 @@ protected: // Displaying the source for a symbol. Search for function named name. FindMatchingFunctions(target, name, sc_list); - size_t num_matches = sc_list.GetSize(); - if (!num_matches) { + if (sc_list.GetSize() == 0) { // If we didn't find any functions with that name, try searching for // symbols that line up exactly with function addresses. SymbolContextList sc_list_symbols; FindMatchingFunctionSymbols(target, name, sc_list_symbols); - size_t num_symbol_matches = sc_list_symbols.GetSize(); - - for (size_t i = 0; i < num_symbol_matches; i++) { - SymbolContext sc; - sc_list_symbols.GetContextAtIndex(i, sc); + for (const SymbolContext &sc : sc_list_symbols) { if (sc.symbol && sc.symbol->ValueIsAddress()) { const Address &base_address = sc.symbol->GetAddressRef(); Function *function = base_address.CalculateSymbolContextFunction(); if (function) { sc_list.Append(SymbolContext(function)); - num_matches++; break; } } } } - if (num_matches == 0) { + if (sc_list.GetSize() == 0) { result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str()); return false; } - if (num_matches > 1) { - std::set<SourceInfo> source_match_set; - - bool displayed_something = false; - for (size_t i = 0; i < num_matches; i++) { - SymbolContext sc; - sc_list.GetContextAtIndex(i, sc); - SourceInfo source_info(sc.GetFunctionName(), - sc.GetFunctionStartLineEntry()); - - if (source_info.IsValid()) { - if (source_match_set.find(source_info) == source_match_set.end()) { - source_match_set.insert(source_info); - if (DisplayFunctionSource(sc, source_info, result)) - displayed_something = true; - } - } - } - - if (displayed_something) - result.SetStatus(eReturnStatusSuccessFinishResult); - else - result.SetStatus(eReturnStatusFailed); - } else { - SymbolContext sc; - sc_list.GetContextAtIndex(0, sc); - SourceInfo source_info; - - if (DisplayFunctionSource(sc, source_info, result)) { - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.SetStatus(eReturnStatusFailed); + std::set<SourceInfo> source_match_set; + bool displayed_something = false; + for (const SymbolContext &sc : sc_list) { + SourceInfo source_info(sc.GetFunctionName(), + sc.GetFunctionStartLineEntry()); + if (source_info.IsValid() && + source_match_set.find(source_info) == source_match_set.end()) { + source_match_set.insert(source_info); + if (DisplayFunctionSource(sc, source_info, result)) + displayed_something = true; } } + if (displayed_something) + result.SetStatus(eReturnStatusSuccessFinishResult); + else + result.SetStatus(eReturnStatusFailed); return result.Succeeded(); } else if (m_options.address != LLDB_INVALID_ADDRESS) { Address so_addr; @@ -1052,10 +1021,7 @@ protected: return false; } } - uint32_t num_matches = sc_list.GetSize(); - for (uint32_t i = 0; i < num_matches; ++i) { - SymbolContext sc; - sc_list.GetContextAtIndex(i, sc); + for (const SymbolContext &sc : sc_list) { if (sc.comp_unit) { if (m_options.show_bp_locs) { m_breakpoint_locations.Clear(); @@ -1175,9 +1141,7 @@ protected: bool got_multiple = false; CompileUnit *test_cu = nullptr; - for (unsigned i = 0; i < num_matches; i++) { - SymbolContext sc; - sc_list.GetContextAtIndex(i, sc); + for (const SymbolContext &sc : sc_list) { if (sc.comp_unit) { if (test_cu) { if (test_cu != sc.comp_unit) @@ -1238,6 +1202,78 @@ protected: std::string m_reverse_name; }; +class CommandObjectSourceCacheDump : public CommandObjectParsed { +public: + CommandObjectSourceCacheDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "source cache dump", + "Dump the state of the source code cache. Intended " + "to be used for debugging LLDB itself.", + nullptr) {} + + ~CommandObjectSourceCacheDump() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + // Dump the debugger source cache. + result.GetOutputStream() << "Debugger Source File Cache\n"; + SourceManager::SourceFileCache &cache = GetDebugger().GetSourceFileCache(); + cache.Dump(result.GetOutputStream()); + + // Dump the process source cache. + if (ProcessSP process_sp = m_exe_ctx.GetProcessSP()) { + result.GetOutputStream() << "\nProcess Source File Cache\n"; + SourceManager::SourceFileCache &cache = process_sp->GetSourceFileCache(); + cache.Dump(result.GetOutputStream()); + } + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + +class CommandObjectSourceCacheClear : public CommandObjectParsed { +public: + CommandObjectSourceCacheClear(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "source cache clear", + "Clear the source code cache.\n", nullptr) {} + + ~CommandObjectSourceCacheClear() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + // Clear the debugger cache. + SourceManager::SourceFileCache &cache = GetDebugger().GetSourceFileCache(); + cache.Clear(); + + // Clear the process cache. + if (ProcessSP process_sp = m_exe_ctx.GetProcessSP()) + process_sp->GetSourceFileCache().Clear(); + + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); + } +}; + +class CommandObjectSourceCache : public CommandObjectMultiword { +public: + CommandObjectSourceCache(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "source cache", + "Commands for managing the source code cache.", + "source cache <sub-command>") { + LoadSubCommand( + "dump", CommandObjectSP(new CommandObjectSourceCacheDump(interpreter))); + LoadSubCommand("clear", CommandObjectSP(new CommandObjectSourceCacheClear( + interpreter))); + } + + ~CommandObjectSourceCache() override = default; + +private: + CommandObjectSourceCache(const CommandObjectSourceCache &) = delete; + const CommandObjectSourceCache & + operator=(const CommandObjectSourceCache &) = delete; +}; + #pragma mark CommandObjectMultiwordSource // CommandObjectMultiwordSource @@ -1253,6 +1289,8 @@ CommandObjectMultiwordSource::CommandObjectMultiwordSource( CommandObjectSP(new CommandObjectSourceInfo(interpreter))); LoadSubCommand("list", CommandObjectSP(new CommandObjectSourceList(interpreter))); + LoadSubCommand("cache", + CommandObjectSP(new CommandObjectSourceCache(interpreter))); } CommandObjectMultiwordSource::~CommandObjectMultiwordSource() = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp index 3d53de1d2d2b..3e024ff91b38 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTarget.cpp @@ -82,8 +82,14 @@ static void DumpTargetInfo(uint32_t target_idx, Target *target, if (!exe_valid) ::strcpy(exe_path, "<none>"); - strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, - exe_path); + std::string formatted_label = ""; + const std::string &label = target->GetLabel(); + if (!label.empty()) { + formatted_label = " (" + label + ")"; + } + + strm.Printf("%starget #%u%s: %s", prefix_cstr ? prefix_cstr : "", target_idx, + formatted_label.data(), exe_path); uint32_t properties = 0; if (target_arch.IsValid()) { @@ -209,6 +215,8 @@ public: m_platform_options(true), // Include the --platform option. m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."), + m_label(LLDB_OPT_SET_1, false, "label", 'l', 0, eArgTypeName, + "Optional name for this target.", nullptr), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug " @@ -234,6 +242,7 @@ public: m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1); m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); + m_option_group.Append(&m_label, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); @@ -247,9 +256,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } protected: @@ -303,6 +311,14 @@ protected: return false; } + const llvm::StringRef label = + m_label.GetOptionValue().GetCurrentValueAsRef(); + if (!label.empty()) { + if (auto E = target_sp->SetLabel(label)) + result.SetError(std::move(E)); + return false; + } + auto on_error = llvm::make_scope_exit( [&target_list = debugger.GetTargetList(), &target_sp]() { target_list.DeleteTarget(target_sp); @@ -455,6 +471,7 @@ private: OptionGroupArchitecture m_arch_option; OptionGroupPlatform m_platform_options; OptionGroupFile m_core_file; + OptionGroupString m_label; OptionGroupFile m_symbol_file; OptionGroupFile m_remote_file; OptionGroupDependents m_add_dependents; @@ -503,11 +520,11 @@ public: protected: bool DoExecute(Args &args, CommandReturnObject &result) override { if (args.GetArgumentCount() == 1) { - const char *target_idx_arg = args.GetArgumentAtIndex(0); - uint32_t target_idx; - if (llvm::to_integer(target_idx_arg, target_idx)) { - TargetList &target_list = GetDebugger().GetTargetList(); - const uint32_t num_targets = target_list.GetNumTargets(); + const char *target_identifier = args.GetArgumentAtIndex(0); + uint32_t target_idx = LLDB_INVALID_INDEX32; + TargetList &target_list = GetDebugger().GetTargetList(); + const uint32_t num_targets = target_list.GetNumTargets(); + if (llvm::to_integer(target_identifier, target_idx)) { if (target_idx < num_targets) { target_list.SetSelectedTarget(target_idx); Stream &strm = result.GetOutputStream(); @@ -526,8 +543,26 @@ protected: } } } else { - result.AppendErrorWithFormat("invalid index string value '%s'\n", - target_idx_arg); + for (size_t i = 0; i < num_targets; i++) { + if (TargetSP target_sp = target_list.GetTargetAtIndex(i)) { + const std::string &label = target_sp->GetLabel(); + if (!label.empty() && label == target_identifier) { + target_idx = i; + break; + } + } + } + + if (target_idx != LLDB_INVALID_INDEX32) { + target_list.SetSelectedTarget(target_idx); + Stream &strm = result.GetOutputStream(); + bool show_stopped_process_status = false; + DumpTargetList(target_list, show_stopped_process_status, strm); + result.SetStatus(eReturnStatusSuccessFinishResult); + } else { + result.AppendErrorWithFormat("invalid index string value '%s'\n", + target_identifier); + } } } else { result.AppendError( @@ -576,7 +611,7 @@ protected: TargetSP target_sp; if (m_all_option.GetOptionValue()) { - for (int i = 0; i < target_list.GetNumTargets(); ++i) + for (size_t i = 0; i < target_list.GetNumTargets(); ++i) delete_target_list.push_back(target_list.GetTargetAtIndex(i)); } else if (argc > 0) { const uint32_t num_targets = target_list.GetNumTargets(); @@ -957,29 +992,21 @@ protected: compile_units.GetFileSpecAtIndex(cu_idx), sc_list); } - const uint32_t num_scs = sc_list.GetSize(); - if (num_scs > 0) { - SymbolContext sc; - for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) { - if (sc_list.GetContextAtIndex(sc_idx, sc)) { - if (sc.comp_unit) { - const bool can_create = true; - VariableListSP comp_unit_varlist_sp( - sc.comp_unit->GetVariableList(can_create)); - if (comp_unit_varlist_sp) - DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, - s); - } else if (sc.module_sp) { - // Get all global variables for this module - lldb_private::RegularExpression all_globals_regex( - llvm::StringRef( - ".")); // Any global with at least one character - VariableList variable_list; - sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX, - variable_list); - DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s); - } - } + for (const SymbolContext &sc : sc_list) { + if (sc.comp_unit) { + const bool can_create = true; + VariableListSP comp_unit_varlist_sp( + sc.comp_unit->GetVariableList(can_create)); + if (comp_unit_varlist_sp) + DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); + } else if (sc.module_sp) { + // Get all global variables for this module + lldb_private::RegularExpression all_globals_regex( + llvm::StringRef(".")); // Any global with at least one character + VariableList variable_list; + sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX, + variable_list); + DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s); } } } @@ -1291,7 +1318,7 @@ static void DumpModuleArchitecture(Stream &strm, Module *module, static void DumpModuleUUID(Stream &strm, Module *module) { if (module && module->GetUUID().IsValid()) - module->GetUUID().Dump(&strm); + module->GetUUID().Dump(strm); else strm.PutCString(" "); } @@ -1306,22 +1333,22 @@ static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter, num_matches = module->ResolveSymbolContextsForFileSpec( file_spec, 0, false, eSymbolContextCompUnit, sc_list); - for (uint32_t i = 0; i < num_matches; ++i) { - SymbolContext sc; - if (sc_list.GetContextAtIndex(i, sc)) { - if (i > 0) - strm << "\n\n"; - - strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `" - << module->GetFileSpec().GetFilename() << "\n"; - LineTable *line_table = sc.comp_unit->GetLineTable(); - if (line_table) - line_table->GetDescription( - &strm, interpreter.GetExecutionContext().GetTargetPtr(), - desc_level); - else - strm << "No line table"; - } + bool first_module = true; + for (const SymbolContext &sc : sc_list) { + if (!first_module) + strm << "\n\n"; + + strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `" + << module->GetFileSpec().GetFilename() << "\n"; + LineTable *line_table = sc.comp_unit->GetLineTable(); + if (line_table) + line_table->GetDescription( + &strm, interpreter.GetExecutionContext().GetTargetPtr(), + desc_level); + else + strm << "No line table"; + + first_module = false; } } return num_matches; @@ -1480,28 +1507,6 @@ static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm); - // strm.IndentMore(); - // strm.Indent (" Address: "); - // so_addr.Dump (&strm, exe_scope, - // Address::DumpStyleModuleWithFileAddress); - // strm.PutCString (" ("); - // so_addr.Dump (&strm, exe_scope, - // Address::DumpStyleSectionNameOffset); - // strm.PutCString (")\n"); - // strm.Indent (" Summary: "); - // const uint32_t save_indent = strm.GetIndentLevel (); - // strm.SetIndentLevel (save_indent + 13); - // so_addr.Dump (&strm, exe_scope, - // Address::DumpStyleResolvedDescription); - // strm.SetIndentLevel (save_indent); - // // Print out detailed address information when verbose is enabled - // if (verbose) - // { - // strm.EOL(); - // so_addr.Dump (&strm, exe_scope, - // Address::DumpStyleDetailedSymbolContext); - // } - // strm.IndentLess(); return true; } @@ -1568,21 +1573,21 @@ static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, } static void DumpSymbolContextList(ExecutionContextScope *exe_scope, - Stream &strm, SymbolContextList &sc_list, + Stream &strm, + const SymbolContextList &sc_list, bool verbose, bool all_ranges) { strm.IndentMore(); + bool first_module = true; + for (const SymbolContext &sc : sc_list) { + if (!first_module) + strm.EOL(); - const uint32_t num_matches = sc_list.GetSize(); - - for (uint32_t i = 0; i < num_matches; ++i) { - SymbolContext sc; - if (sc_list.GetContextAtIndex(i, sc)) { - AddressRange range; + AddressRange range; - sc.GetAddressRange(eSymbolContextEverything, 0, true, range); + sc.GetAddressRange(eSymbolContextEverything, 0, true, range); - DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm); - } + DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm); + first_module = false; } strm.IndentLess(); } @@ -1818,9 +1823,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request, - nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eModuleCompletion, request, nullptr); } }; @@ -1856,9 +1860,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eSourceFileCompletion, request, nullptr); } }; @@ -2002,8 +2005,11 @@ protected: result.GetOutputStream().EOL(); result.GetOutputStream().EOL(); } - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), + "Interrupted in dump all symtabs with {0} " + "of {1} dumped.", num_dumped, num_modules)) break; + num_dumped++; DumpModuleSymtab(m_interpreter, result.GetOutputStream(), module_sp.get(), m_options.m_sort_order, @@ -2029,8 +2035,11 @@ protected: result.GetOutputStream().EOL(); result.GetOutputStream().EOL(); } - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), + "Interrupted in dump symtab list with {0} of {1} dumped.", + num_dumped, num_matches)) break; + num_dumped++; DumpModuleSymtab(m_interpreter, result.GetOutputStream(), module_sp.get(), m_options.m_sort_order, @@ -2090,8 +2099,11 @@ protected: result.GetOutputStream().Format("Dumping sections for {0} modules.\n", num_modules); for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), + "Interrupted in dump all sections with {0} of {1} dumped", + image_idx, num_modules)) break; + num_dumped++; DumpModuleSections( m_interpreter, result.GetOutputStream(), @@ -2108,8 +2120,11 @@ protected: FindModulesByName(target, arg_cstr, module_list, true); if (num_matches > 0) { for (size_t i = 0; i < num_matches; ++i) { - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), + "Interrupted in dump section list with {0} of {1} dumped.", + i, num_matches)) break; + Module *module = module_list.GetModulePointerAtIndex(i); if (module) { num_dumped++; @@ -2159,9 +2174,9 @@ protected: } const char *pcm_path = command.GetArgumentAtIndex(0); - FileSpec pcm_file{pcm_path}; + const FileSpec pcm_file{pcm_path}; - if (pcm_file.GetFileNameExtension().GetStringRef() != ".pcm") { + if (pcm_file.GetFileNameExtension() != ".pcm") { result.AppendError("file must have a .pcm extension"); return false; } @@ -2177,8 +2192,11 @@ protected: const char *clang_args[] = {"clang", pcm_path}; compiler.setInvocation(clang::createInvocation(clang_args)); - clang::DumpModuleInfoAction dump_module_info; - dump_module_info.OutputStream = &result.GetOutputStream().AsRawOstream(); + // Pass empty deleter to not attempt to free memory that was allocated + // outside of the current scope, possibly statically. + std::shared_ptr<llvm::raw_ostream> Out( + &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {}); + clang::DumpModuleInfoAction dump_module_info(Out); // DumpModuleInfoAction requires ObjectFilePCHContainerReader. compiler.getPCHContainerOperations()->registerReader( std::make_unique<clang::ObjectFilePCHContainerReader>()); @@ -2222,7 +2240,7 @@ protected: result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n", num_modules); for (ModuleSP module_sp : module_list.ModulesNoLocking()) { - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast")) break; if (SymbolFile *sf = module_sp->GetSymbolFile()) sf->DumpClangAST(result.GetOutputStream()); @@ -2247,8 +2265,11 @@ protected: } for (size_t i = 0; i < num_matches; ++i) { - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), + "Interrupted in dump clang ast list with {0} of {1} dumped.", + i, num_matches)) break; + Module *m = module_list.GetModulePointerAtIndex(i); if (SymbolFile *sf = m->GetSymbolFile()) sf->DumpClangAST(result.GetOutputStream()); @@ -2296,8 +2317,11 @@ protected: result.GetOutputStream().Format( "Dumping debug symbols for {0} modules.\n", num_modules); for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all " + "debug symbols with {0} of {1} modules dumped", + num_dumped, num_modules)) break; + if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get())) num_dumped++; } @@ -2312,7 +2336,9 @@ protected: FindModulesByName(target, arg_cstr, module_list, true); if (num_matches > 0) { for (size_t i = 0; i < num_matches; ++i) { - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} " + "of {1} requested modules", + i, num_matches)) break; Module *module = module_list.GetModulePointerAtIndex(i); if (module) { @@ -2376,11 +2402,16 @@ protected: const ModuleList &target_modules = target->GetImages(); std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); - if (target_modules.GetSize() > 0) { + size_t num_modules = target_modules.GetSize(); + if (num_modules > 0) { uint32_t num_dumped = 0; for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { - if (m_interpreter.WasInterrupted()) + if (INTERRUPT_REQUESTED(GetDebugger(), + "Interrupted in dump all line tables with " + "{0} of {1} dumped", num_dumped, + num_modules)) break; + if (DumpCompileUnitLineTable( m_interpreter, result.GetOutputStream(), module_sp.get(), file_spec, @@ -2500,9 +2531,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } protected: @@ -2533,7 +2563,7 @@ protected: return true; } else { StreamString strm; - module_spec.GetUUID().Dump(&strm); + module_spec.GetUUID().Dump(strm); if (module_spec.GetFileSpec()) { if (module_spec.GetSymbolFileSpec()) { result.AppendErrorWithFormat( @@ -2557,7 +2587,7 @@ protected: } } else { StreamString strm; - module_spec.GetUUID().Dump(&strm); + module_spec.GetUUID().Dump(strm); result.AppendErrorWithFormat( "Unable to locate the executable or symbol file with UUID %s", strm.GetData()); @@ -3363,16 +3393,13 @@ protected: return false; } - size_t num_matches = sc_list.GetSize(); - if (num_matches == 0) { + if (sc_list.GetSize() == 0) { result.AppendErrorWithFormat("no unwind data found that matches '%s'.", m_options.m_str.c_str()); return false; } - for (uint32_t idx = 0; idx < num_matches; idx++) { - SymbolContext sc; - sc_list.GetContextAtIndex(idx, sc); + for (const SymbolContext &sc : sc_list) { if (sc.symbol == nullptr && sc.function == nullptr) continue; if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr) @@ -4034,8 +4061,8 @@ public: "target symbols add <cmd-options> [<symfile>]", eCommandRequiresTarget), m_file_option( - LLDB_OPT_SET_1, false, "shlib", 's', - CommandCompletions::eModuleCompletion, eArgTypeShlibName, + LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion, + eArgTypeShlibName, "Locate the debug symbols for the shared library specified by " "name."), m_current_frame_option( @@ -4065,9 +4092,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } Options *GetOptions() override { return &m_option_group; } @@ -4193,7 +4219,7 @@ protected: Status error; StreamString feedback_stream; module_sp->LoadScriptingResourceInTarget(target, error, - &feedback_stream); + feedback_stream); if (error.Fail() && error.AsCString()) result.AppendWarningWithFormat( "unable to load scripting data for module %s - error " @@ -4217,7 +4243,7 @@ protected: StreamString ss_symfile_uuid; if (module_spec.GetUUID().IsValid()) { ss_symfile_uuid << " ("; - module_spec.GetUUID().Dump(&ss_symfile_uuid); + module_spec.GetUUID().Dump(ss_symfile_uuid); ss_symfile_uuid << ')'; } result.AppendErrorWithFormat( @@ -4252,7 +4278,7 @@ protected: if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { StreamString error_strm; error_strm.PutCString("unable to find debug symbols for UUID "); - module_spec.GetUUID().Dump(&error_strm); + module_spec.GetUUID().Dump(error_strm); result.AppendError(error_strm.GetString()); return false; } @@ -4916,9 +4942,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr); } protected: @@ -4974,9 +4999,8 @@ public: OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex()) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eStopHookIDCompletion, request, nullptr); } protected: @@ -5036,7 +5060,7 @@ protected: Target::StopHookSP this_hook = target.GetStopHookAtIndex(i); if (i > 0) result.GetOutputStream().PutCString("\n"); - this_hook->GetDescription(&(result.GetOutputStream()), + this_hook->GetDescription(result.GetOutputStream(), eDescriptionLevelFull); } } @@ -5084,8 +5108,8 @@ public: CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter) : CommandObjectParsed( interpreter, "target dump typesystem", - "Dump the state of the target's internal type system.\n" - "Intended to be used for debugging LLDB itself.", + "Dump the state of the target's internal type system. Intended to " + "be used for debugging LLDB itself.", nullptr, eCommandRequiresTarget) {} ~CommandObjectTargetDumpTypesystem() override = default; @@ -5102,6 +5126,29 @@ protected: } }; +#pragma mark CommandObjectTargetDumpSectionLoadList + +/// Dumps the SectionLoadList of the selected Target. +class CommandObjectTargetDumpSectionLoadList : public CommandObjectParsed { +public: + CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "target dump section-load-list", + "Dump the state of the target's internal section load list. " + "Intended to be used for debugging LLDB itself.", + nullptr, eCommandRequiresTarget) {} + + ~CommandObjectTargetDumpSectionLoadList() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + Target &target = GetSelectedTarget(); + target.GetSectionLoadList().Dump(result.GetOutputStream(), &target); + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + #pragma mark CommandObjectTargetDump /// Multi-word command for 'target dump'. @@ -5112,10 +5159,13 @@ public: : CommandObjectMultiword( interpreter, "target dump", "Commands for dumping information about the target.", - "target dump [typesystem]") { + "target dump [typesystem|section-load-list]") { LoadSubCommand( "typesystem", CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter))); + LoadSubCommand("section-load-list", + CommandObjectSP(new CommandObjectTargetDumpSectionLoadList( + interpreter))); } ~CommandObjectTargetDump() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp index 411f28d84a21..64f3edcad563 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectThread.cpp @@ -228,8 +228,11 @@ protected: thread->GetIndexID()); return false; } - if (m_options.m_extended_backtrace) { - DoExtendedBacktrace(thread, result); + if (m_options.m_extended_backtrace) { + if (!INTERRUPT_REQUESTED(GetDebugger(), + "Interrupt skipped extended backtrace")) { + DoExtendedBacktrace(thread, result); + } } return true; @@ -401,9 +404,9 @@ public: if (request.GetCursorIndex()) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eThreadIndexCompletion, request, + nullptr); } Options *GetOptions() override { return &m_all_options; } @@ -556,8 +559,9 @@ protected: } else if (m_step_type == eStepTypeOut) { new_plan_sp = thread->QueueThreadPlanForStepOut( abort_other_plans, nullptr, false, bool_stop_other_threads, eVoteYes, - eVoteNoOpinion, thread->GetSelectedFrameIndex(), new_plan_status, - m_options.m_step_out_avoid_no_debug); + eVoteNoOpinion, + thread->GetSelectedFrameIndex(DoNoSelectMostRelevantFrame), + new_plan_status, m_options.m_step_out_avoid_no_debug); } else if (m_step_type == eStepTypeScripted) { new_plan_sp = thread->QueueThreadPlanForStepScripted( abort_other_plans, m_class_options.GetName().c_str(), @@ -663,9 +667,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eThreadIndexCompletion, request, + nullptr); } bool DoExecute(Args &command, CommandReturnObject &result) override { @@ -1160,9 +1164,9 @@ public: if (request.GetCursorIndex()) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eThreadIndexCompletion, request, + nullptr); } protected: @@ -1294,9 +1298,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eThreadIndexCompletion, request, + nullptr); } Options *GetOptions() override { return &m_options; } @@ -1344,9 +1348,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eThreadIndexCompletion, request, + nullptr); } bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { @@ -1392,9 +1396,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eThreadIndexCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eThreadIndexCompletion, request, + nullptr); } bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { @@ -1527,7 +1531,8 @@ protected: bool success = thread->SetSelectedFrameByIndexNoisily(0, result.GetOutputStream()); if (success) { - m_exe_ctx.SetFrameSP(thread->GetSelectedFrame()); + m_exe_ctx.SetFrameSP( + thread->GetSelectedFrame(DoNoSelectMostRelevantFrame)); result.SetStatus(eReturnStatusSuccessFinishResult); } else { result.AppendErrorWithFormat( @@ -2418,7 +2423,7 @@ protected: } CommandOptions m_options; - // Last traversed id used to continue a repeat command. None means + // Last traversed id used to continue a repeat command. std::nullopt means // that all the trace has been consumed. std::optional<lldb::user_id_t> m_last_id; }; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp index ba8289cb68d3..52fb56ffc1fb 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectTrace.cpp @@ -96,9 +96,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } ~CommandObjectTraceSave() override = default; @@ -186,9 +185,8 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eDiskFileCompletion, request, nullptr); } ~CommandObjectTraceLoad() override = default; diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp index 1120caa1da4c..e6dd63a6cb21 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectType.cpp @@ -39,9 +39,6 @@ #include <functional> #include <memory> -#define CHECK_FORMATTER_KIND_MASK(VAL) \ - ((m_formatter_kind_mask & (VAL)) == (VAL)) - using namespace lldb; using namespace lldb_private; @@ -100,6 +97,22 @@ static bool WarnOnPotentialUnquotedUnsignedType(Args &command, return false; } +const char *FormatCategoryToString(FormatCategoryItem item, bool long_name) { + switch (item) { + case eFormatCategoryItemSummary: + return "summary"; + case eFormatCategoryItemFilter: + return "filter"; + case eFormatCategoryItemSynth: + if (long_name) + return "synthetic child provider"; + return "synthetic"; + case eFormatCategoryItemFormat: + return "format"; + } + llvm_unreachable("Fully covered switch above!"); +} + #define LLDB_OPTIONS_type_summary_add #include "CommandOptions.inc" @@ -754,16 +767,25 @@ protected: }; CommandOptions m_options; - uint32_t m_formatter_kind_mask; + FormatCategoryItem m_formatter_kind; Options *GetOptions() override { return &m_options; } + static constexpr const char *g_short_help_template = + "Delete an existing %s for a type."; + + static constexpr const char *g_long_help_template = + "Delete an existing %s for a type. Unless you specify a " + "specific category or all categories, only the " + "'default' category is searched. The names must be exactly as " + "shown in the 'type %s list' output"; + public: CommandObjectTypeFormatterDelete(CommandInterpreter &interpreter, - uint32_t formatter_kind_mask, - const char *name, const char *help) - : CommandObjectParsed(interpreter, name, help, nullptr), - m_formatter_kind_mask(formatter_kind_mask) { + FormatCategoryItem formatter_kind) + : CommandObjectParsed(interpreter, + FormatCategoryToString(formatter_kind, false)), + m_formatter_kind(formatter_kind) { CommandArgumentEntry type_arg; CommandArgumentData type_style_arg; @@ -773,6 +795,19 @@ public: type_arg.push_back(type_style_arg); m_arguments.push_back(type_arg); + + const char *kind = FormatCategoryToString(formatter_kind, true); + const char *short_kind = FormatCategoryToString(formatter_kind, false); + + StreamString s; + s.Printf(g_short_help_template, kind); + SetHelp(s.GetData()); + s.Clear(); + s.Printf(g_long_help_template, kind, short_kind); + SetHelpLong(s.GetData()); + s.Clear(); + s.Printf("type %s delete", short_kind); + SetCommandName(s.GetData()); } ~CommandObjectTypeFormatterDelete() override = default; @@ -785,7 +820,7 @@ public: DataVisualization::Categories::ForEach( [this, &request](const lldb::TypeCategoryImplSP &category_sp) { - category_sp->AutoComplete(request, m_formatter_kind_mask); + category_sp->AutoComplete(request, m_formatter_kind); return true; }); } @@ -812,7 +847,7 @@ protected: if (m_options.m_delete_all) { DataVisualization::Categories::ForEach( [this, typeCS](const lldb::TypeCategoryImplSP &category_sp) -> bool { - category_sp->Delete(typeCS, m_formatter_kind_mask); + category_sp->Delete(typeCS, m_formatter_kind); return true; }); result.SetStatus(eReturnStatusSuccessFinishNoResult); @@ -827,14 +862,14 @@ protected: DataVisualization::Categories::GetCategory(m_options.m_language, category); if (category) - delete_category = category->Delete(typeCS, m_formatter_kind_mask); + delete_category = category->Delete(typeCS, m_formatter_kind); extra_deletion = FormatterSpecificDeletion(typeCS); } else { lldb::TypeCategoryImplSP category; DataVisualization::Categories::GetCategory( ConstString(m_options.m_category.c_str()), category); if (category) - delete_category = category->Delete(typeCS, m_formatter_kind_mask); + delete_category = category->Delete(typeCS, m_formatter_kind); extra_deletion = FormatterSpecificDeletion(typeCS); } @@ -888,16 +923,16 @@ private: }; CommandOptions m_options; - uint32_t m_formatter_kind_mask; + FormatCategoryItem m_formatter_kind; Options *GetOptions() override { return &m_options; } public: CommandObjectTypeFormatterClear(CommandInterpreter &interpreter, - uint32_t formatter_kind_mask, + FormatCategoryItem formatter_kind, const char *name, const char *help) : CommandObjectParsed(interpreter, name, help, nullptr), - m_formatter_kind_mask(formatter_kind_mask) { + m_formatter_kind(formatter_kind) { CommandArgumentData category_arg{eArgTypeName, eArgRepeatOptional}; m_arguments.push_back({category_arg}); } @@ -911,7 +946,7 @@ protected: if (m_options.m_delete_all) { DataVisualization::Categories::ForEach( [this](const TypeCategoryImplSP &category_sp) -> bool { - category_sp->Clear(m_formatter_kind_mask); + category_sp->Clear(m_formatter_kind); return true; }); } else { @@ -924,7 +959,7 @@ protected: DataVisualization::Categories::GetCategory(ConstString(nullptr), category); } - category->Clear(m_formatter_kind_mask); + category->Clear(m_formatter_kind); } FormatterSpecificDeletion(); @@ -940,8 +975,7 @@ class CommandObjectTypeFormatDelete : public CommandObjectTypeFormatterDelete { public: CommandObjectTypeFormatDelete(CommandInterpreter &interpreter) : CommandObjectTypeFormatterDelete( - interpreter, eFormatCategoryItemFormat, "type format delete", - "Delete an existing formatting style for a type.") {} + interpreter, eFormatCategoryItemFormat) {} ~CommandObjectTypeFormatDelete() override = default; }; @@ -1609,8 +1643,7 @@ class CommandObjectTypeSummaryDelete : public CommandObjectTypeFormatterDelete { public: CommandObjectTypeSummaryDelete(CommandInterpreter &interpreter) : CommandObjectTypeFormatterDelete( - interpreter, eFormatCategoryItemSummary, "type summary delete", - "Delete an existing summary for a type.") {} + interpreter, eFormatCategoryItemSummary) {} ~CommandObjectTypeSummaryDelete() override = default; @@ -1734,9 +1767,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), - CommandCompletions::eTypeCategoryNameCompletion, request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, + nullptr); } protected: @@ -1836,9 +1869,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), - CommandCompletions::eTypeCategoryNameCompletion, request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, + nullptr); } protected: @@ -1904,9 +1937,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), - CommandCompletions::eTypeCategoryNameCompletion, request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, + nullptr); } protected: @@ -2013,9 +2046,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), - CommandCompletions::eTypeCategoryNameCompletion, request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, + nullptr); } protected: @@ -2078,9 +2111,9 @@ public: OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex()) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), - CommandCompletions::eTypeCategoryNameCompletion, request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eTypeCategoryNameCompletion, request, + nullptr); } protected: @@ -2159,8 +2192,7 @@ class CommandObjectTypeFilterDelete : public CommandObjectTypeFormatterDelete { public: CommandObjectTypeFilterDelete(CommandInterpreter &interpreter) : CommandObjectTypeFormatterDelete( - interpreter, eFormatCategoryItemFilter, "type filter delete", - "Delete an existing filter for a type.") {} + interpreter, eFormatCategoryItemFilter) {} ~CommandObjectTypeFilterDelete() override = default; }; @@ -2173,8 +2205,7 @@ class CommandObjectTypeSynthDelete : public CommandObjectTypeFormatterDelete { public: CommandObjectTypeSynthDelete(CommandInterpreter &interpreter) : CommandObjectTypeFormatterDelete( - interpreter, eFormatCategoryItemSynth, "type synthetic delete", - "Delete an existing synthetic provider for a type.") {} + interpreter, eFormatCategoryItemSynth) {} ~CommandObjectTypeSynthDelete() override = default; }; @@ -2845,7 +2876,8 @@ protected: return false; } - StackFrameSP frame_sp = thread->GetSelectedFrame(); + StackFrameSP frame_sp = + thread->GetSelectedFrame(DoNoSelectMostRelevantFrame); ValueObjectSP result_valobj_sp; EvaluateExpressionOptions options; lldb::ExpressionResults expr_result = target_sp->EvaluateExpression( diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp index 8df8aca04e4a..a4929ea0d515 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -9,6 +9,7 @@ #include "CommandObjectWatchpoint.h" #include "CommandObjectWatchpointCommand.h" +#include <memory> #include <vector> #include "llvm/ADT/StringRef.h" @@ -20,6 +21,7 @@ #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandOptionArgumentTable.h" #include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Symbol/Function.h" #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/StackFrame.h" @@ -29,12 +31,12 @@ using namespace lldb; using namespace lldb_private; -static void AddWatchpointDescription(Stream *s, Watchpoint *wp, +static void AddWatchpointDescription(Stream &s, Watchpoint &wp, lldb::DescriptionLevel level) { - s->IndentMore(); - wp->GetDescription(s, level); - s->IndentLess(); - s->EOL(); + s.IndentMore(); + wp.GetDescription(&s, level); + s.IndentLess(); + s.EOL(); } static bool CheckTargetForWatchpointOperations(Target *target, @@ -209,13 +211,13 @@ protected: Target *target = &GetSelectedTarget(); if (target->GetProcessSP() && target->GetProcessSP()->IsAlive()) { - uint32_t num_supported_hardware_watchpoints; - Status error = target->GetProcessSP()->GetWatchpointSupportInfo( - num_supported_hardware_watchpoints); - if (error.Success()) + std::optional<uint32_t> num_supported_hardware_watchpoints = + target->GetProcessSP()->GetWatchpointSlotCount(); + + if (num_supported_hardware_watchpoints) result.AppendMessageWithFormat( "Number of supported hardware watchpoints: %u\n", - num_supported_hardware_watchpoints); + *num_supported_hardware_watchpoints); } const WatchpointList &watchpoints = target->GetWatchpointList(); @@ -237,8 +239,8 @@ protected: // No watchpoint selected; show info about all currently set watchpoints. result.AppendMessage("Current watchpoints:"); for (size_t i = 0; i < num_watchpoints; ++i) { - Watchpoint *wp = watchpoints.GetByIndex(i).get(); - AddWatchpointDescription(&output_stream, wp, m_options.m_level); + WatchpointSP watch_sp = watchpoints.GetByIndex(i); + AddWatchpointDescription(output_stream, *watch_sp, m_options.m_level); } result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { @@ -252,9 +254,9 @@ protected: const size_t size = wp_ids.size(); for (size_t i = 0; i < size; ++i) { - Watchpoint *wp = watchpoints.FindByID(wp_ids[i]).get(); - if (wp) - AddWatchpointDescription(&output_stream, wp, m_options.m_level); + WatchpointSP watch_sp = watchpoints.FindByID(wp_ids[i]); + if (watch_sp) + AddWatchpointDescription(output_stream, *watch_sp, m_options.m_level); result.SetStatus(eReturnStatusSuccessFinishNoResult); } } @@ -289,9 +291,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eWatchpointIDCompletion, request, + nullptr); } protected: @@ -365,9 +367,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eWatchpointIDCompletion, request, + nullptr); } protected: @@ -446,9 +448,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eWatchpointIDCompletion, request, + nullptr); } Options *GetOptions() override { return &m_options; } @@ -569,9 +571,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eWatchpointIDCompletion, request, + nullptr); } Options *GetOptions() override { return &m_options; } @@ -694,9 +696,9 @@ public: void HandleArgumentCompletion(CompletionRequest &request, OptionElementVector &opt_element_vector) override { - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eWatchPointIDCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eWatchpointIDCompletion, request, + nullptr); } Options *GetOptions() override { return &m_options; } @@ -758,8 +760,8 @@ protected: } if (command.GetArgumentCount() == 0) { - WatchpointSP wp_sp = target->GetLastCreatedWatchpoint(); - wp_sp->SetCondition(m_options.m_condition.c_str()); + WatchpointSP watch_sp = target->GetLastCreatedWatchpoint(); + watch_sp->SetCondition(m_options.m_condition.c_str()); result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { // Particular watchpoints selected; set condition on them. @@ -773,9 +775,9 @@ protected: int count = 0; const size_t size = wp_ids.size(); for (size_t i = 0; i < size; ++i) { - WatchpointSP wp_sp = watchpoints.FindByID(wp_ids[i]); - if (wp_sp) { - wp_sp->SetCondition(m_options.m_condition.c_str()); + WatchpointSP watch_sp = watchpoints.FindByID(wp_ids[i]); + if (watch_sp) { + watch_sp->SetCondition(m_options.m_condition.c_str()); ++count; } } @@ -835,8 +837,7 @@ corresponding to the byte size of the data type."); m_arguments.push_back(arg); // Absorb the '-w' and '-s' options into our option group. - m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_ALL, - LLDB_OPT_SET_1); + m_option_group.Append(&m_option_watchpoint, LLDB_OPT_SET_1, LLDB_OPT_SET_1); m_option_group.Finalize(); } @@ -847,9 +848,9 @@ corresponding to the byte size of the data type."); OptionElementVector &opt_element_vector) override { if (request.GetCursorIndex() != 0) return; - CommandCompletions::InvokeCommonCompletionCallbacks( - GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, - request, nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + GetCommandInterpreter(), lldb::eVariablePathCompletion, request, + nullptr); } Options *GetOptions() override { return &m_option_group; } @@ -949,30 +950,34 @@ protected: uint32_t watch_type = m_option_watchpoint.watch_type; error.Clear(); - Watchpoint *wp = - target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error) - .get(); - if (wp) { - wp->SetWatchSpec(command.GetArgumentAtIndex(0)); - wp->SetWatchVariable(true); - if (var_sp && var_sp->GetDeclaration().GetFile()) { + WatchpointSP watch_sp = + target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error); + if (!watch_sp) { + result.AppendErrorWithFormat( + "Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64 + ", variable expression='%s').\n", + addr, static_cast<uint64_t>(size), command.GetArgumentAtIndex(0)); + if (const char *error_message = error.AsCString(nullptr)) + result.AppendError(error_message); + return result.Succeeded(); + } + + watch_sp->SetWatchSpec(command.GetArgumentAtIndex(0)); + watch_sp->SetWatchVariable(true); + if (var_sp) { + if (var_sp->GetDeclaration().GetFile()) { StreamString ss; // True to show fullpath for declaration file. var_sp->GetDeclaration().DumpStopContext(&ss, true); - wp->SetDeclInfo(std::string(ss.GetString())); + watch_sp->SetDeclInfo(std::string(ss.GetString())); } - output_stream.Printf("Watchpoint created: "); - wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); - output_stream.EOL(); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - result.AppendErrorWithFormat( - "Watchpoint creation failed (addr=0x%" PRIx64 ", size=%" PRIu64 - ", variable expression='%s').\n", - addr, (uint64_t)size, command.GetArgumentAtIndex(0)); - if (error.AsCString(nullptr)) - result.AppendError(error.AsCString()); + if (var_sp->GetScope() == eValueTypeVariableLocal) + watch_sp->SetupVariableWatchpointDisabler(m_exe_ctx.GetFrameSP()); } + output_stream.Printf("Watchpoint created: "); + watch_sp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); + output_stream.EOL(); + result.SetStatus(eReturnStatusSuccessFinishResult); return result.Succeeded(); } @@ -991,6 +996,7 @@ public: : CommandObjectRaw( interpreter, "watchpoint set expression", "Set a watchpoint on an address by supplying an expression. " + "Use the '-l' option to specify the language of the expression. " "Use the '-w' option to specify the type of watchpoint and " "the '-s' option to specify the byte size to watch for. " "If no '-w' option is specified, it defaults to write. " @@ -1084,6 +1090,8 @@ protected: options.SetKeepInMemory(false); options.SetTryAllThreads(true); options.SetTimeout(std::nullopt); + if (m_option_watchpoint.language_type != eLanguageTypeUnknown) + options.SetLanguage(m_option_watchpoint.language_type); ExpressionResults expr_result = target->EvaluateExpression(expr, frame, valobj_sp, options); @@ -1117,13 +1125,13 @@ protected: CompilerType compiler_type(valobj_sp->GetCompilerType()); Status error; - Watchpoint *wp = - target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error) - .get(); - if (wp) { + WatchpointSP watch_sp = + target->CreateWatchpoint(addr, size, &compiler_type, watch_type, error); + if (watch_sp) { + watch_sp->SetWatchSpec(std::string(expr)); Stream &output_stream = result.GetOutputStream(); output_stream.Printf("Watchpoint created: "); - wp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); + watch_sp->GetDescription(&output_stream, lldb::eDescriptionLevelFull); output_stream.EOL(); result.SetStatus(eReturnStatusSuccessFinishResult); } else { diff --git a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index b33f403a6964..37052ddd62c8 100644 --- a/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/contrib/llvm-project/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -415,17 +415,18 @@ protected: // Special handling for one-liner specified inline. if (m_options.m_use_one_liner) { script_interp->SetWatchpointCommandCallback( - wp_options, m_options.m_one_liner.c_str()); + wp_options, m_options.m_one_liner.c_str(), + /*is_callback=*/false); } // Special handling for using a Python function by name instead of // extending the watchpoint callback data structures, we just // automatize what the user would do manually: make their watchpoint // command be a function call else if (!m_options.m_function_name.empty()) { - std::string oneliner(m_options.m_function_name); - oneliner += "(frame, wp, internal_dict)"; + std::string function_signature = m_options.m_function_name; + function_signature += "(frame, wp, internal_dict)"; script_interp->SetWatchpointCommandCallback( - wp_options, oneliner.c_str()); + wp_options, function_signature.c_str(), /*is_callback=*/true); } else { script_interp->CollectDataForWatchpointCommandCallback(wp_options, result); diff --git a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessAttach.cpp b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessAttach.cpp new file mode 100644 index 000000000000..d3d864dfe025 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessAttach.cpp @@ -0,0 +1,76 @@ +//===-- CommandOptionsProcessAttach.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 "CommandOptionsProcessAttach.h" + +#include "lldb/Host/FileSystem.h" +#include "lldb/Host/HostInfo.h" +#include "lldb/Host/OptionParser.h" +#include "lldb/Interpreter/CommandCompletions.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandOptionArgumentTable.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Platform.h" +#include "lldb/Target/Target.h" + +#include "llvm/ADT/ArrayRef.h" + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; + +#define LLDB_OPTIONS_process_attach +#include "CommandOptions.inc" + +Status CommandOptionsProcessAttach::SetOptionValue( + uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) { + Status error; + const int short_option = g_process_attach_options[option_idx].short_option; + switch (short_option) { + case 'c': + attach_info.SetContinueOnceAttached(true); + break; + + case 'p': { + lldb::pid_t pid; + if (option_arg.getAsInteger(0, pid)) { + error.SetErrorStringWithFormat("invalid process ID '%s'", + option_arg.str().c_str()); + } else { + attach_info.SetProcessID(pid); + } + } break; + + case 'P': + attach_info.SetProcessPluginName(option_arg); + break; + + case 'n': + attach_info.GetExecutableFile().SetFile(option_arg, + FileSpec::Style::native); + break; + + case 'w': + attach_info.SetWaitForLaunch(true); + break; + + case 'i': + attach_info.SetIgnoreExisting(false); + break; + + default: + llvm_unreachable("Unimplemented option"); + } + return error; +} + +llvm::ArrayRef<OptionDefinition> CommandOptionsProcessAttach::GetDefinitions() { + return llvm::ArrayRef(g_process_attach_options); +} diff --git a/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessAttach.h b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessAttach.h new file mode 100644 index 000000000000..02daf1aa769a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Commands/CommandOptionsProcessAttach.h @@ -0,0 +1,47 @@ +//===-- CommandOptionsProcessAttach.h ---------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSATTACH_H +#define LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSATTACH_H + +#include "lldb/Interpreter/Options.h" +#include "lldb/Target/Process.h" + +namespace lldb_private { + +// CommandOptionsProcessAttach + +class CommandOptionsProcessAttach : public lldb_private::OptionGroup { +public: + CommandOptionsProcessAttach() { + // Keep default values of all options in one place: OptionParsingStarting + // () + OptionParsingStarting(nullptr); + } + + ~CommandOptionsProcessAttach() override = default; + + lldb_private::Status + SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + lldb_private::ExecutionContext *execution_context) override; + + void OptionParsingStarting( + lldb_private::ExecutionContext *execution_context) override { + attach_info.Clear(); + } + + llvm::ArrayRef<lldb_private::OptionDefinition> GetDefinitions() override; + + // Instance variables to hold the values for command options. + + lldb_private::ProcessAttachInfo attach_info; +}; // CommandOptionsProcessAttach + +} // namespace lldb_private + +#endif // LLDB_SOURCE_COMMANDS_COMMANDOPTIONSPROCESSATTACH_H diff --git a/contrib/llvm-project/lldb/source/Commands/Options.td b/contrib/llvm-project/lldb/source/Commands/Options.td index 6aee2ac22804..04830b8b990e 100644 --- a/contrib/llvm-project/lldb/source/Commands/Options.td +++ b/contrib/llvm-project/lldb/source/Commands/Options.td @@ -371,7 +371,7 @@ let Command = "expression" in { Arg<"Language">, Desc<"Specifies the Language to use when parsing the " "expression. If not set the target.language setting is used.">; def expression_options_apply_fixits : Option<"apply-fixits", "X">, - Groups<[1,2]>, Arg<"Language">, Desc<"If true, simple fix-it hints will be " + Groups<[1,2]>, Arg<"Boolean">, Desc<"If true, simple fix-it hints will be " "automatically applied to the expression.">; def expression_options_description_verbosity : Option<"description-verbosity", "v">, Group<1>, @@ -386,6 +386,11 @@ let Command = "expression" in { Arg<"Boolean">, Desc<"Controls whether the expression can fall back to being JITted if it's " "not supported by the interpreter (defaults to true).">; + def persistent_result : Option<"persistent-result", "\\x01">, Groups<[1,2]>, + Arg<"Boolean">, + Desc<"Persist expression result in a variable for subsequent use. " + "Expression results will be labeled with $-prefixed variables, e.g. $0, " + "$1, etc. Defaults to true.">; } let Command = "frame diag" in { @@ -799,6 +804,9 @@ let Command = "script add" in { EnumArg<"ScriptedCommandSynchronicity">, Desc<"Set the synchronicity of this command's executions with regard to " "LLDB event system.">; + def completion_type : Option<"completion-type", "C">, + EnumArg<"CompletionType">, + Desc<"Specify which completion type the command should use - if none is specified, the command won't use auto-completion.">; } let Command = "container add" in { diff --git a/contrib/llvm-project/lldb/source/Core/Address.cpp b/contrib/llvm-project/lldb/source/Core/Address.cpp index 5969cf11d865..189d50fe962a 100644 --- a/contrib/llvm-project/lldb/source/Core/Address.cpp +++ b/contrib/llvm-project/lldb/source/Core/Address.cpp @@ -37,8 +37,8 @@ #include "lldb/Utility/StreamString.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" #include <cstdint> #include <memory> diff --git a/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp b/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp index 8152a57644fa..6ab3b8fcee15 100644 --- a/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp +++ b/contrib/llvm-project/lldb/source/Core/AddressResolverFileLine.cpp @@ -45,24 +45,20 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter, // TODO: Handle SourceLocationSpec column information cu->ResolveSymbolContext(m_src_location_spec, eSymbolContextEverything, sc_list); - uint32_t sc_list_size = sc_list.GetSize(); - for (uint32_t i = 0; i < sc_list_size; i++) { - SymbolContext sc; - if (sc_list.GetContextAtIndex(i, sc)) { - Address line_start = sc.line_entry.range.GetBaseAddress(); - addr_t byte_size = sc.line_entry.range.GetByteSize(); - if (line_start.IsValid()) { - AddressRange new_range(line_start, byte_size); - m_address_ranges.push_back(new_range); - } else { - LLDB_LOGF(log, - "error: Unable to resolve address at file address 0x%" PRIx64 - " for %s:%d\n", - line_start.GetFileAddress(), - m_src_location_spec.GetFileSpec().GetFilename().AsCString( - "<Unknown>"), - m_src_location_spec.GetLine().value_or(0)); - } + for (const SymbolContext &sc : sc_list) { + Address line_start = sc.line_entry.range.GetBaseAddress(); + addr_t byte_size = sc.line_entry.range.GetByteSize(); + if (line_start.IsValid()) { + AddressRange new_range(line_start, byte_size); + m_address_ranges.push_back(new_range); + } else { + LLDB_LOGF(log, + "error: Unable to resolve address at file address 0x%" PRIx64 + " for %s:%d\n", + line_start.GetFileAddress(), + m_src_location_spec.GetFileSpec().GetFilename().AsCString( + "<Unknown>"), + m_src_location_spec.GetLine().value_or(0)); } } return Searcher::eCallbackReturnContinue; diff --git a/contrib/llvm-project/lldb/source/Core/CoreProperties.td b/contrib/llvm-project/lldb/source/Core/CoreProperties.td index a4a6213e1447..53bc586905a3 100644 --- a/contrib/llvm-project/lldb/source/Core/CoreProperties.td +++ b/contrib/llvm-project/lldb/source/Core/CoreProperties.td @@ -74,7 +74,7 @@ let Definition = "debugger" in { Global, DefaultEnumValue<"eLanguageTypeUnknown">, Desc<"The language to use for the REPL.">; - def StopDisassemblyCount: Property<"stop-disassembly-count", "SInt64">, + def StopDisassemblyCount: Property<"stop-disassembly-count", "UInt64">, Global, DefaultUnsignedValue<4>, Desc<"The number of disassembly lines to show when displaying a stopped context.">; @@ -87,11 +87,11 @@ let Definition = "debugger" in { Global, DefaultUnsignedValue<32000>, Desc<"The size limit to use when disassembling large functions (default: 32KB).">; - def StopLineCountAfter: Property<"stop-line-count-after", "SInt64">, + def StopLineCountAfter: Property<"stop-line-count-after", "UInt64">, Global, DefaultUnsignedValue<3>, Desc<"The number of sources lines to display that come after the current source line when displaying a stopped context.">; - def StopLineCountBefore: Property<"stop-line-count-before", "SInt64">, + def StopLineCountBefore: Property<"stop-line-count-before", "UInt64">, Global, DefaultUnsignedValue<3>, Desc<"The number of sources lines to display that come before the current source line when displaying a stopped context.">; @@ -135,6 +135,10 @@ let Definition = "debugger" in { Global, DefaultFalse, Desc<"Whether to use an external editor or not.">; + def ExternalEditor: Property<"external-editor", "String">, + Global, + DefaultStringValue<"">, + Desc<"External editor to use when use-external-editor is enabled.">; def UseColor: Property<"use-color", "Boolean">, Global, DefaultTrue, @@ -193,7 +197,7 @@ let Definition = "debugger" in { Desc<"When displaying suggestion in a color-enabled terminal, use the ANSI terminal code specified in this format immediately after the suggestion.">; def DWIMPrintVerbosity: Property<"dwim-print-verbosity", "Enum">, Global, - DefaultEnumValue<"eDWIMPrintVerbosityExpression">, + DefaultEnumValue<"eDWIMPrintVerbosityNone">, EnumValues<"OptionEnumValues(g_dwim_print_verbosities)">, Desc<"The verbosity level used by dwim-print.">; } diff --git a/contrib/llvm-project/lldb/source/Core/Debugger.cpp b/contrib/llvm-project/lldb/source/Core/Debugger.cpp index 8a8a01c70ce6..f54108629185 100644 --- a/contrib/llvm-project/lldb/source/Core/Debugger.cpp +++ b/contrib/llvm-project/lldb/source/Core/Debugger.cpp @@ -44,7 +44,6 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" #include "lldb/Utility/AnsiTerminal.h" -#include "lldb/Utility/Diagnostics.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Listener.h" @@ -100,10 +99,9 @@ static size_t g_debugger_event_thread_stack_bytes = 8 * 1024 * 1024; #pragma mark Static Functions -typedef std::vector<DebuggerSP> DebuggerList; static std::recursive_mutex *g_debugger_list_mutex_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain -static DebuggerList *g_debugger_list_ptr = +static Debugger::DebuggerList *g_debugger_list_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain static llvm::ThreadPool *g_thread_pool = nullptr; @@ -214,7 +212,7 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, TargetSP target_sp; LoadScriptFromSymFile load_script_old_value = eLoadScriptFromSymFileFalse; - if (is_load_script && exe_ctx->GetTargetSP()) { + if (is_load_script && exe_ctx && exe_ctx->GetTargetSP()) { target_sp = exe_ctx->GetTargetSP(); load_script_old_value = target_sp->TargetProperties::GetLoadScriptFromSymbolFile(); @@ -237,8 +235,10 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, // use-color changed. Ping the prompt so it can reset the ansi terminal // codes. SetPrompt(GetPrompt()); - } else if (property_path == g_debugger_properties[ePropertyUseSourceCache].name) { - // use-source-cache changed. Wipe out the cache contents if it was disabled. + } else if (property_path == + g_debugger_properties[ePropertyUseSourceCache].name) { + // use-source-cache changed. Wipe out the cache contents if it was + // disabled. if (!GetUseSourceCache()) { m_source_file_cache.Clear(); } @@ -248,7 +248,7 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, eLoadScriptFromSymFileTrue) { std::list<Status> errors; StreamString feedback_stream; - if (!target_sp->LoadScriptingResources(errors, &feedback_stream)) { + if (!target_sp->LoadScriptingResources(errors, feedback_stream)) { Stream &s = GetErrorStream(); for (auto error : errors) { s.Printf("%s\n", error.AsCString()); @@ -263,47 +263,47 @@ Status Debugger::SetPropertyValue(const ExecutionContext *exe_ctx, } bool Debugger::GetAutoConfirm() const { - const uint32_t idx = ePropertyAutoConfirm; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); + constexpr uint32_t idx = ePropertyAutoConfirm; + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } const FormatEntity::Entry *Debugger::GetDisassemblyFormat() const { - const uint32_t idx = ePropertyDisassemblyFormat; - return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); + constexpr uint32_t idx = ePropertyDisassemblyFormat; + return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx); } const FormatEntity::Entry *Debugger::GetFrameFormat() const { - const uint32_t idx = ePropertyFrameFormat; - return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); + constexpr uint32_t idx = ePropertyFrameFormat; + return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx); } const FormatEntity::Entry *Debugger::GetFrameFormatUnique() const { - const uint32_t idx = ePropertyFrameFormatUnique; - return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); + constexpr uint32_t idx = ePropertyFrameFormatUnique; + return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx); } -uint32_t Debugger::GetStopDisassemblyMaxSize() const { - const uint32_t idx = ePropertyStopDisassemblyMaxSize; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_debugger_properties[idx].default_uint_value); +uint64_t Debugger::GetStopDisassemblyMaxSize() const { + constexpr uint32_t idx = ePropertyStopDisassemblyMaxSize; + return GetPropertyAtIndexAs<uint64_t>( + idx, g_debugger_properties[idx].default_uint_value); } bool Debugger::GetNotifyVoid() const { - const uint32_t idx = ePropertyNotiftVoid; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); + constexpr uint32_t idx = ePropertyNotiftVoid; + return GetPropertyAtIndexAs<uint64_t>( + idx, g_debugger_properties[idx].default_uint_value != 0); } llvm::StringRef Debugger::GetPrompt() const { - const uint32_t idx = ePropertyPrompt; - return m_collection_sp->GetPropertyAtIndexAsString( - nullptr, idx, g_debugger_properties[idx].default_cstr_value); + constexpr uint32_t idx = ePropertyPrompt; + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } void Debugger::SetPrompt(llvm::StringRef p) { - const uint32_t idx = ePropertyPrompt; - m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, p); + constexpr uint32_t idx = ePropertyPrompt; + SetPropertyAtIndex(idx, p); llvm::StringRef new_prompt = GetPrompt(); std::string str = lldb_private::ansi::FormatAnsiTerminalCodes(new_prompt, GetUseColor()); @@ -313,126 +313,136 @@ void Debugger::SetPrompt(llvm::StringRef p) { } const FormatEntity::Entry *Debugger::GetThreadFormat() const { - const uint32_t idx = ePropertyThreadFormat; - return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); + constexpr uint32_t idx = ePropertyThreadFormat; + return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx); } const FormatEntity::Entry *Debugger::GetThreadStopFormat() const { - const uint32_t idx = ePropertyThreadStopFormat; - return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); + constexpr uint32_t idx = ePropertyThreadStopFormat; + return GetPropertyAtIndexAs<const FormatEntity::Entry *>(idx); } lldb::ScriptLanguage Debugger::GetScriptLanguage() const { const uint32_t idx = ePropertyScriptLanguage; - return (lldb::ScriptLanguage)m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<lldb::ScriptLanguage>( + idx, static_cast<lldb::ScriptLanguage>( + g_debugger_properties[idx].default_uint_value)); } bool Debugger::SetScriptLanguage(lldb::ScriptLanguage script_lang) { const uint32_t idx = ePropertyScriptLanguage; - return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, - script_lang); + return SetPropertyAtIndex(idx, script_lang); } lldb::LanguageType Debugger::GetREPLLanguage() const { const uint32_t idx = ePropertyREPLLanguage; - OptionValueLanguage *value = - m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage(nullptr, idx); - if (value) - return value->GetCurrentValue(); - return LanguageType(); + return GetPropertyAtIndexAs<LanguageType>(idx, {}); } bool Debugger::SetREPLLanguage(lldb::LanguageType repl_lang) { const uint32_t idx = ePropertyREPLLanguage; - return m_collection_sp->SetPropertyAtIndexAsLanguage(nullptr, idx, repl_lang); + return SetPropertyAtIndex(idx, repl_lang); } -uint32_t Debugger::GetTerminalWidth() const { +uint64_t Debugger::GetTerminalWidth() const { const uint32_t idx = ePropertyTerminalWidth; - return m_collection_sp->GetPropertyAtIndexAsSInt64( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<int64_t>( + idx, g_debugger_properties[idx].default_uint_value); } -bool Debugger::SetTerminalWidth(uint32_t term_width) { +bool Debugger::SetTerminalWidth(uint64_t term_width) { if (auto handler_sp = m_io_handler_stack.Top()) handler_sp->TerminalSizeChanged(); const uint32_t idx = ePropertyTerminalWidth; - return m_collection_sp->SetPropertyAtIndexAsSInt64(nullptr, idx, term_width); + return SetPropertyAtIndex(idx, term_width); } bool Debugger::GetUseExternalEditor() const { const uint32_t idx = ePropertyUseExternalEditor; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } bool Debugger::SetUseExternalEditor(bool b) { const uint32_t idx = ePropertyUseExternalEditor; - return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + return SetPropertyAtIndex(idx, b); +} + +llvm::StringRef Debugger::GetExternalEditor() const { + const uint32_t idx = ePropertyExternalEditor; + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); +} + +bool Debugger::SetExternalEditor(llvm::StringRef editor) { + const uint32_t idx = ePropertyExternalEditor; + return SetPropertyAtIndex(idx, editor); } bool Debugger::GetUseColor() const { const uint32_t idx = ePropertyUseColor; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } bool Debugger::SetUseColor(bool b) { const uint32_t idx = ePropertyUseColor; - bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + bool ret = SetPropertyAtIndex(idx, b); SetPrompt(GetPrompt()); 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); + return GetPropertyAtIndexAs<bool>( + 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); + return SetPropertyAtIndex(idx, show_progress); } llvm::StringRef Debugger::GetShowProgressAnsiPrefix() const { const uint32_t idx = ePropertyShowProgressAnsiPrefix; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } llvm::StringRef Debugger::GetShowProgressAnsiSuffix() const { const uint32_t idx = ePropertyShowProgressAnsiSuffix; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } bool Debugger::GetUseAutosuggestion() const { const uint32_t idx = ePropertyShowAutosuggestion; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + 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, ""); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } llvm::StringRef Debugger::GetAutosuggestionAnsiSuffix() const { const uint32_t idx = ePropertyShowAutosuggestionAnsiSuffix; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } bool Debugger::GetUseSourceCache() const { const uint32_t idx = ePropertyUseSourceCache; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_debugger_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } bool Debugger::SetUseSourceCache(bool b) { const uint32_t idx = ePropertyUseSourceCache; - bool ret = m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + bool ret = SetPropertyAtIndex(idx, b); if (!ret) { m_source_file_cache.Clear(); } @@ -440,102 +450,111 @@ bool Debugger::SetUseSourceCache(bool b) { } bool Debugger::GetHighlightSource() const { const uint32_t idx = ePropertyHighlightSource; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } StopShowColumn Debugger::GetStopShowColumn() const { const uint32_t idx = ePropertyStopShowColumn; - return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<lldb::StopShowColumn>( + idx, static_cast<lldb::StopShowColumn>( + g_debugger_properties[idx].default_uint_value)); } llvm::StringRef Debugger::GetStopShowColumnAnsiPrefix() const { const uint32_t idx = ePropertyStopShowColumnAnsiPrefix; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const { const uint32_t idx = ePropertyStopShowColumnAnsiSuffix; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } llvm::StringRef Debugger::GetStopShowLineMarkerAnsiPrefix() const { const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } llvm::StringRef Debugger::GetStopShowLineMarkerAnsiSuffix() const { const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_debugger_properties[idx].default_cstr_value); } -uint32_t Debugger::GetStopSourceLineCount(bool before) const { +uint64_t Debugger::GetStopSourceLineCount(bool before) const { const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; - return m_collection_sp->GetPropertyAtIndexAsSInt64( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_debugger_properties[idx].default_uint_value); } Debugger::StopDisassemblyType Debugger::GetStopDisassemblyDisplay() const { const uint32_t idx = ePropertyStopDisassemblyDisplay; - return (Debugger::StopDisassemblyType) - m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<Debugger::StopDisassemblyType>( + idx, static_cast<Debugger::StopDisassemblyType>( + g_debugger_properties[idx].default_uint_value)); } -uint32_t Debugger::GetDisassemblyLineCount() const { +uint64_t Debugger::GetDisassemblyLineCount() const { const uint32_t idx = ePropertyStopDisassemblyCount; - return m_collection_sp->GetPropertyAtIndexAsSInt64( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_debugger_properties[idx].default_uint_value); } bool Debugger::GetAutoOneLineSummaries() const { const uint32_t idx = ePropertyAutoOneLineSummaries; - return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } bool Debugger::GetEscapeNonPrintables() const { const uint32_t idx = ePropertyEscapeNonPrintables; - return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } bool Debugger::GetAutoIndent() const { const uint32_t idx = ePropertyAutoIndent; - return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } bool Debugger::SetAutoIndent(bool b) { const uint32_t idx = ePropertyAutoIndent; - return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + return SetPropertyAtIndex(idx, b); } bool Debugger::GetPrintDecls() const { const uint32_t idx = ePropertyPrintDecls; - return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); + return GetPropertyAtIndexAs<bool>( + idx, g_debugger_properties[idx].default_uint_value != 0); } bool Debugger::SetPrintDecls(bool b) { const uint32_t idx = ePropertyPrintDecls; - return m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + return SetPropertyAtIndex(idx, b); } -uint32_t Debugger::GetTabSize() const { +uint64_t Debugger::GetTabSize() const { const uint32_t idx = ePropertyTabSize; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_debugger_properties[idx].default_uint_value); } -bool Debugger::SetTabSize(uint32_t tab_size) { +bool Debugger::SetTabSize(uint64_t tab_size) { const uint32_t idx = ePropertyTabSize; - return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, tab_size); + return SetPropertyAtIndex(idx, tab_size); } lldb::DWIMPrintVerbosity Debugger::GetDWIMPrintVerbosity() const { const uint32_t idx = ePropertyDWIMPrintVerbosity; - return (lldb::DWIMPrintVerbosity) - m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_debugger_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<lldb::DWIMPrintVerbosity>( + idx, static_cast<lldb::DWIMPrintVerbosity>( + g_debugger_properties[idx].default_uint_value)); } #pragma mark Debugger @@ -560,6 +579,12 @@ void Debugger::Terminate() { assert(g_debugger_list_ptr && "Debugger::Terminate called without a matching Debugger::Initialize!"); + 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) + debugger->HandleDestroyCallback(); + } + if (g_thread_pool) { // The destructor will wait for all the threads to complete. delete g_thread_pool; @@ -602,8 +627,8 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) { Status error; - static ConstString g_dylibext(".dylib"); - static ConstString g_solibext(".so"); + static constexpr llvm::StringLiteral g_dylibext(".dylib"); + static constexpr llvm::StringLiteral g_solibext(".so"); if (!baton) return FileSystem::eEnumerateDirectoryResultQuit; @@ -679,10 +704,18 @@ DebuggerSP Debugger::CreateInstance(lldb::LogOutputCallback log_callback, return debugger_sp; } +void Debugger::HandleDestroyCallback() { + if (m_destroy_callback) { + m_destroy_callback(GetID(), m_destroy_callback_baton); + m_destroy_callback = nullptr; + } +} + void Debugger::Destroy(DebuggerSP &debugger_sp) { if (!debugger_sp) return; + debugger_sp->HandleDestroyCallback(); CommandInterpreter &cmd_interpreter = debugger_sp->GetCommandInterpreter(); if (cmd_interpreter.GetSaveSessionOnQuit()) { @@ -708,19 +741,20 @@ void Debugger::Destroy(DebuggerSP &debugger_sp) { } } -DebuggerSP Debugger::FindDebuggerWithInstanceName(ConstString instance_name) { - DebuggerSP debugger_sp; - if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { - std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); - DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); - for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) { - if ((*pos)->m_instance_name == instance_name) { - debugger_sp = *pos; - break; - } - } +DebuggerSP +Debugger::FindDebuggerWithInstanceName(llvm::StringRef instance_name) { + if (!g_debugger_list_ptr || !g_debugger_list_mutex_ptr) + return DebuggerSP(); + + std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); + for (const DebuggerSP &debugger_sp : *g_debugger_list_ptr) { + if (!debugger_sp) + continue; + + if (llvm::StringRef(debugger_sp->GetInstanceName()) == instance_name) + return debugger_sp; } - return debugger_sp; + return DebuggerSP(); } TargetSP Debugger::FindTargetWithProcessID(lldb::pid_t pid) { @@ -769,13 +803,31 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) m_source_manager_up(), m_source_file_cache(), m_command_interpreter_up( std::make_unique<CommandInterpreter>(*this, false)), - m_io_handler_stack(), m_instance_name(), m_loaded_plugins(), - m_event_handler_thread(), m_io_handler_thread(), + m_io_handler_stack(), + m_instance_name(llvm::formatv("debugger_{0}", GetID()).str()), + m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(), m_sync_broadcaster(nullptr, "lldb.debugger.sync"), m_broadcaster(m_broadcaster_manager_sp, GetStaticBroadcasterClass().AsCString()), m_forward_listener_sp(), m_clear_once() { - m_instance_name.SetString(llvm::formatv("debugger_{0}", GetID()).str()); + // Initialize the debugger properties as early as possible as other parts of + // LLDB will start querying them during construction. + m_collection_sp->Initialize(g_debugger_properties); + m_collection_sp->AppendProperty( + "target", "Settings specify to debugging targets.", true, + Target::GetGlobalProperties().GetValueProperties()); + m_collection_sp->AppendProperty( + "platform", "Platform settings.", true, + Platform::GetGlobalPlatformProperties().GetValueProperties()); + m_collection_sp->AppendProperty( + "symbols", "Symbol lookup and cache settings.", true, + ModuleList::GetGlobalModuleListProperties().GetValueProperties()); + if (m_command_interpreter_up) { + m_collection_sp->AppendProperty( + "interpreter", + "Settings specify to the debugger's command interpreter.", true, + m_command_interpreter_up->GetValueProperties()); + } if (log_callback) m_callback_handler_sp = std::make_shared<CallbackLogHandler>(log_callback, baton); @@ -797,26 +849,9 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) } assert(m_dummy_target_sp.get() && "Couldn't construct dummy target?"); - m_collection_sp->Initialize(g_debugger_properties); - m_collection_sp->AppendProperty( - ConstString("target"), - ConstString("Settings specify to debugging targets."), true, - Target::GetGlobalProperties().GetValueProperties()); - m_collection_sp->AppendProperty( - ConstString("platform"), ConstString("Platform settings."), true, - Platform::GetGlobalPlatformProperties().GetValueProperties()); - m_collection_sp->AppendProperty( - ConstString("symbols"), ConstString("Symbol lookup and cache settings."), - true, ModuleList::GetGlobalModuleListProperties().GetValueProperties()); - if (m_command_interpreter_up) { - m_collection_sp->AppendProperty( - ConstString("interpreter"), - ConstString("Settings specify to the debugger's command interpreter."), - true, m_command_interpreter_up->GetValueProperties()); - } OptionValueSInt64 *term_width = m_collection_sp->GetPropertyAtIndexAsOptionValueSInt64( - nullptr, ePropertyTerminalWidth); + ePropertyTerminalWidth); term_width->SetMinimumValue(10); term_width->SetMaximumValue(1024); @@ -828,6 +863,22 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) if (!GetOutputFile().GetIsTerminalWithColors()) SetUseColor(false); + if (Diagnostics::Enabled()) { + m_diagnostics_callback_id = Diagnostics::Instance().AddCallback( + [this](const FileSpec &dir) -> llvm::Error { + for (auto &entry : m_stream_handlers) { + llvm::StringRef log_path = entry.first(); + llvm::StringRef file_name = llvm::sys::path::filename(log_path); + FileSpec destination = dir.CopyByAppendingPathComponent(file_name); + std::error_code ec = + llvm::sys::fs::copy_file(log_path, destination.GetPath()); + if (ec) + return llvm::errorCodeToError(ec); + } + return llvm::Error::success(); + }); + } + #if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) // Enabling use of ANSI color codes because LLDB is using them to highlight // text. @@ -866,6 +917,9 @@ void Debugger::Clear() { GetInputFile().Close(); m_command_interpreter_up->Clear(); + + if (Diagnostics::Enabled()) + Diagnostics::Instance().RemoveCallback(m_diagnostics_callback_id); }); } @@ -1074,7 +1128,7 @@ void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { } } -ConstString Debugger::GetTopIOHandlerControlSequence(char ch) { +llvm::StringRef Debugger::GetTopIOHandlerControlSequence(char ch) { return m_io_handler_stack.GetTopIOHandlerControlSequence(ch); } @@ -1198,6 +1252,56 @@ StreamSP Debugger::GetAsyncErrorStream() { return std::make_shared<StreamAsynchronousIO>(*this, false, GetUseColor()); } +void Debugger::RequestInterrupt() { + std::lock_guard<std::mutex> guard(m_interrupt_mutex); + m_interrupt_requested++; +} + +void Debugger::CancelInterruptRequest() { + std::lock_guard<std::mutex> guard(m_interrupt_mutex); + if (m_interrupt_requested > 0) + m_interrupt_requested--; +} + +bool Debugger::InterruptRequested() { + // This is the one we should call internally. This will return true either + // if there's a debugger interrupt and we aren't on the IOHandler thread, + // or if we are on the IOHandler thread and there's a CommandInterpreter + // interrupt. + if (!IsIOHandlerThreadCurrentThread()) { + std::lock_guard<std::mutex> guard(m_interrupt_mutex); + return m_interrupt_requested != 0; + } + return GetCommandInterpreter().WasInterrupted(); +} + +Debugger::InterruptionReport::InterruptionReport(std::string function_name, + const llvm::formatv_object_base &payload) : + m_function_name(std::move(function_name)), + m_interrupt_time(std::chrono::system_clock::now()), + m_thread_id(llvm::get_threadid()) { + llvm::raw_string_ostream desc(m_description); + desc << payload << "\n"; +} + +void Debugger::ReportInterruption(const InterruptionReport &report) { + // For now, just log the description: + Log *log = GetLog(LLDBLog::Host); + LLDB_LOG(log, "Interruption: {0}", report.m_description); +} + +Debugger::DebuggerList Debugger::DebuggersRequestingInterruption() { + DebuggerList result; + if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { + std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); + for (auto debugger_sp : *g_debugger_list_ptr) { + if (debugger_sp->InterruptRequested()) + result.push_back(debugger_sp); + } + } + return result; +} + size_t Debugger::GetNumDebuggers() { if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); @@ -1276,6 +1380,13 @@ bool Debugger::FormatDisassemblerAddress(const FormatEntity::Entry *format, function_changed, initial_function); } +void Debugger::AssertCallback(llvm::StringRef message, + llvm::StringRef backtrace, + llvm::StringRef prompt) { + Debugger::ReportError( + llvm::formatv("{0}\n{1}{2}", message, backtrace, prompt).str()); +} + void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, void *baton) { // For simplicity's sake, I am not going to deal with how to close down any @@ -1285,8 +1396,14 @@ void Debugger::SetLoggingCallback(lldb::LogOutputCallback log_callback, std::make_shared<CallbackLogHandler>(log_callback, baton); } +void Debugger::SetDestroyCallback( + lldb_private::DebuggerDestroyCallback destroy_callback, void *baton) { + m_destroy_callback = destroy_callback; + m_destroy_callback_baton = baton; +} + static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id, - const std::string &message, + std::string title, std::string details, uint64_t completed, uint64_t total, bool is_debugger_specific) { // Only deliver progress events if we have any progress listeners. @@ -1294,13 +1411,15 @@ static void PrivateReportProgress(Debugger &debugger, uint64_t progress_id, if (!debugger.GetBroadcaster().EventTypeHasListeners(event_type)) return; EventSP event_sp(new Event( - event_type, new ProgressEventData(progress_id, message, completed, total, - is_debugger_specific))); + event_type, + new ProgressEventData(progress_id, std::move(title), std::move(details), + completed, total, is_debugger_specific))); debugger.GetBroadcaster().BroadcastEvent(event_sp); } -void Debugger::ReportProgress(uint64_t progress_id, const std::string &message, - uint64_t completed, uint64_t total, +void Debugger::ReportProgress(uint64_t progress_id, std::string title, + std::string details, uint64_t completed, + uint64_t total, std::optional<lldb::user_id_t> debugger_id) { // Check if this progress is for a specific debugger. if (debugger_id) { @@ -1308,8 +1427,9 @@ void Debugger::ReportProgress(uint64_t progress_id, const std::string &message, // still exists. DebuggerSP debugger_sp = FindDebuggerWithID(*debugger_id); if (debugger_sp) - PrivateReportProgress(*debugger_sp, progress_id, message, completed, - total, /*is_debugger_specific*/ true); + PrivateReportProgress(*debugger_sp, progress_id, std::move(title), + std::move(details), completed, total, + /*is_debugger_specific*/ true); return; } // The progress event is not debugger specific, iterate over all debuggers @@ -1318,8 +1438,8 @@ void Debugger::ReportProgress(uint64_t progress_id, const std::string &message, std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); DebuggerList::iterator pos, end = g_debugger_list_ptr->end(); for (pos = g_debugger_list_ptr->begin(); pos != end; ++pos) - PrivateReportProgress(*(*pos), progress_id, message, completed, total, - /*is_debugger_specific*/ false); + PrivateReportProgress(*(*pos), progress_id, title, details, completed, + total, /*is_debugger_specific*/ false); } } @@ -1615,7 +1735,10 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) { // Display running state changes first before any STDIO if (got_state_changed && !state_is_stopped) { + // This is a public stop which we are going to announce to the user, so + // we should force the most relevant frame selection here. Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), + SelectMostRelevantFrame, pop_process_io_handler); } @@ -1655,6 +1778,7 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) { // Now display any stopped state changes after any STDIO if (got_state_changed && state_is_stopped) { Process::HandleProcessStateChangedEvent(event_sp, output_stream_sp.get(), + SelectMostRelevantFrame, pop_process_io_handler); } @@ -1817,8 +1941,8 @@ bool Debugger::StartEventHandlerThread() { if (event_handler_thread) { m_event_handler_thread = *event_handler_thread; } else { - LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", - llvm::toString(event_handler_thread.takeError())); + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), event_handler_thread.takeError(), + "failed to launch host thread: {0}"); } // Make sure DefaultEventHandler() is running and listening to events @@ -1940,7 +2064,15 @@ void Debugger::HandleDiagnosticEvent(const lldb::EventSP &event_sp) { data->Dump(stream.get()); } -bool Debugger::HasIOHandlerThread() { return m_io_handler_thread.IsJoinable(); } +bool Debugger::HasIOHandlerThread() const { + return m_io_handler_thread.IsJoinable(); +} + +HostThread Debugger::SetIOHandlerThread(HostThread &new_thread) { + HostThread old_host = m_io_handler_thread; + m_io_handler_thread = new_thread; + return old_host; +} bool Debugger::StartIOHandlerThread() { if (!m_io_handler_thread.IsJoinable()) { @@ -1950,8 +2082,8 @@ bool Debugger::StartIOHandlerThread() { if (io_handler_thread) { m_io_handler_thread = *io_handler_thread; } else { - LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", - llvm::toString(io_handler_thread.takeError())); + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), io_handler_thread.takeError(), + "failed to launch host thread: {0}"); } } return m_io_handler_thread.IsJoinable(); @@ -1972,6 +2104,12 @@ void Debugger::JoinIOHandlerThread() { } } +bool Debugger::IsIOHandlerThreadCurrentThread() const { + if (!HasIOHandlerThread()) + return false; + return m_io_handler_thread.EqualsThread(Host::GetCurrentThread()); +} + Target &Debugger::GetSelectedOrDummyTarget(bool prefer_dummy) { if (!prefer_dummy) { if (TargetSP target = m_target_list.GetSelectedTarget()) diff --git a/contrib/llvm-project/lldb/source/Core/DebuggerEvents.cpp b/contrib/llvm-project/lldb/source/Core/DebuggerEvents.cpp index 6b33af9e0ee1..dd77fff349a6 100644 --- a/contrib/llvm-project/lldb/source/Core/DebuggerEvents.cpp +++ b/contrib/llvm-project/lldb/source/Core/DebuggerEvents.cpp @@ -23,17 +23,18 @@ static const T *GetEventDataFromEventImpl(const Event *event_ptr) { return nullptr; } -ConstString ProgressEventData::GetFlavorString() { - static ConstString g_flavor("ProgressEventData"); - return g_flavor; +llvm::StringRef ProgressEventData::GetFlavorString() { + return "ProgressEventData"; } -ConstString ProgressEventData::GetFlavor() const { +llvm::StringRef ProgressEventData::GetFlavor() const { return ProgressEventData::GetFlavorString(); } void ProgressEventData::Dump(Stream *s) const { - s->Printf(" id = %" PRIu64 ", message = \"%s\"", m_id, m_message.c_str()); + s->Printf(" id = %" PRIu64 ", title = \"%s\"", m_id, m_title.c_str()); + if (!m_details.empty()) + s->Printf(", details = \"%s\"", m_details.c_str()); if (m_completed == 0 || m_completed == m_total) s->Printf(", type = %s", m_completed == 0 ? "start" : "end"); else @@ -49,6 +50,27 @@ ProgressEventData::GetEventDataFromEvent(const Event *event_ptr) { return GetEventDataFromEventImpl<ProgressEventData>(event_ptr); } +StructuredData::DictionarySP +ProgressEventData::GetAsStructuredData(const Event *event_ptr) { + const ProgressEventData *progress_data = + ProgressEventData::GetEventDataFromEvent(event_ptr); + + if (!progress_data) + return {}; + + auto dictionary_sp = std::make_shared<StructuredData::Dictionary>(); + dictionary_sp->AddStringItem("title", progress_data->GetTitle()); + dictionary_sp->AddStringItem("details", progress_data->GetDetails()); + dictionary_sp->AddStringItem("message", progress_data->GetMessage()); + dictionary_sp->AddIntegerItem("progress_id", progress_data->GetID()); + dictionary_sp->AddIntegerItem("completed", progress_data->GetCompleted()); + dictionary_sp->AddIntegerItem("total", progress_data->GetTotal()); + dictionary_sp->AddBooleanItem("debugger_specific", + progress_data->IsDebuggerSpecific()); + + return dictionary_sp; +} + llvm::StringRef DiagnosticEventData::GetPrefix() const { switch (m_type) { case Type::Info: @@ -71,12 +93,11 @@ void DiagnosticEventData::Dump(Stream *s) const { s->Flush(); } -ConstString DiagnosticEventData::GetFlavorString() { - static ConstString g_flavor("DiagnosticEventData"); - return g_flavor; +llvm::StringRef DiagnosticEventData::GetFlavorString() { + return "DiagnosticEventData"; } -ConstString DiagnosticEventData::GetFlavor() const { +llvm::StringRef DiagnosticEventData::GetFlavor() const { return DiagnosticEventData::GetFlavorString(); } @@ -85,12 +106,27 @@ DiagnosticEventData::GetEventDataFromEvent(const Event *event_ptr) { return GetEventDataFromEventImpl<DiagnosticEventData>(event_ptr); } -ConstString SymbolChangeEventData::GetFlavorString() { - static ConstString g_flavor("SymbolChangeEventData"); - return g_flavor; +StructuredData::DictionarySP +DiagnosticEventData::GetAsStructuredData(const Event *event_ptr) { + const DiagnosticEventData *diagnostic_data = + DiagnosticEventData::GetEventDataFromEvent(event_ptr); + + if (!diagnostic_data) + return {}; + + auto dictionary_sp = std::make_shared<StructuredData::Dictionary>(); + dictionary_sp->AddStringItem("message", diagnostic_data->GetMessage()); + dictionary_sp->AddStringItem("type", diagnostic_data->GetPrefix()); + dictionary_sp->AddBooleanItem("debugger_specific", + diagnostic_data->IsDebuggerSpecific()); + return dictionary_sp; +} + +llvm::StringRef SymbolChangeEventData::GetFlavorString() { + return "SymbolChangeEventData"; } -ConstString SymbolChangeEventData::GetFlavor() const { +llvm::StringRef SymbolChangeEventData::GetFlavor() const { return SymbolChangeEventData::GetFlavorString(); } diff --git a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp index cc354636987c..104e9100e388 100644 --- a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp +++ b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp @@ -41,8 +41,8 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-private-interfaces.h" #include "lldb/lldb-private-types.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" #include <cstdint> #include <cstring> @@ -67,20 +67,16 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName(plugin_name); if (create_callback) { - DisassemblerSP disassembler_sp(create_callback(arch, flavor)); - - if (disassembler_sp) - return disassembler_sp; + if (auto disasm_sp = create_callback(arch, flavor)) + return disasm_sp; } } else { for (uint32_t idx = 0; (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex( idx)) != nullptr; ++idx) { - DisassemblerSP disassembler_sp(create_callback(arch, flavor)); - - if (disassembler_sp) - return disassembler_sp; + if (auto disasm_sp = create_callback(arch, flavor)) + return disasm_sp; } } return DisassemblerSP(); @@ -243,7 +239,7 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine( // Skip any line #0 entries - they are implementation details if (line.line == 0) - return false; + return true; ThreadSP thread_sp = exe_ctx.GetThreadSP(); if (thread_sp) { @@ -253,7 +249,7 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine( if (target_sp) { Status error; OptionValueSP value_sp = target_sp->GetDebugger().GetPropertyValue( - &exe_ctx, "target.process.thread.step-avoid-regexp", false, error); + &exe_ctx, "target.process.thread.step-avoid-regexp", error); if (value_sp && value_sp->GetType() == OptionValue::eTypeRegex) { OptionValueRegex *re = value_sp->GetAsRegex(); if (re) { @@ -691,7 +687,7 @@ bool Instruction::HasDelaySlot() { return false; } -OptionValueSP Instruction::ReadArray(FILE *in_file, Stream *out_stream, +OptionValueSP Instruction::ReadArray(FILE *in_file, Stream &out_stream, OptionValue::Type data_type) { bool done = false; char buffer[1024]; @@ -701,7 +697,7 @@ OptionValueSP Instruction::ReadArray(FILE *in_file, Stream *out_stream, int idx = 0; while (!done) { if (!fgets(buffer, 1023, in_file)) { - out_stream->Printf( + out_stream.Printf( "Instruction::ReadArray: Error reading file (fgets).\n"); option_value_sp.reset(); return option_value_sp; @@ -750,18 +746,18 @@ OptionValueSP Instruction::ReadArray(FILE *in_file, Stream *out_stream, return option_value_sp; } -OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) { +OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream &out_stream) { bool done = false; char buffer[1024]; auto option_value_sp = std::make_shared<OptionValueDictionary>(); - static ConstString encoding_key("data_encoding"); + static constexpr llvm::StringLiteral encoding_key("data_encoding"); OptionValue::Type data_type = OptionValue::eTypeInvalid; while (!done) { // Read the next line in the file if (!fgets(buffer, 1023, in_file)) { - out_stream->Printf( + out_stream.Printf( "Instruction::ReadDictionary: Error reading file (fgets).\n"); option_value_sp.reset(); return option_value_sp; @@ -796,13 +792,12 @@ OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) { key = matches[1].str(); value = matches[2].str(); } else { - out_stream->Printf("Instruction::ReadDictionary: Failure executing " - "regular expression.\n"); + out_stream.Printf("Instruction::ReadDictionary: Failure executing " + "regular expression.\n"); option_value_sp.reset(); return option_value_sp; } - ConstString const_key(key.c_str()); // Check value to see if it's the start of an array or dictionary. lldb::OptionValueSP value_sp; @@ -838,15 +833,14 @@ OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) { value_sp = std::make_shared<OptionValueString>(value.c_str(), ""); } - if (const_key == encoding_key) { + if (key == encoding_key) { // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data - // indicating the - // data type of an upcoming array (usually the next bit of data to be - // read in). - if (strcmp(value.c_str(), "uint32_t") == 0) + // indicating the data type of an upcoming array (usually the next bit + // of data to be read in). + if (llvm::StringRef(value) == "uint32_t") data_type = OptionValue::eTypeUInt64; } else - option_value_sp->GetAsDictionary()->SetValueForKey(const_key, value_sp, + option_value_sp->GetAsDictionary()->SetValueForKey(key, value_sp, false); } } @@ -854,32 +848,29 @@ OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) { return option_value_sp; } -bool Instruction::TestEmulation(Stream *out_stream, const char *file_name) { - if (!out_stream) - return false; - +bool Instruction::TestEmulation(Stream &out_stream, const char *file_name) { if (!file_name) { - out_stream->Printf("Instruction::TestEmulation: Missing file_name."); + out_stream.Printf("Instruction::TestEmulation: Missing file_name."); return false; } FILE *test_file = FileSystem::Instance().Fopen(file_name, "r"); if (!test_file) { - out_stream->Printf( + out_stream.Printf( "Instruction::TestEmulation: Attempt to open test file failed."); return false; } char buffer[256]; if (!fgets(buffer, 255, test_file)) { - out_stream->Printf( + out_stream.Printf( "Instruction::TestEmulation: Error reading first line of test file.\n"); fclose(test_file); return false; } if (strncmp(buffer, "InstructionEmulationState={", 27) != 0) { - out_stream->Printf("Instructin::TestEmulation: Test file does not contain " - "emulation state dictionary\n"); + out_stream.Printf("Instructin::TestEmulation: Test file does not contain " + "emulation state dictionary\n"); fclose(test_file); return false; } @@ -889,7 +880,7 @@ bool Instruction::TestEmulation(Stream *out_stream, const char *file_name) { OptionValueSP data_dictionary_sp(ReadDictionary(test_file, out_stream)); if (!data_dictionary_sp) { - out_stream->Printf( + out_stream.Printf( "Instruction::TestEmulation: Error reading Dictionary Object.\n"); fclose(test_file); return false; @@ -899,28 +890,29 @@ bool Instruction::TestEmulation(Stream *out_stream, const char *file_name) { OptionValueDictionary *data_dictionary = data_dictionary_sp->GetAsDictionary(); - static ConstString description_key("assembly_string"); - static ConstString triple_key("triple"); + static constexpr llvm::StringLiteral description_key("assembly_string"); + static constexpr llvm::StringLiteral triple_key("triple"); OptionValueSP value_sp = data_dictionary->GetValueForKey(description_key); if (!value_sp) { - out_stream->Printf("Instruction::TestEmulation: Test file does not " - "contain description string.\n"); + out_stream.Printf("Instruction::TestEmulation: Test file does not " + "contain description string.\n"); return false; } - SetDescription(value_sp->GetStringValue()); + SetDescription(value_sp->GetValueAs<llvm::StringRef>().value_or("")); value_sp = data_dictionary->GetValueForKey(triple_key); if (!value_sp) { - out_stream->Printf( + out_stream.Printf( "Instruction::TestEmulation: Test file does not contain triple.\n"); return false; } ArchSpec arch; - arch.SetTriple(llvm::Triple(value_sp->GetStringValue())); + arch.SetTriple( + llvm::Triple(value_sp->GetValueAs<llvm::StringRef>().value_or(""))); bool success = false; std::unique_ptr<EmulateInstruction> insn_emulator_up( @@ -930,9 +922,9 @@ bool Instruction::TestEmulation(Stream *out_stream, const char *file_name) { insn_emulator_up->TestEmulation(out_stream, arch, data_dictionary); if (success) - out_stream->Printf("Emulation test succeeded."); + out_stream.Printf("Emulation test succeeded."); else - out_stream->Printf("Emulation test failed."); + out_stream.Printf("Emulation test failed."); return success; } diff --git a/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp b/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp index 7f6108f40c59..cb76b118325b 100644 --- a/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Core/DumpDataExtractor.cpp @@ -212,7 +212,7 @@ static void DumpCharacter(Stream &s, const char c) { s.PutChar(c); return; } - s.Printf("\\x%2.2x", c); + s.Printf("\\x%2.2hhx", c); } /// Dump a floating point type. diff --git a/contrib/llvm-project/lldb/source/Core/DumpRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Core/DumpRegisterInfo.cpp new file mode 100644 index 000000000000..833479541690 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Core/DumpRegisterInfo.cpp @@ -0,0 +1,116 @@ +//===-- DumpRegisterInfo.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/DumpRegisterInfo.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/RegisterFlags.h" +#include "lldb/Utility/Stream.h" + +using namespace lldb; +using namespace lldb_private; + +using SetInfo = std::pair<const char *, uint32_t>; + +void lldb_private::DumpRegisterInfo(Stream &strm, RegisterContext &ctx, + const RegisterInfo &info, + uint32_t terminal_width) { + std::vector<const char *> invalidates; + if (info.invalidate_regs) { + for (uint32_t *inv_regs = info.invalidate_regs; + *inv_regs != LLDB_INVALID_REGNUM; ++inv_regs) { + const RegisterInfo *inv_info = + ctx.GetRegisterInfo(lldb::eRegisterKindLLDB, *inv_regs); + assert( + inv_info && + "Register invalidate list refers to a register that does not exist."); + invalidates.push_back(inv_info->name); + } + } + + // We include the index here so that you can use it with "register read -s". + std::vector<SetInfo> in_sets; + for (uint32_t set_idx = 0; set_idx < ctx.GetRegisterSetCount(); ++set_idx) { + const RegisterSet *set = ctx.GetRegisterSet(set_idx); + assert(set && "Register set should be valid."); + for (uint32_t reg_idx = 0; reg_idx < set->num_registers; ++reg_idx) { + const RegisterInfo *set_reg_info = + ctx.GetRegisterInfoAtIndex(set->registers[reg_idx]); + assert(set_reg_info && "Register info should be valid."); + + if (set_reg_info == &info) { + in_sets.push_back({set->name, set_idx}); + break; + } + } + } + + std::vector<const char *> read_from; + if (info.value_regs) { + for (uint32_t *read_regs = info.value_regs; + *read_regs != LLDB_INVALID_REGNUM; ++read_regs) { + const RegisterInfo *read_info = + ctx.GetRegisterInfo(lldb::eRegisterKindLLDB, *read_regs); + assert(read_info && "Register value registers list refers to a register " + "that does not exist."); + read_from.push_back(read_info->name); + } + } + + DoDumpRegisterInfo(strm, info.name, info.alt_name, info.byte_size, + invalidates, read_from, in_sets, info.flags_type, + terminal_width); +} + +template <typename ElementType> +static void DumpList(Stream &strm, const char *title, + const std::vector<ElementType> &list, + std::function<void(Stream &, ElementType)> emitter) { + if (list.empty()) + return; + + strm.EOL(); + strm << title; + bool first = true; + for (ElementType elem : list) { + if (!first) + strm << ", "; + first = false; + emitter(strm, elem); + } +} + +void lldb_private::DoDumpRegisterInfo( + Stream &strm, const char *name, const char *alt_name, uint32_t byte_size, + const std::vector<const char *> &invalidates, + const std::vector<const char *> &read_from, + const std::vector<SetInfo> &in_sets, const RegisterFlags *flags_type, + uint32_t terminal_width) { + strm << " Name: " << name; + if (alt_name) + strm << " (" << alt_name << ")"; + strm.EOL(); + + // Size in bits may seem obvious for the usual 32 or 64 bit registers. + // When we get to vector registers, then scalable vector registers, it is very + // useful to know without the user doing extra work. + strm.Printf(" Size: %d bytes (%d bits)", byte_size, byte_size * 8); + + std::function<void(Stream &, const char *)> emit_str = + [](Stream &strm, const char *s) { strm << s; }; + DumpList(strm, "Invalidates: ", invalidates, emit_str); + DumpList(strm, " Read from: ", read_from, emit_str); + + std::function<void(Stream &, SetInfo)> emit_set = [](Stream &strm, + SetInfo info) { + strm.Printf("%s (index %d)", info.first, info.second); + }; + DumpList(strm, " In sets: ", in_sets, emit_set); + + if (flags_type) + strm.Printf("\n\n%s", flags_type->AsTable(terminal_width).c_str()); +} diff --git a/contrib/llvm-project/lldb/source/Core/DumpRegisterValue.cpp b/contrib/llvm-project/lldb/source/Core/DumpRegisterValue.cpp index 14659e03f18b..463aa5926772 100644 --- a/contrib/llvm-project/lldb/source/Core/DumpRegisterValue.cpp +++ b/contrib/llvm-project/lldb/source/Core/DumpRegisterValue.cpp @@ -8,19 +8,62 @@ #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/DumpDataExtractor.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/DataFormatters/DumpValueObjectOptions.h" +#include "lldb/Target/RegisterFlags.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-private-types.h" +#include "llvm/ADT/bit.h" using namespace lldb; -void lldb_private::DumpRegisterValue(const RegisterValue ®_val, Stream *s, - const RegisterInfo *reg_info, +template <typename T> +static void dump_type_value(lldb_private::CompilerType &fields_type, T value, + lldb_private::ExecutionContextScope *exe_scope, + const lldb_private::RegisterInfo ®_info, + lldb_private::Stream &strm) { + lldb::ByteOrder target_order = exe_scope->CalculateProcess()->GetByteOrder(); + + // For the bitfield types we generate, it is expected that the fields are + // in what is usually a big endian order. Most significant field first. + // This is also clang's internal ordering and the order we want to print + // them. On a big endian host this all matches up, for a little endian + // host we have to swap the order of the fields before display. + if (target_order == lldb::ByteOrder::eByteOrderLittle) { + value = reg_info.flags_type->ReverseFieldOrder(value); + } + + // Then we need to match the target's endian on a byte level as well. + if (lldb_private::endian::InlHostByteOrder() != target_order) + value = llvm::byteswap(value); + + lldb_private::DataExtractor data_extractor{ + &value, sizeof(T), lldb_private::endian::InlHostByteOrder(), 8}; + + lldb::ValueObjectSP vobj_sp = lldb_private::ValueObjectConstResult::Create( + exe_scope, fields_type, lldb_private::ConstString(), data_extractor); + lldb_private::DumpValueObjectOptions dump_options; + lldb_private::DumpValueObjectOptions::ChildPrintingDecider decider = + [](lldb_private::ConstString varname) { + // Unnamed bit-fields are padding that we don't want to show. + return varname.GetLength(); + }; + dump_options.SetChildPrintingDecider(decider).SetHideRootType(true); + + vobj_sp->Dump(strm, dump_options); +} + +void lldb_private::DumpRegisterValue(const RegisterValue ®_val, Stream &s, + const RegisterInfo ®_info, bool prefix_with_name, bool prefix_with_alt_name, Format format, uint32_t reg_name_right_align_at, - ExecutionContextScope *exe_scope) { + ExecutionContextScope *exe_scope, + bool print_flags, TargetSP target_sp) { DataExtractor data; if (!reg_val.GetData(data)) return; @@ -38,42 +81,93 @@ void lldb_private::DumpRegisterValue(const RegisterValue ®_val, Stream *s, format_string.Printf("%%s"); std::string fmt = std::string(format_string.GetString()); if (prefix_with_name) { - if (reg_info->name) { - s->Printf(fmt.c_str(), reg_info->name); + if (reg_info.name) { + s.Printf(fmt.c_str(), reg_info.name); name_printed = true; - } else if (reg_info->alt_name) { - s->Printf(fmt.c_str(), reg_info->alt_name); + } else if (reg_info.alt_name) { + s.Printf(fmt.c_str(), reg_info.alt_name); prefix_with_alt_name = false; name_printed = true; } } if (prefix_with_alt_name) { if (name_printed) - s->PutChar('/'); - if (reg_info->alt_name) { - s->Printf(fmt.c_str(), reg_info->alt_name); + s.PutChar('/'); + if (reg_info.alt_name) { + s.Printf(fmt.c_str(), reg_info.alt_name); name_printed = true; } else if (!name_printed) { // No alternate name but we were asked to display a name, so show the // main name - s->Printf(fmt.c_str(), reg_info->name); + s.Printf(fmt.c_str(), reg_info.name); name_printed = true; } } if (name_printed) - s->PutCString(" = "); + s.PutCString(" = "); if (format == eFormatDefault) - format = reg_info->format; + format = reg_info.format; - DumpDataExtractor(data, s, + DumpDataExtractor(data, &s, 0, // Offset in "data" format, // Format to use when dumping - reg_info->byte_size, // item_byte_size + reg_info.byte_size, // item_byte_size 1, // item_count UINT32_MAX, // num_per_line LLDB_INVALID_ADDRESS, // base_addr 0, // item_bit_size 0, // item_bit_offset exe_scope); + + if (!print_flags || !reg_info.flags_type || !exe_scope || !target_sp || + (reg_info.byte_size != 4 && reg_info.byte_size != 8)) + return; + + CompilerType fields_type = target_sp->GetRegisterType( + reg_info.name, *reg_info.flags_type, reg_info.byte_size); + + // Use a new stream so we can remove a trailing newline later. + StreamString fields_stream; + + if (reg_info.byte_size == 4) { + dump_type_value(fields_type, reg_val.GetAsUInt32(), exe_scope, reg_info, + fields_stream); + } else { + dump_type_value(fields_type, reg_val.GetAsUInt64(), exe_scope, reg_info, + fields_stream); + } + + // Registers are indented like: + // (lldb) register read foo + // foo = 0x12345678 + // So we need to indent to match that. + + // First drop the extra newline that the value printer added. The register + // command will add one itself. + llvm::StringRef fields_str = fields_stream.GetString().drop_back(); + + // End the line that contains " foo = 0x12345678". + s.EOL(); + + // Then split the value lines and indent each one. + bool first = true; + while (fields_str.size()) { + std::pair<llvm::StringRef, llvm::StringRef> split = fields_str.split('\n'); + fields_str = split.second; + // Indent as far as the register name did. + s.Printf(fmt.c_str(), ""); + + // Lines after the first won't have " = " so compensate for that. + if (!first) + s << " "; + first = false; + + s << split.first; + + // On the last line we don't want a newline because the command will add + // one too. + if (fields_str.size()) + s.EOL(); + } } diff --git a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp index 8849ccedbd48..2e5378f654a5 100644 --- a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp +++ b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp @@ -187,14 +187,13 @@ static ModuleSP ReadUnnamedMemoryModule(Process *process, addr_t addr, ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( Process *process, llvm::StringRef name, UUID uuid, addr_t value, - bool value_is_offset, bool force_symbol_search, bool notify) { + bool value_is_offset, bool force_symbol_search, bool notify, + bool set_address_in_target) { ModuleSP memory_module_sp; ModuleSP module_sp; PlatformSP platform_sp = process->GetTarget().GetPlatform(); Target &target = process->GetTarget(); Status error; - ModuleSpec module_spec; - module_spec.GetUUID() = uuid; if (!uuid.IsValid() && !value_is_offset) { memory_module_sp = ReadUnnamedMemoryModule(process, value, name); @@ -202,23 +201,46 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( if (memory_module_sp) uuid = memory_module_sp->GetUUID(); } + ModuleSpec module_spec; + module_spec.GetUUID() = uuid; + FileSpec name_filespec(name); + if (FileSystem::Instance().Exists(name_filespec)) + module_spec.GetFileSpec() = name_filespec; if (uuid.IsValid()) { - ModuleSpec module_spec; - module_spec.GetUUID() = uuid; - + // Has lldb already seen a module with this UUID? if (!module_sp) - module_sp = target.GetOrCreateModule(module_spec, false, &error); + error = ModuleList::GetSharedModule(module_spec, module_sp, nullptr, + nullptr, nullptr); + + // Can lldb's symbol/executable location schemes + // find an executable and symbol file. + if (!module_sp) { + FileSpecList search_paths = Target::GetDefaultDebugFileSearchPaths(); + module_spec.GetSymbolFileSpec() = + Symbols::LocateExecutableSymbolFile(module_spec, search_paths); + ModuleSpec objfile_module_spec = + Symbols::LocateExecutableObjectFile(module_spec); + module_spec.GetFileSpec() = objfile_module_spec.GetFileSpec(); + if (FileSystem::Instance().Exists(module_spec.GetFileSpec()) && + FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec())) { + module_sp = std::make_shared<Module>(module_spec); + } + } // If we haven't found a binary, or we don't have a SymbolFile, see // if there is an external search tool that can find it. - if (force_symbol_search && - (!module_sp || !module_sp->GetSymbolFileFileSpec())) { - Symbols::DownloadObjectAndSymbolFile(module_spec, error, true); + if (!module_sp || !module_sp->GetSymbolFileFileSpec()) { + Symbols::DownloadObjectAndSymbolFile(module_spec, error, + force_symbol_search); if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { module_sp = std::make_shared<Module>(module_spec); } } + + // If we only found the executable, create a Module based on that. + if (!module_sp && FileSystem::Instance().Exists(module_spec.GetFileSpec())) + module_sp = std::make_shared<Module>(module_spec); } // If we couldn't find the binary anywhere else, as a last resort, @@ -239,25 +261,34 @@ ModuleSP DynamicLoader::LoadBinaryWithUUIDAndAddress( target.GetImages().AppendIfNeeded(module_sp, false); bool changed = false; - if (module_sp->GetObjectFile()) { - if (value != LLDB_INVALID_ADDRESS) { - LLDB_LOGF(log, "Loading binary UUID %s at %s 0x%" PRIx64, - uuid.GetAsString().c_str(), - value_is_offset ? "offset" : "address", value); - module_sp->SetLoadAddress(target, value, value_is_offset, changed); + if (set_address_in_target) { + if (module_sp->GetObjectFile()) { + if (value != LLDB_INVALID_ADDRESS) { + LLDB_LOGF(log, + "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading " + "binary UUID %s at %s 0x%" PRIx64, + uuid.GetAsString().c_str(), + value_is_offset ? "offset" : "address", value); + module_sp->SetLoadAddress(target, value, value_is_offset, changed); + } else { + // No address/offset/slide, load the binary at file address, + // offset 0. + LLDB_LOGF(log, + "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading " + "binary UUID %s at file address", + uuid.GetAsString().c_str()); + module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, + changed); + } } else { - // No address/offset/slide, load the binary at file address, - // offset 0. - LLDB_LOGF(log, "Loading binary UUID %s at file address", - uuid.GetAsString().c_str()); + // In-memory image, load at its true address, offset 0. + LLDB_LOGF(log, + "DynamicLoader::LoadBinaryWithUUIDAndAddress Loading binary " + "UUID %s from memory at address 0x%" PRIx64, + uuid.GetAsString().c_str(), value); module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, changed); } - } else { - // In-memory image, load at its true address, offset 0. - LLDB_LOGF(log, "Loading binary UUID %s from memory at address 0x%" PRIx64, - uuid.GetAsString().c_str(), value); - module_sp->SetLoadAddress(target, 0, true /* value_is_slide */, changed); } if (notify) { diff --git a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp index ca830ccc04bc..753bee25de6d 100644 --- a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp +++ b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp @@ -363,7 +363,7 @@ bool EmulateInstruction::WriteRegisterDefault(EmulateInstruction *instruction, const RegisterValue ®_value) { StreamFile strm(stdout, false); strm.Printf(" Write to Register (name = %s, value = ", reg_info->name); - DumpRegisterValue(reg_value, &strm, reg_info, false, false, eFormatDefault); + DumpRegisterValue(reg_value, strm, *reg_info, false, false, eFormatDefault); strm.PutCString(", context = "); context.Dump(strm, instruction); strm.EOL(); diff --git a/contrib/llvm-project/lldb/source/Core/FileLineResolver.cpp b/contrib/llvm-project/lldb/source/Core/FileLineResolver.cpp index 2cf7007165bc..7c3cf70572ee 100644 --- a/contrib/llvm-project/lldb/source/Core/FileLineResolver.cpp +++ b/contrib/llvm-project/lldb/source/Core/FileLineResolver.cpp @@ -8,10 +8,10 @@ #include "lldb/Core/FileLineResolver.h" -#include "lldb/Core/FileSpecList.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/Stream.h" #include <string> @@ -48,7 +48,7 @@ FileLineResolver::SearchCallback(SearchFilter &filter, SymbolContext &context, // Match all lines in a file... const bool append = true; while (file_idx != UINT32_MAX) { - line_table->FineLineEntriesForFileIndex(file_idx, append, + line_table->FindLineEntriesForFileIndex(file_idx, append, m_sc_list); // Get the next file index in case we have multiple file entries // for the same file diff --git a/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp b/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp index 4f615a110652..00ab20243855 100644 --- a/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp +++ b/contrib/llvm-project/lldb/source/Core/FormatEntity.cpp @@ -56,8 +56,8 @@ #include "lldb/lldb-forward.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" #include <cctype> #include <cinttypes> @@ -605,7 +605,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, RegisterKind reg_kind, if (reg_info) { RegisterValue reg_value; if (reg_ctx->ReadRegister(reg_info, reg_value)) { - DumpRegisterValue(reg_value, &s, reg_info, false, false, format); + DumpRegisterValue(reg_value, s, *reg_info, false, false, format); return true; } } @@ -985,7 +985,7 @@ static bool DumpRegister(Stream &s, StackFrame *frame, const char *reg_name, if (reg_info) { RegisterValue reg_value; if (reg_ctx->ReadRegister(reg_info, reg_value)) { - DumpRegisterValue(reg_value, &s, reg_info, false, false, format); + DumpRegisterValue(reg_value, s, *reg_info, false, false, format); return true; } } @@ -1008,7 +1008,7 @@ static bool FormatThreadExtendedInfoRecurse( const char *token_format = "0x%4.4" PRIx64; if (!entry.printf_format.empty()) token_format = entry.printf_format.c_str(); - s.Printf(token_format, value->GetAsInteger()->GetValue()); + s.Printf(token_format, value->GetUnsignedIntegerValue()); return true; } else if (value->GetType() == eStructuredDataTypeFloat) { s.Printf("%f", value->GetAsFloat()->GetValue()); diff --git a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp index 95957b6948fc..49f39f2ce492 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp @@ -215,9 +215,9 @@ void IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler, io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion(request); break; case Completion::Expression: - CommandCompletions::InvokeCommonCompletionCallbacks( + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( io_handler.GetDebugger().GetCommandInterpreter(), - CommandCompletions::eVariablePathCompletion, request, nullptr); + lldb::eVariablePathCompletion, request, nullptr); break; } } diff --git a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp index 18d8affd58d8..79d3da63059c 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -3821,7 +3821,7 @@ protected: // This is a searcher delegate wrapper around CommandCompletions common // callbacks. The callbacks are only given the match string. The completion_mask -// can be a combination of CommonCompletionTypes. +// can be a combination of lldb::CompletionType. class CommonCompletionSearcherDelegate : public SearcherDelegate { public: typedef std::function<void(const std::string &)> CallbackType; @@ -3840,7 +3840,7 @@ public: void UpdateMatches(const std::string &text) override { CompletionResult result; CompletionRequest request(text.c_str(), text.size(), result); - CommandCompletions::InvokeCommonCompletionCallbacks( + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( m_debugger.GetCommandInterpreter(), m_completion_mask, request, nullptr); result.GetMatches(m_matches); @@ -3852,7 +3852,7 @@ public: protected: Debugger &m_debugger; - // A compound mask from CommonCompletionTypes. + // A compound mask from lldb::CompletionType. uint32_t m_completion_mask; // A callback to execute once the user selects a match. The match is passed to // the callback as a string. @@ -4522,7 +4522,7 @@ struct Row { if (valobj) { const size_t num_children = valobj->GetNumChildren(); for (size_t i = 0; i < num_children; ++i) { - children.push_back(Row(valobj->GetChildAtIndex(i, true), this)); + children.push_back(Row(valobj->GetChildAtIndex(i), this)); } } } @@ -5259,7 +5259,8 @@ public: for (size_t i = 0; i < num_threads; ++i) { ThreadSP thread = threads.GetThreadAtIndex(i); if (selected_thread->GetID() == thread->GetID()) { - selected_item = &root[i][thread->GetSelectedFrameIndex()]; + selected_item = + &root[i][thread->GetSelectedFrameIndex(SelectMostRelevantFrame)]; selection_index = selected_item->GetRowIndex(); return; } @@ -6411,7 +6412,8 @@ public: if (process && process->IsAlive() && StateIsStoppedState(process->GetState(), true)) { Thread *thread = exe_ctx.GetThreadPtr(); - uint32_t frame_idx = thread->GetSelectedFrameIndex(); + uint32_t frame_idx = + thread->GetSelectedFrameIndex(SelectMostRelevantFrame); exe_ctx.GetThreadRef().StepOut(frame_idx); } } @@ -6827,7 +6829,7 @@ public: if (process_alive) { thread = exe_ctx.GetThreadPtr(); if (thread) { - frame_sp = thread->GetSelectedFrame(); + frame_sp = thread->GetSelectedFrame(SelectMostRelevantFrame); auto tid = thread->GetID(); thread_changed = tid != m_tid; m_tid = tid; @@ -7374,7 +7376,8 @@ public: if (exe_ctx.HasThreadScope() && StateIsStoppedState(exe_ctx.GetProcessRef().GetState(), true)) { Thread *thread = exe_ctx.GetThreadPtr(); - uint32_t frame_idx = thread->GetSelectedFrameIndex(); + uint32_t frame_idx = + thread->GetSelectedFrameIndex(SelectMostRelevantFrame); exe_ctx.GetThreadRef().StepOut(frame_idx); } } @@ -7413,7 +7416,8 @@ public: m_debugger.GetCommandInterpreter().GetExecutionContext(); if (exe_ctx.HasThreadScope()) { Thread *thread = exe_ctx.GetThreadPtr(); - uint32_t frame_idx = thread->GetSelectedFrameIndex(); + uint32_t frame_idx = + thread->GetSelectedFrameIndex(SelectMostRelevantFrame); if (frame_idx == UINT32_MAX) frame_idx = 0; if (c == 'u' && frame_idx + 1 < thread->GetStackFrameCount()) @@ -7421,7 +7425,7 @@ public: else if (c == 'd' && frame_idx > 0) --frame_idx; if (thread->SetSelectedFrameByIndex(frame_idx, true)) - exe_ctx.SetFrameSP(thread->GetSelectedFrame()); + exe_ctx.SetFrameSP(thread->GetSelectedFrame(SelectMostRelevantFrame)); } } return eKeyHandled; diff --git a/contrib/llvm-project/lldb/source/Core/Mangled.cpp b/contrib/llvm-project/lldb/source/Core/Mangled.cpp index 0c4d9f78c440..d1973a9a8f7f 100644 --- a/contrib/llvm-project/lldb/source/Core/Mangled.cpp +++ b/contrib/llvm-project/lldb/source/Core/Mangled.cpp @@ -25,6 +25,7 @@ #include <mutex> #include <string> +#include <string_view> #include <utility> #include <cstdlib> @@ -90,23 +91,6 @@ int Mangled::Compare(const Mangled &a, const Mangled &b) { b.GetName(ePreferMangled)); } -// Set the string value in this objects. If "mangled" is true, then the mangled -// named is set with the new value in "s", else the demangled name is set. -void Mangled::SetValue(ConstString s, bool mangled) { - if (s) { - if (mangled) { - m_demangled.Clear(); - m_mangled = s; - } else { - m_demangled = s; - m_mangled.Clear(); - } - } else { - m_demangled.Clear(); - m_mangled.Clear(); - } -} - void Mangled::SetValue(ConstString name) { if (name) { if (cstring_is_mangled(name.GetStringRef())) { @@ -123,18 +107,18 @@ void Mangled::SetValue(ConstString name) { } // Local helpers for different demangling implementations. -static char *GetMSVCDemangledStr(const char *M) { +static char *GetMSVCDemangledStr(std::string_view M) { char *demangled_cstr = llvm::microsoftDemangle( - M, nullptr, nullptr, nullptr, nullptr, + M, nullptr, nullptr, llvm::MSDemangleFlags( llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention | llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType)); if (Log *log = GetLog(LLDBLog::Demangle)) { if (demangled_cstr && demangled_cstr[0]) - LLDB_LOGF(log, "demangled msvc: %s -> \"%s\"", M, demangled_cstr); + LLDB_LOGF(log, "demangled msvc: %s -> \"%s\"", M.data(), demangled_cstr); else - LLDB_LOGF(log, "demangled msvc: %s -> error", M); + LLDB_LOGF(log, "demangled msvc: %s -> error", M.data()); } return demangled_cstr; @@ -167,7 +151,7 @@ static char *GetItaniumDemangledStr(const char *M) { return demangled_cstr; } -static char *GetRustV0DemangledStr(const char *M) { +static char *GetRustV0DemangledStr(std::string_view M) { char *demangled_cstr = llvm::rustDemangle(M); if (Log *log = GetLog(LLDBLog::Demangle)) { @@ -180,7 +164,7 @@ static char *GetRustV0DemangledStr(const char *M) { return demangled_cstr; } -static char *GetDLangDemangledStr(const char *M) { +static char *GetDLangDemangledStr(std::string_view M) { char *demangled_cstr = llvm::dlangDemangle(M); if (Log *log = GetLog(LLDBLog::Demangle)) { @@ -220,7 +204,7 @@ bool Mangled::GetRichManglingInfo(RichManglingContext &context, // We have no rich mangling for MSVC-mangled names yet, so first try to // demangle it if necessary. if (!m_demangled && !m_mangled.GetMangledCounterpart(m_demangled)) { - if (char *d = GetMSVCDemangledStr(m_mangled.GetCString())) { + if (char *d = GetMSVCDemangledStr(m_mangled)) { // Without the rich mangling info we have to demangle the full name. // Copy it to string pool and connect the counterparts to accelerate // later access in GetDemangledName(). @@ -276,10 +260,10 @@ ConstString Mangled::GetDemangledName() const { break; } case eManglingSchemeRustV0: - demangled_name = GetRustV0DemangledStr(mangled_name); + demangled_name = GetRustV0DemangledStr(m_mangled); break; case eManglingSchemeD: - demangled_name = GetDLangDemangledStr(mangled_name); + demangled_name = GetDLangDemangledStr(m_mangled); break; case eManglingSchemeNone: llvm_unreachable("eManglingSchemeNone was handled already"); diff --git a/contrib/llvm-project/lldb/source/Core/Module.cpp b/contrib/llvm-project/lldb/source/Core/Module.cpp index 8f9defabd76f..672d86496bde 100644 --- a/contrib/llvm-project/lldb/source/Core/Module.cpp +++ b/contrib/llvm-project/lldb/source/Core/Module.cpp @@ -12,7 +12,6 @@ #include "lldb/Core/AddressResolverFileLine.h" #include "lldb/Core/DataFileCache.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/FileSpecList.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/SearchFilter.h" @@ -39,6 +38,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" @@ -748,8 +748,7 @@ bool Module::LookupInfo::NameMatchesLookupInfo( // relatively inexpensive since no demangling is actually occuring. See // Mangled::SetValue for more context. const bool function_name_may_be_mangled = - Mangled::GetManglingScheme(function_name.GetStringRef()) != - Mangled::eManglingSchemeNone; + Mangled::GetManglingScheme(function_name) != Mangled::eManglingSchemeNone; ConstString demangled_function_name = function_name; if (function_name_may_be_mangled) { Mangled mangled_function_name(function_name); @@ -760,11 +759,10 @@ bool Module::LookupInfo::NameMatchesLookupInfo( // Otherwise just check that the demangled function name contains the // demangled user-provided name. if (Language *language = Language::FindPlugin(language_type)) - return language->DemangledNameContainsPath(m_name.GetStringRef(), - demangled_function_name); + return language->DemangledNameContainsPath(m_name, demangled_function_name); - llvm::StringRef function_name_ref = demangled_function_name.GetStringRef(); - return function_name_ref.contains(m_name.GetStringRef()); + llvm::StringRef function_name_ref = demangled_function_name; + return function_name_ref.contains(m_name); } void Module::LookupInfo::Prune(SymbolContextList &sc_list, @@ -803,7 +801,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, CPlusPlusLanguage::MethodName cpp_method(full_name); if (cpp_method.IsValid()) { if (cpp_method.GetContext().empty()) { - if (cpp_method.GetBasename().compare(m_name.GetStringRef()) != 0) { + if (cpp_method.GetBasename().compare(m_name) != 0) { sc_list.RemoveContextAtIndex(i); continue; } @@ -1026,8 +1024,8 @@ void Module::FindTypes( FindTypes_Impl(name, CompilerDeclContext(), UINT_MAX, searched_symbol_files, typesmap); if (exact_match) { - typesmap.RemoveMismatchedTypes(type_scope, name.GetStringRef(), - type_class, exact_match); + typesmap.RemoveMismatchedTypes(type_scope, name, type_class, + exact_match); } } } @@ -1049,10 +1047,38 @@ void Module::FindTypes( symbols->FindTypes(pattern, languages, searched_symbol_files, types); } +static Debugger::DebuggerList +DebuggersOwningModuleRequestingInterruption(Module &module) { + Debugger::DebuggerList requestors + = Debugger::DebuggersRequestingInterruption(); + Debugger::DebuggerList interruptors; + if (requestors.empty()) + return interruptors; + + for (auto debugger_sp : requestors) { + if (!debugger_sp->InterruptRequested()) + continue; + if (debugger_sp->GetTargetList() + .AnyTargetContainsModule(module)) + interruptors.push_back(debugger_sp); + } + return interruptors; +} + SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) { if (!m_did_load_symfile.load()) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_did_load_symfile.load() && can_create) { + Debugger::DebuggerList interruptors + = DebuggersOwningModuleRequestingInterruption(*this); + if (!interruptors.empty()) { + for (auto debugger_sp : interruptors) { + REPORT_INTERRUPTION(*(debugger_sp.get()), + "Interrupted fetching symbols for module {0}", + this->GetFileSpec()); + } + return nullptr; + } ObjectFile *obj_file = GetObjectFile(); if (obj_file != nullptr) { LLDB_SCOPED_TIMER(); @@ -1132,7 +1158,7 @@ void Module::ReportWarningOptimization( return; StreamString ss; - ss << file_name.GetStringRef() + ss << file_name << " was compiled with optimization - stepping may behave " "oddly; variables may not be available."; Debugger::ReportWarning(std::string(ss.GetString()), debugger_id, @@ -1473,7 +1499,7 @@ bool Module::IsLoadedInTarget(Target *target) { } bool Module::LoadScriptingResourceInTarget(Target *target, Status &error, - Stream *feedback_stream) { + Stream &feedback_stream) { if (!target) { error.SetErrorString("invalid destination Target"); return false; @@ -1508,17 +1534,16 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error, if (scripting_fspec && FileSystem::Instance().Exists(scripting_fspec)) { if (should_load == eLoadScriptFromSymFileWarn) { - if (feedback_stream) - feedback_stream->Printf( - "warning: '%s' contains a debug script. To run this script " - "in " - "this debug session:\n\n command script import " - "\"%s\"\n\n" - "To run all discovered debug scripts in this session:\n\n" - " settings set target.load-script-from-symbol-file " - "true\n", - GetFileSpec().GetFileNameStrippingExtension().GetCString(), - scripting_fspec.GetPath().c_str()); + feedback_stream.Printf( + "warning: '%s' contains a debug script. To run this script " + "in " + "this debug session:\n\n command script import " + "\"%s\"\n\n" + "To run all discovered debug scripts in this session:\n\n" + " settings set target.load-script-from-symbol-file " + "true\n", + GetFileSpec().GetFileNameStrippingExtension().GetCString(), + scripting_fspec.GetPath().c_str()); return false; } StreamString scripting_stream; @@ -1609,8 +1634,8 @@ std::optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const { void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) { - XcodeSDK sdk(sdk_name.str()); - auto sdk_path_or_err = HostInfo::GetXcodeSDKPath(sdk); + auto sdk_path_or_err = + HostInfo::GetSDKRoot(HostInfo::SDKOptions{sdk_name.str()}); if (!sdk_path_or_err) { Debugger::ReportError("Error while searching for Xcode SDK: " + @@ -1668,7 +1693,7 @@ uint32_t Module::Hash() { llvm::raw_string_ostream id_strm(identifier); id_strm << m_arch.GetTriple().str() << '-' << m_file.GetPath(); if (m_object_name) - id_strm << '(' << m_object_name.GetStringRef() << ')'; + id_strm << '(' << m_object_name << ')'; if (m_object_offset > 0) id_strm << m_object_offset; const auto mtime = llvm::sys::toTimeT(m_object_mod_time); @@ -1682,7 +1707,7 @@ std::string Module::GetCacheKey() { llvm::raw_string_ostream strm(key); strm << m_arch.GetTriple().str() << '-' << m_file.GetFilename(); if (m_object_name) - strm << '(' << m_object_name.GetStringRef() << ')'; + strm << '(' << m_object_name << ')'; strm << '-' << llvm::format_hex(Hash(), 10); return strm.str(); } diff --git a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp index 5aa58d9bba6b..d0d0b2050e18 100644 --- a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp +++ b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ModuleList.h" -#include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileSystem.h" @@ -22,6 +21,7 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/UUID.h" @@ -97,79 +97,71 @@ ModuleListProperties::ModuleListProperties() { bool ModuleListProperties::GetEnableExternalLookup() const { const uint32_t idx = ePropertyEnableExternalLookup; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_modulelist_properties[idx].default_uint_value != 0); } bool ModuleListProperties::SetEnableExternalLookup(bool new_value) { - return m_collection_sp->SetPropertyAtIndexAsBoolean( - nullptr, ePropertyEnableExternalLookup, new_value); + return SetPropertyAtIndex(ePropertyEnableExternalLookup, new_value); } bool ModuleListProperties::GetEnableBackgroundLookup() const { const uint32_t idx = ePropertyEnableBackgroundLookup; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_modulelist_properties[idx].default_uint_value != 0); } FileSpec ModuleListProperties::GetClangModulesCachePath() const { - return m_collection_sp - ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false, - ePropertyClangModulesCachePath) - ->GetCurrentValue(); + const uint32_t idx = ePropertyClangModulesCachePath; + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } bool ModuleListProperties::SetClangModulesCachePath(const FileSpec &path) { - return m_collection_sp->SetPropertyAtIndexAsFileSpec( - nullptr, ePropertyClangModulesCachePath, path); + const uint32_t idx = ePropertyClangModulesCachePath; + return SetPropertyAtIndex(idx, path); } FileSpec ModuleListProperties::GetLLDBIndexCachePath() const { - return m_collection_sp - ->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false, - ePropertyLLDBIndexCachePath) - ->GetCurrentValue(); + const uint32_t idx = ePropertyLLDBIndexCachePath; + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } bool ModuleListProperties::SetLLDBIndexCachePath(const FileSpec &path) { - return m_collection_sp->SetPropertyAtIndexAsFileSpec( - nullptr, ePropertyLLDBIndexCachePath, path); + const uint32_t idx = ePropertyLLDBIndexCachePath; + return SetPropertyAtIndex(idx, path); } bool ModuleListProperties::GetEnableLLDBIndexCache() const { const uint32_t idx = ePropertyEnableLLDBIndexCache; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_modulelist_properties[idx].default_uint_value != 0); } bool ModuleListProperties::SetEnableLLDBIndexCache(bool new_value) { - return m_collection_sp->SetPropertyAtIndexAsBoolean( - nullptr, ePropertyEnableLLDBIndexCache, new_value); + return SetPropertyAtIndex(ePropertyEnableLLDBIndexCache, new_value); } uint64_t ModuleListProperties::GetLLDBIndexCacheMaxByteSize() { const uint32_t idx = ePropertyLLDBIndexCacheMaxByteSize; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_modulelist_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_modulelist_properties[idx].default_uint_value); } uint64_t ModuleListProperties::GetLLDBIndexCacheMaxPercent() { const uint32_t idx = ePropertyLLDBIndexCacheMaxPercent; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_modulelist_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_modulelist_properties[idx].default_uint_value); } uint64_t ModuleListProperties::GetLLDBIndexCacheExpirationDays() { const uint32_t idx = ePropertyLLDBIndexCacheExpirationDays; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_modulelist_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_modulelist_properties[idx].default_uint_value); } void ModuleListProperties::UpdateSymlinkMappings() { - FileSpecList list = m_collection_sp - ->GetPropertyAtIndexAsOptionValueFileSpecList( - nullptr, false, ePropertySymLinkPaths) - ->GetCurrentValue(); + FileSpecList list = + GetPropertyAtIndexAs<FileSpecList>(ePropertySymLinkPaths, {}); llvm::sys::ScopedWriter lock(m_symlink_paths_mutex); const bool notify = false; m_symlink_paths.Clear(notify); @@ -188,8 +180,8 @@ PathMappingList ModuleListProperties::GetSymlinkMappings() const { bool ModuleListProperties::GetLoadSymbolOnDemand() { const uint32_t idx = ePropertyLoadSymbolOnDemand; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_modulelist_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_modulelist_properties[idx].default_uint_value != 0); } ModuleList::ModuleList() : m_modules(), m_modules_mutex() {} @@ -1036,7 +1028,7 @@ bool ModuleList::RemoveSharedModuleIfOrphaned(const Module *module_ptr) { bool ModuleList::LoadScriptingResourcesInTarget(Target *target, std::list<Status> &errors, - Stream *feedback_stream, + Stream &feedback_stream, bool continue_on_error) { if (!target) return false; diff --git a/contrib/llvm-project/lldb/source/Core/Opcode.cpp b/contrib/llvm-project/lldb/source/Core/Opcode.cpp index a3fc97f95266..3e30d98975d8 100644 --- a/contrib/llvm-project/lldb/source/Core/Opcode.cpp +++ b/contrib/llvm-project/lldb/source/Core/Opcode.cpp @@ -103,7 +103,7 @@ uint32_t Opcode::GetData(DataExtractor &data) const { buf = GetOpcodeDataBytes(); break; case Opcode::eType16: - *(uint16_t *)swap_buf = llvm::ByteSwap_16(m_data.inst16); + *(uint16_t *)swap_buf = llvm::byteswap<uint16_t>(m_data.inst16); buf = swap_buf; break; case Opcode::eType16_2: @@ -114,11 +114,11 @@ uint32_t Opcode::GetData(DataExtractor &data) const { buf = swap_buf; break; case Opcode::eType32: - *(uint32_t *)swap_buf = llvm::ByteSwap_32(m_data.inst32); + *(uint32_t *)swap_buf = llvm::byteswap<uint32_t>(m_data.inst32); buf = swap_buf; break; case Opcode::eType64: - *(uint32_t *)swap_buf = llvm::ByteSwap_64(m_data.inst64); + *(uint32_t *)swap_buf = llvm::byteswap<uint64_t>(m_data.inst64); buf = swap_buf; break; case Opcode::eTypeBytes: diff --git a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp index 05ca0ff1e1ec..ac274112e53d 100644 --- a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp @@ -13,7 +13,6 @@ #include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Target/Process.h" -#include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StringList.h" @@ -875,6 +874,45 @@ void PluginManager::AutoCompleteProcessName(llvm::StringRef name, } } +#pragma mark RegisterTypeBuilder + +struct RegisterTypeBuilderInstance + : public PluginInstance<RegisterTypeBuilderCreateInstance> { + RegisterTypeBuilderInstance(llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback) + : PluginInstance<RegisterTypeBuilderCreateInstance>(name, description, + create_callback) {} +}; + +typedef PluginInstances<RegisterTypeBuilderInstance> + RegisterTypeBuilderInstances; + +static RegisterTypeBuilderInstances &GetRegisterTypeBuilderInstances() { + static RegisterTypeBuilderInstances g_instances; + return g_instances; +} + +bool PluginManager::RegisterPlugin( + llvm::StringRef name, llvm::StringRef description, + RegisterTypeBuilderCreateInstance create_callback) { + return GetRegisterTypeBuilderInstances().RegisterPlugin(name, description, + create_callback); +} + +bool PluginManager::UnregisterPlugin( + RegisterTypeBuilderCreateInstance create_callback) { + return GetRegisterTypeBuilderInstances().UnregisterPlugin(create_callback); +} + +lldb::RegisterTypeBuilderSP +PluginManager::GetRegisterTypeBuilder(Target &target) { + const auto &instances = GetRegisterTypeBuilderInstances().GetInstances(); + // We assume that RegisterTypeBuilderClang is the only instance of this plugin + // type and is always present. + assert(instances.size()); + return instances[0].create_callback(target); +} + #pragma mark ScriptInterpreter struct ScriptInterpreterInstance @@ -1393,21 +1431,22 @@ void PluginManager::DebuggerInitialize(Debugger &debugger) { // This will put a plugin's settings under e.g. // "plugin.<plugin_type_name>.<plugin_type_desc>.SETTINGNAME". static lldb::OptionValuePropertiesSP -GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name, - ConstString plugin_type_desc, bool can_create) { +GetDebuggerPropertyForPlugins(Debugger &debugger, llvm::StringRef plugin_type_name, + llvm::StringRef plugin_type_desc, + bool can_create) { lldb::OptionValuePropertiesSP parent_properties_sp( debugger.GetValueProperties()); if (parent_properties_sp) { - static ConstString g_property_name("plugin"); + static constexpr llvm::StringLiteral g_property_name("plugin"); OptionValuePropertiesSP plugin_properties_sp = parent_properties_sp->GetSubProperty(nullptr, g_property_name); if (!plugin_properties_sp && can_create) { plugin_properties_sp = std::make_shared<OptionValueProperties>(g_property_name); - parent_properties_sp->AppendProperty( - g_property_name, ConstString("Settings specify to plugins."), true, - plugin_properties_sp); + parent_properties_sp->AppendProperty(g_property_name, + "Settings specify to plugins.", true, + plugin_properties_sp); } if (plugin_properties_sp) { @@ -1429,9 +1468,9 @@ GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name, // "<plugin_type_name>.plugin.<plugin_type_desc>.SETTINGNAME" and Platform // generic settings would be under "platform.SETTINGNAME". static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( - Debugger &debugger, ConstString plugin_type_name, - ConstString plugin_type_desc, bool can_create) { - static ConstString g_property_name("plugin"); + Debugger &debugger, llvm::StringRef plugin_type_name, + llvm::StringRef plugin_type_desc, bool can_create) { + static constexpr llvm::StringLiteral g_property_name("plugin"); lldb::OptionValuePropertiesSP parent_properties_sp( debugger.GetValueProperties()); if (parent_properties_sp) { @@ -1450,9 +1489,9 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( if (!plugin_type_properties_sp && can_create) { plugin_type_properties_sp = std::make_shared<OptionValueProperties>(g_property_name); - plugin_properties_sp->AppendProperty( - g_property_name, ConstString("Settings specific to plugins"), true, - plugin_type_properties_sp); + plugin_properties_sp->AppendProperty(g_property_name, + "Settings specific to plugins", + true, plugin_type_properties_sp); } return plugin_type_properties_sp; } @@ -1463,19 +1502,19 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( namespace { typedef lldb::OptionValuePropertiesSP -GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString, +GetDebuggerPropertyForPluginsPtr(Debugger &, llvm::StringRef, llvm::StringRef, bool can_create); } static lldb::OptionValuePropertiesSP -GetSettingForPlugin(Debugger &debugger, ConstString setting_name, - ConstString plugin_type_name, +GetSettingForPlugin(Debugger &debugger, llvm::StringRef setting_name, + llvm::StringRef plugin_type_name, GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins) { lldb::OptionValuePropertiesSP properties_sp; lldb::OptionValuePropertiesSP plugin_type_properties_sp(get_debugger_property( debugger, plugin_type_name, - ConstString(), // not creating to so we don't need the description + "", // not creating to so we don't need the description false)); if (plugin_type_properties_sp) properties_sp = @@ -1484,10 +1523,10 @@ GetSettingForPlugin(Debugger &debugger, ConstString setting_name, } static bool -CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name, - ConstString plugin_type_desc, +CreateSettingForPlugin(Debugger &debugger, llvm::StringRef plugin_type_name, + llvm::StringRef plugin_type_desc, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property, + llvm::StringRef description, bool is_global_property, GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins) { if (properties_sp) { @@ -1504,115 +1543,107 @@ CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name, return false; } -static const char *kDynamicLoaderPluginName("dynamic-loader"); -static const char *kPlatformPluginName("platform"); -static const char *kProcessPluginName("process"); -static const char *kTracePluginName("trace"); -static const char *kObjectFilePluginName("object-file"); -static const char *kSymbolFilePluginName("symbol-file"); -static const char *kJITLoaderPluginName("jit-loader"); -static const char *kStructuredDataPluginName("structured-data"); +static constexpr llvm::StringLiteral kDynamicLoaderPluginName("dynamic-loader"); +static constexpr llvm::StringLiteral kPlatformPluginName("platform"); +static constexpr llvm::StringLiteral kProcessPluginName("process"); +static constexpr llvm::StringLiteral kTracePluginName("trace"); +static constexpr llvm::StringLiteral kObjectFilePluginName("object-file"); +static constexpr llvm::StringLiteral kSymbolFilePluginName("symbol-file"); +static constexpr llvm::StringLiteral kJITLoaderPluginName("jit-loader"); +static constexpr llvm::StringLiteral + kStructuredDataPluginName("structured-data"); lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, - ConstString setting_name) { - return GetSettingForPlugin(debugger, setting_name, - ConstString(kDynamicLoaderPluginName)); + llvm::StringRef setting_name) { + return GetSettingForPlugin(debugger, setting_name, kDynamicLoaderPluginName); } bool PluginManager::CreateSettingForDynamicLoaderPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property) { - return CreateSettingForPlugin( - debugger, ConstString(kDynamicLoaderPluginName), - ConstString("Settings for dynamic loader plug-ins"), properties_sp, - description, is_global_property); + llvm::StringRef description, bool is_global_property) { + return CreateSettingForPlugin(debugger, kDynamicLoaderPluginName, + "Settings for dynamic loader plug-ins", + properties_sp, description, is_global_property); } lldb::OptionValuePropertiesSP PluginManager::GetSettingForPlatformPlugin(Debugger &debugger, - ConstString setting_name) { - return GetSettingForPlugin(debugger, setting_name, - ConstString(kPlatformPluginName), + llvm::StringRef setting_name) { + return GetSettingForPlugin(debugger, setting_name, kPlatformPluginName, GetDebuggerPropertyForPluginsOldStyle); } bool PluginManager::CreateSettingForPlatformPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property) { - return CreateSettingForPlugin(debugger, ConstString(kPlatformPluginName), - ConstString("Settings for platform plug-ins"), - properties_sp, description, is_global_property, + llvm::StringRef description, bool is_global_property) { + return CreateSettingForPlugin(debugger, kPlatformPluginName, + "Settings for platform plug-ins", properties_sp, + description, is_global_property, GetDebuggerPropertyForPluginsOldStyle); } lldb::OptionValuePropertiesSP PluginManager::GetSettingForProcessPlugin(Debugger &debugger, - ConstString setting_name) { - return GetSettingForPlugin(debugger, setting_name, - ConstString(kProcessPluginName)); + llvm::StringRef setting_name) { + return GetSettingForPlugin(debugger, setting_name, kProcessPluginName); } bool PluginManager::CreateSettingForProcessPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property) { - return CreateSettingForPlugin(debugger, ConstString(kProcessPluginName), - ConstString("Settings for process plug-ins"), - properties_sp, description, is_global_property); + llvm::StringRef description, bool is_global_property) { + return CreateSettingForPlugin(debugger, kProcessPluginName, + "Settings for process plug-ins", properties_sp, + description, is_global_property); } bool PluginManager::CreateSettingForTracePlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property) { - return CreateSettingForPlugin(debugger, ConstString(kTracePluginName), - ConstString("Settings for trace plug-ins"), - properties_sp, description, is_global_property); + llvm::StringRef description, bool is_global_property) { + return CreateSettingForPlugin(debugger, kTracePluginName, + "Settings for trace plug-ins", properties_sp, + description, is_global_property); } lldb::OptionValuePropertiesSP PluginManager::GetSettingForObjectFilePlugin(Debugger &debugger, - ConstString setting_name) { - return GetSettingForPlugin(debugger, setting_name, - ConstString(kObjectFilePluginName)); + llvm::StringRef setting_name) { + return GetSettingForPlugin(debugger, setting_name, 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); + llvm::StringRef description, bool is_global_property) { + return CreateSettingForPlugin(debugger, kObjectFilePluginName, + "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, - ConstString(kSymbolFilePluginName)); + llvm::StringRef setting_name) { + return GetSettingForPlugin(debugger, setting_name, kSymbolFilePluginName); } bool PluginManager::CreateSettingForSymbolFilePlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property) { - return CreateSettingForPlugin( - debugger, ConstString(kSymbolFilePluginName), - ConstString("Settings for symbol file plug-ins"), properties_sp, - description, is_global_property); + llvm::StringRef description, bool is_global_property) { + return CreateSettingForPlugin(debugger, kSymbolFilePluginName, + "Settings for symbol file plug-ins", + properties_sp, description, is_global_property); } lldb::OptionValuePropertiesSP PluginManager::GetSettingForJITLoaderPlugin(Debugger &debugger, - ConstString setting_name) { - return GetSettingForPlugin(debugger, setting_name, - ConstString(kJITLoaderPluginName)); + llvm::StringRef setting_name) { + return GetSettingForPlugin(debugger, setting_name, kJITLoaderPluginName); } bool PluginManager::CreateSettingForJITLoaderPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property) { - return CreateSettingForPlugin(debugger, ConstString(kJITLoaderPluginName), - ConstString("Settings for JIT loader plug-ins"), + llvm::StringRef description, bool is_global_property) { + return CreateSettingForPlugin(debugger, kJITLoaderPluginName, + "Settings for JIT loader plug-ins", properties_sp, description, is_global_property); } @@ -1620,12 +1651,12 @@ static const char *kOperatingSystemPluginName("os"); lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, - ConstString setting_name) { + llvm::StringRef setting_name) { lldb::OptionValuePropertiesSP properties_sp; lldb::OptionValuePropertiesSP plugin_type_properties_sp( GetDebuggerPropertyForPlugins( - debugger, ConstString(kOperatingSystemPluginName), - ConstString(), // not creating to so we don't need the description + debugger, kOperatingSystemPluginName, + "", // not creating to so we don't need the description false)); if (plugin_type_properties_sp) properties_sp = @@ -1635,12 +1666,12 @@ PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, bool PluginManager::CreateSettingForOperatingSystemPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property) { + llvm::StringRef description, bool is_global_property) { if (properties_sp) { lldb::OptionValuePropertiesSP plugin_type_properties_sp( - GetDebuggerPropertyForPlugins( - debugger, ConstString(kOperatingSystemPluginName), - ConstString("Settings for operating system plug-ins"), true)); + GetDebuggerPropertyForPlugins(debugger, kOperatingSystemPluginName, + "Settings for operating system plug-ins", + true)); if (plugin_type_properties_sp) { plugin_type_properties_sp->AppendProperty(properties_sp->GetName(), description, is_global_property, @@ -1653,16 +1684,14 @@ bool PluginManager::CreateSettingForOperatingSystemPlugin( lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger, - ConstString setting_name) { - return GetSettingForPlugin(debugger, setting_name, - ConstString(kStructuredDataPluginName)); + llvm::StringRef setting_name) { + return GetSettingForPlugin(debugger, setting_name, kStructuredDataPluginName); } bool PluginManager::CreateSettingForStructuredDataPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property) { - return CreateSettingForPlugin( - debugger, ConstString(kStructuredDataPluginName), - ConstString("Settings for structured data plug-ins"), properties_sp, - description, is_global_property); + llvm::StringRef description, bool is_global_property) { + return CreateSettingForPlugin(debugger, kStructuredDataPluginName, + "Settings for structured data plug-ins", + properties_sp, description, is_global_property); } diff --git a/contrib/llvm-project/lldb/source/Core/Progress.cpp b/contrib/llvm-project/lldb/source/Core/Progress.cpp index c54e7774adf3..08be73f1470f 100644 --- a/contrib/llvm-project/lldb/source/Core/Progress.cpp +++ b/contrib/llvm-project/lldb/source/Core/Progress.cpp @@ -36,7 +36,7 @@ Progress::~Progress() { } } -void Progress::Increment(uint64_t amount) { +void Progress::Increment(uint64_t amount, std::string update) { if (amount > 0) { std::lock_guard<std::mutex> guard(m_mutex); // Watch out for unsigned overflow and make sure we don't increment too @@ -45,16 +45,16 @@ void Progress::Increment(uint64_t amount) { m_completed = m_total; else m_completed += amount; - ReportProgress(); + ReportProgress(update); } } -void Progress::ReportProgress() { +void Progress::ReportProgress(std::string update) { if (!m_complete) { // Make sure we only send one notification that indicates the progress is // complete. m_complete = m_completed == m_total; - Debugger::ReportProgress(m_id, m_title, m_completed, m_total, - m_debugger_id); + Debugger::ReportProgress(m_id, m_title, std::move(update), m_completed, + m_total, m_debugger_id); } } diff --git a/contrib/llvm-project/lldb/source/Core/Section.cpp b/contrib/llvm-project/lldb/source/Core/Section.cpp index 50c1562f7561..212b3119894f 100644 --- a/contrib/llvm-project/lldb/source/Core/Section.cpp +++ b/contrib/llvm-project/lldb/source/Core/Section.cpp @@ -145,6 +145,8 @@ const char *Section::GetTypeAsCString() const { return "absolute"; case eSectionTypeDWARFGNUDebugAltLink: return "dwarf-gnu-debugaltlink"; + case eSectionTypeCTF: + return "ctf"; case eSectionTypeOther: return "regular"; } @@ -452,6 +454,7 @@ bool Section::ContainsOnlyDebugInfo() const { case eSectionTypeDWARFAppleNamespaces: case eSectionTypeDWARFAppleObjC: case eSectionTypeDWARFGNUDebugAltLink: + case eSectionTypeCTF: return true; } return false; @@ -673,3 +676,36 @@ uint64_t SectionList::GetDebugInfoSize() const { } return debug_info_size; } + +namespace llvm { +namespace json { + +bool fromJSON(const llvm::json::Value &value, + lldb_private::JSONSection §ion, llvm::json::Path path) { + llvm::json::ObjectMapper o(value, path); + return o && o.map("name", section.name) && o.map("type", section.type) && + o.map("size", section.address) && o.map("size", section.size); +} + +bool fromJSON(const llvm::json::Value &value, lldb::SectionType &type, + llvm::json::Path path) { + if (auto str = value.getAsString()) { + type = llvm::StringSwitch<lldb::SectionType>(*str) + .Case("code", eSectionTypeCode) + .Case("container", eSectionTypeContainer) + .Case("data", eSectionTypeData) + .Case("debug", eSectionTypeDebug) + .Default(eSectionTypeInvalid); + + if (type == eSectionTypeInvalid) { + path.report("invalid section type"); + return false; + } + + return true; + } + path.report("expected string"); + return false; +} +} // namespace json +} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp b/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp index 805291f7d59a..7165d04955d6 100644 --- a/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp +++ b/contrib/llvm-project/lldb/source/Core/SourceLocationSpec.cpp @@ -8,6 +8,7 @@ #include "lldb/Core/SourceLocationSpec.h" #include "lldb/Utility/StreamString.h" +#include "llvm/ADT/StringExtras.h" #include <optional> using namespace lldb; diff --git a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp index 72fabb42507c..517a4b0268d2 100644 --- a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp @@ -21,10 +21,13 @@ #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/PathMappingList.h" +#include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" @@ -73,39 +76,89 @@ SourceManager::~SourceManager() = default; SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { if (!file_spec) - return nullptr; + return {}; - FileSpec resolved_fspec = file_spec; - resolve_tilde(resolved_fspec); + Log *log = GetLog(LLDBLog::Source); DebuggerSP debugger_sp(m_debugger_wp.lock()); - FileSP file_sp; - if (debugger_sp && debugger_sp->GetUseSourceCache()) - file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(resolved_fspec); - TargetSP target_sp(m_target_wp.lock()); - // It the target source path map has been updated, get this file again so we - // can successfully remap the source file - if (target_sp && file_sp && - file_sp->GetSourceMapModificationID() != - target_sp->GetSourcePathMap().GetModificationID()) - file_sp.reset(); + if (!debugger_sp || !debugger_sp->GetUseSourceCache()) { + LLDB_LOG(log, "Source file caching disabled: creating new source file: {0}", + file_spec); + if (target_sp) + return std::make_shared<File>(file_spec, target_sp); + return std::make_shared<File>(file_spec, debugger_sp); + } - // Update the file contents if needed if we found a file + ProcessSP process_sp = target_sp ? target_sp->GetProcessSP() : ProcessSP(); + + // Check the process source cache first. This is the fast path which avoids + // touching the file system unless the path remapping has changed. + if (process_sp) { + if (FileSP file_sp = + process_sp->GetSourceFileCache().FindSourceFile(file_spec)) { + LLDB_LOG(log, "Found source file in the process cache: {0}", file_spec); + if (file_sp->PathRemappingIsStale()) { + LLDB_LOG(log, "Path remapping is stale: removing file from caches: {0}", + file_spec); + + // Remove the file from the debugger and process cache. Otherwise we'll + // hit the same issue again below when querying the debugger cache. + debugger_sp->GetSourceFileCache().RemoveSourceFile(file_sp); + process_sp->GetSourceFileCache().RemoveSourceFile(file_sp); + + file_sp.reset(); + } else { + return file_sp; + } + } + } + + // Cache miss in the process cache. Check the debugger source cache. + FileSP file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(file_spec); + + // We found the file in the debugger cache. Check if anything invalidated our + // cache result. if (file_sp) - file_sp->UpdateIfNeeded(); + LLDB_LOG(log, "Found source file in the debugger cache: {0}", file_spec); + + // Check if the path remapping has changed. + if (file_sp && file_sp->PathRemappingIsStale()) { + LLDB_LOG(log, "Path remapping is stale: {0}", file_spec); + file_sp.reset(); + } - // 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())) { + // Check if the modification time has changed. + if (file_sp && file_sp->ModificationTimeIsStale()) { + LLDB_LOG(log, "Modification time is stale: {0}", file_spec); + file_sp.reset(); + } + + // Check if the file exists on disk. + if (file_sp && !FileSystem::Instance().Exists(file_sp->GetFileSpec())) { + LLDB_LOG(log, "File doesn't exist on disk: {0}", file_spec); + file_sp.reset(); + } + + // If at this point we don't have a valid file, it means we either didn't find + // it in the debugger cache or something caused it to be invalidated. + if (!file_sp) { + LLDB_LOG(log, "Creating and caching new source file: {0}", file_spec); + + // (Re)create the file. if (target_sp) - file_sp = std::make_shared<File>(resolved_fspec, target_sp.get()); + file_sp = std::make_shared<File>(file_spec, target_sp); else - file_sp = std::make_shared<File>(resolved_fspec, debugger_sp); + file_sp = std::make_shared<File>(file_spec, debugger_sp); - if (debugger_sp && debugger_sp->GetUseSourceCache()) - debugger_sp->GetSourceFileCache().AddSourceFile(file_sp); + // Add the file to the debugger and process cache. If the file was + // invalidated, this will overwrite it. + debugger_sp->GetSourceFileCache().AddSourceFile(file_spec, file_sp); + if (process_sp) + process_sp->GetSourceFileCache().AddSourceFile(file_spec, file_sp); } + return file_sp; } @@ -205,7 +258,8 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( } char buffer[3]; - sprintf(buffer, "%2.2s", (line == curr_line) ? current_line_cstr : ""); + snprintf(buffer, sizeof(buffer), "%2.2s", + (line == curr_line) ? current_line_cstr : ""); std::string current_line_highlight(buffer); auto debugger_sp = m_debugger_wp.lock(); @@ -358,10 +412,7 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { executable_ptr->FindFunctions(main_name, CompilerDeclContext(), lldb::eFunctionNameTypeBase, function_options, sc_list); - size_t num_matches = sc_list.GetSize(); - for (size_t idx = 0; idx < num_matches; idx++) { - SymbolContext sc; - sc_list.GetContextAtIndex(idx, sc); + for (const SymbolContext &sc : sc_list) { if (sc.function) { lldb_private::LineEntry line_entry; if (sc.function->GetAddressRange() @@ -395,33 +446,37 @@ void SourceManager::FindLinesMatchingRegex(FileSpec &file_spec, SourceManager::File::File(const FileSpec &file_spec, lldb::DebuggerSP debugger_sp) - : m_file_spec_orig(file_spec), m_file_spec(file_spec), - m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), - m_debugger_wp(debugger_sp) { - CommonInitializer(file_spec, nullptr); + : m_file_spec_orig(file_spec), m_file_spec(), m_mod_time(), + m_debugger_wp(debugger_sp), m_target_wp(TargetSP()) { + CommonInitializer(file_spec, {}); } -SourceManager::File::File(const FileSpec &file_spec, Target *target) - : m_file_spec_orig(file_spec), m_file_spec(file_spec), - m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), - m_debugger_wp(target ? target->GetDebugger().shared_from_this() - : DebuggerSP()) { - CommonInitializer(file_spec, target); +SourceManager::File::File(const FileSpec &file_spec, TargetSP target_sp) + : m_file_spec_orig(file_spec), m_file_spec(), m_mod_time(), + m_debugger_wp(target_sp ? target_sp->GetDebugger().shared_from_this() + : DebuggerSP()), + m_target_wp(target_sp) { + CommonInitializer(file_spec, target_sp); } void SourceManager::File::CommonInitializer(const FileSpec &file_spec, - Target *target) { - if (m_mod_time == llvm::sys::TimePoint<>()) { - if (target) { - m_source_map_mod_id = target->GetSourcePathMap().GetModificationID(); + TargetSP target_sp) { + // Set the file and update the modification time. + SetFileSpec(file_spec); + + // Always update the source map modification ID if we have a target. + if (target_sp) + m_source_map_mod_id = target_sp->GetSourcePathMap().GetModificationID(); + // File doesn't exist. + if (m_mod_time == llvm::sys::TimePoint<>()) { + if (target_sp) { + // If this is just a file name, try finding it in the target. if (!file_spec.GetDirectory() && file_spec.GetFilename()) { - // If this is just a file name, lets see if we can find it in the - // target: bool check_inlines = false; SymbolContextList sc_list; size_t num_matches = - target->GetImages().ResolveSymbolContextForFilePath( + target_sp->GetImages().ResolveSymbolContextForFilePath( file_spec.GetFilename().AsCString(), 0, check_inlines, SymbolContextItem(eSymbolContextModule | eSymbolContextCompUnit), @@ -429,11 +484,8 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, bool got_multiple = false; if (num_matches != 0) { if (num_matches > 1) { - SymbolContext sc; CompileUnit *test_cu = nullptr; - - for (unsigned i = 0; i < num_matches; i++) { - sc_list.GetContextAtIndex(i, sc); + for (const SymbolContext &sc : sc_list) { if (sc.comp_unit) { if (test_cu) { if (test_cu != sc.comp_unit) @@ -448,35 +500,39 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, SymbolContext sc; sc_list.GetContextAtIndex(0, sc); if (sc.comp_unit) - m_file_spec = sc.comp_unit->GetPrimaryFile(); - m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); + SetFileSpec(sc.comp_unit->GetPrimaryFile()); } } } - resolve_tilde(m_file_spec); - // Try remapping if m_file_spec does not correspond to an existing file. + + // Try remapping the file if it doesn't exist. if (!FileSystem::Instance().Exists(m_file_spec)) { // Check target specific source remappings (i.e., the // target.source-map setting), then fall back to the module // specific remapping (i.e., the .dSYM remapping dictionary). - auto remapped = target->GetSourcePathMap().FindFile(m_file_spec); + auto remapped = target_sp->GetSourcePathMap().FindFile(m_file_spec); if (!remapped) { FileSpec new_spec; - if (target->GetImages().FindSourceFile(m_file_spec, new_spec)) + if (target_sp->GetImages().FindSourceFile(m_file_spec, new_spec)) remapped = new_spec; } - if (remapped) { - m_file_spec = *remapped; - m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); - } + if (remapped) + SetFileSpec(*remapped); } } } + // If the file exists, read in the data. if (m_mod_time != llvm::sys::TimePoint<>()) m_data_sp = FileSystem::Instance().CreateDataBuffer(m_file_spec); } +void SourceManager::File::SetFileSpec(FileSpec file_spec) { + resolve_tilde(file_spec); + m_file_spec = std::move(file_spec); + m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); +} + uint32_t SourceManager::File::GetLineOffset(uint32_t line) { if (line == 0) return UINT32_MAX; @@ -543,18 +599,20 @@ bool SourceManager::File::LineIsValid(uint32_t line) { return false; } -void SourceManager::File::UpdateIfNeeded() { +bool SourceManager::File::ModificationTimeIsStale() const { // TODO: use host API to sign up for file modifications to anything in our // source cache and only update when we determine a file has been updated. // For now we check each time we want to display info for the file. auto curr_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); + return curr_mod_time != llvm::sys::TimePoint<>() && + m_mod_time != curr_mod_time; +} - if (curr_mod_time != llvm::sys::TimePoint<>() && - m_mod_time != curr_mod_time) { - m_mod_time = curr_mod_time; - m_data_sp = FileSystem::Instance().CreateDataBuffer(m_file_spec); - m_offsets.clear(); - } +bool SourceManager::File::PathRemappingIsStale() const { + if (TargetSP target_sp = m_target_wp.lock()) + return GetSourceMapModificationID() != + target_sp->GetSourcePathMap().GetModificationID(); + return false; } size_t SourceManager::File::DisplaySourceLines(uint32_t line, @@ -713,12 +771,40 @@ bool SourceManager::File::GetLine(uint32_t line_no, std::string &buffer) { return true; } -void SourceManager::SourceFileCache::AddSourceFile(const FileSP &file_sp) { - FileSpec file_spec = file_sp->GetFileSpec(); +void SourceManager::SourceFileCache::AddSourceFile(const FileSpec &file_spec, + FileSP file_sp) { + llvm::sys::ScopedWriter guard(m_mutex); + + assert(file_sp && "invalid FileSP"); + + AddSourceFileImpl(file_spec, file_sp); + const FileSpec &resolved_file_spec = file_sp->GetFileSpec(); + if (file_spec != resolved_file_spec) + AddSourceFileImpl(file_sp->GetFileSpec(), file_sp); +} + +void SourceManager::SourceFileCache::RemoveSourceFile(const FileSP &file_sp) { + llvm::sys::ScopedWriter guard(m_mutex); + + assert(file_sp && "invalid FileSP"); + + // Iterate over all the elements in the cache. + // This is expensive but a relatively uncommon operation. + auto it = m_file_cache.begin(); + while (it != m_file_cache.end()) { + if (it->second == file_sp) + it = m_file_cache.erase(it); + else + it++; + } +} + +void SourceManager::SourceFileCache::AddSourceFileImpl( + const FileSpec &file_spec, FileSP file_sp) { FileCache::iterator pos = m_file_cache.find(file_spec); - if (pos == m_file_cache.end()) + if (pos == m_file_cache.end()) { m_file_cache[file_spec] = file_sp; - else { + } else { if (file_sp != pos->second) m_file_cache[file_spec] = file_sp; } @@ -726,9 +812,22 @@ void SourceManager::SourceFileCache::AddSourceFile(const FileSP &file_sp) { SourceManager::FileSP SourceManager::SourceFileCache::FindSourceFile( const FileSpec &file_spec) const { - FileSP file_sp; + llvm::sys::ScopedReader guard(m_mutex); + FileCache::const_iterator pos = m_file_cache.find(file_spec); if (pos != m_file_cache.end()) - file_sp = pos->second; - return file_sp; + return pos->second; + return {}; +} + +void SourceManager::SourceFileCache::Dump(Stream &stream) const { + stream << "Modification time Lines Path\n"; + stream << "------------------- -------- --------------------------------\n"; + for (auto &entry : m_file_cache) { + if (!entry.second) + continue; + FileSP file = entry.second; + stream.Format("{0:%Y-%m-%d %H:%M:%S} {1,8:d} {2}\n", file->GetTimestamp(), + file->GetNumLines(), entry.first.GetPath()); + } } diff --git a/contrib/llvm-project/lldb/source/Core/ThreadedCommunication.cpp b/contrib/llvm-project/lldb/source/Core/ThreadedCommunication.cpp index d547c858f0f5..755a158a5359 100644 --- a/contrib/llvm-project/lldb/source/Core/ThreadedCommunication.cpp +++ b/contrib/llvm-project/lldb/source/Core/ThreadedCommunication.cpp @@ -57,7 +57,7 @@ ThreadedCommunication::ThreadedCommunication(const char *name) ThreadedCommunication::~ThreadedCommunication() { LLDB_LOG(GetLog(LLDBLog::Object | LLDBLog::Communication), "{0} ThreadedCommunication::~ThreadedCommunication (name = {1})", - this, GetBroadcasterName().AsCString()); + this, GetBroadcasterName()); } void ThreadedCommunication::Clear() { @@ -177,8 +177,8 @@ bool ThreadedCommunication::StartReadThread(Status *error_ptr) { if (error_ptr) *error_ptr = Status(maybe_thread.takeError()); else { - LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", - llvm::toString(maybe_thread.takeError())); + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), maybe_thread.takeError(), + "failed to launch host thread: {0}"); } } diff --git a/contrib/llvm-project/lldb/source/Core/UserSettingsController.cpp b/contrib/llvm-project/lldb/source/Core/UserSettingsController.cpp index 9ea4f78ddd06..f5dd926cf050 100644 --- a/contrib/llvm-project/lldb/source/Core/UserSettingsController.cpp +++ b/contrib/llvm-project/lldb/source/Core/UserSettingsController.cpp @@ -32,11 +32,10 @@ using namespace lldb_private; lldb::OptionValueSP Properties::GetPropertyValue(const ExecutionContext *exe_ctx, - llvm::StringRef path, bool will_modify, - Status &error) const { + llvm::StringRef path, Status &error) const { OptionValuePropertiesSP properties_sp(GetValueProperties()); if (properties_sp) - return properties_sp->GetSubValue(exe_ctx, path, will_modify, error); + return properties_sp->GetSubValue(exe_ctx, path, error); return lldb::OptionValueSP(); } @@ -99,17 +98,11 @@ Properties::Apropos(llvm::StringRef keyword, return matching_properties.size(); } -lldb::OptionValuePropertiesSP -Properties::GetSubProperty(const ExecutionContext *exe_ctx, - ConstString name) { - OptionValuePropertiesSP properties_sp(GetValueProperties()); - if (properties_sp) - return properties_sp->GetSubProperty(exe_ctx, name); - return lldb::OptionValuePropertiesSP(); +llvm::StringRef Properties::GetExperimentalSettingsName() { + static constexpr llvm::StringLiteral g_experimental("experimental"); + return g_experimental; } -const char *Properties::GetExperimentalSettingsName() { return "experimental"; } - bool Properties::IsSettingExperimental(llvm::StringRef setting) { if (setting.empty()) return false; diff --git a/contrib/llvm-project/lldb/source/Core/Value.cpp b/contrib/llvm-project/lldb/source/Core/Value.cpp index ccd36096b545..5a2631ca501f 100644 --- a/contrib/llvm-project/lldb/source/Core/Value.cpp +++ b/contrib/llvm-project/lldb/source/Core/Value.cpp @@ -121,6 +121,20 @@ AddressType Value::GetValueAddressType() const { return eAddressTypeInvalid; } +Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) { + switch (address_type) { + case eAddressTypeFile: + return Value::ValueType::FileAddress; + case eAddressTypeLoad: + return Value::ValueType::LoadAddress; + case eAddressTypeHost: + return Value::ValueType::HostAddress; + case eAddressTypeInvalid: + return Value::ValueType::Invalid; + } + llvm_unreachable("Unexpected address type!"); +} + RegisterInfo *Value::GetRegisterInfo() const { if (m_context_type == ContextType::RegisterInfo) return static_cast<RegisterInfo *>(m_context); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp index 38645b087435..d60a1d6f7a10 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp @@ -400,7 +400,7 @@ ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs, return GetSP(); ValueObjectSP root(GetSP()); for (size_t idx : idxs) { - root = root->GetChildAtIndex(idx, true); + root = root->GetChildAtIndex(idx); if (!root) { if (index_of_error) *index_of_error = idx; @@ -427,16 +427,13 @@ lldb::ValueObjectSP ValueObject::GetChildAtIndexPath( } lldb::ValueObjectSP -ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names, - ConstString *name_of_error) { +ValueObject::GetChildAtNamePath(llvm::ArrayRef<llvm::StringRef> names) { if (names.size() == 0) return GetSP(); ValueObjectSP root(GetSP()); - for (ConstString name : names) { - root = root->GetChildMemberWithName(name, true); + for (llvm::StringRef name : names) { + root = root->GetChildMemberWithName(name); if (!root) { - if (name_of_error) - *name_of_error = name; return root; } } @@ -460,13 +457,13 @@ lldb::ValueObjectSP ValueObject::GetChildAtNamePath( return root; } -size_t ValueObject::GetIndexOfChildWithName(ConstString name) { +size_t ValueObject::GetIndexOfChildWithName(llvm::StringRef name) { bool omit_empty_base_classes = true; - return GetCompilerType().GetIndexOfChildWithName(name.GetCString(), + return GetCompilerType().GetIndexOfChildWithName(name, omit_empty_base_classes); } -ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name, +ValueObjectSP ValueObject::GetChildMemberWithName(llvm::StringRef name, bool can_create) { // We may need to update our value if we are dynamic. if (IsPossibleDynamicType()) @@ -483,7 +480,7 @@ ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name, const size_t num_child_indexes = GetCompilerType().GetIndexOfChildMemberWithName( - name.GetCString(), omit_empty_base_classes, child_indexes); + name, omit_empty_base_classes, child_indexes); if (num_child_indexes == 0) return nullptr; @@ -700,7 +697,7 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx, return 0; return pointee_sp->GetData(data, error); } else { - ValueObjectSP child_sp = GetChildAtIndex(0, true); + ValueObjectSP child_sp = GetChildAtIndex(0); if (child_sp.get() == nullptr) return 0; Status error; @@ -1173,6 +1170,15 @@ bool ValueObject::DumpPrintableRepresentation( Stream &s, ValueObjectRepresentationStyle val_obj_display, Format custom_format, PrintableRepresentationSpecialCases special, bool do_dump_error) { + + // If the ValueObject has an error, we might end up dumping the type, which + // is useful, but if we don't even have a type, then don't examine the object + // further as that's not meaningful, only the error is. + if (m_error.Fail() && !GetCompilerType().IsValid()) { + if (do_dump_error) + s.Printf("<%s>", m_error.AsCString()); + return false; + } Flags flags(GetTypeInfo()); @@ -1230,7 +1236,7 @@ bool ValueObject::DumpPrintableRepresentation( if (low) s << ','; - ValueObjectSP child = GetChildAtIndex(low, true); + ValueObjectSP child = GetChildAtIndex(low); if (!child.get()) { s << "<invalid child>"; continue; @@ -1271,7 +1277,7 @@ bool ValueObject::DumpPrintableRepresentation( if (low) s << ','; - ValueObjectSP child = GetChildAtIndex(low, true); + ValueObjectSP child = GetChildAtIndex(low); if (!child.get()) { s << "<invalid child>"; continue; @@ -1374,6 +1380,8 @@ bool ValueObject::DumpPrintableRepresentation( if (!str.empty()) s << str; else { + // We checked for errors at the start, but do it again here in case + // realizing the value for dumping produced an error. if (m_error.Fail()) { if (do_dump_error) s.Printf("<%s>", m_error.AsCString()); @@ -1848,7 +1856,7 @@ ValueObjectSP ValueObject::GetDynamicValue(DynamicValueType use_dynamic) { if (!IsDynamic() && m_dynamic_value == nullptr) { CalculateDynamicValue(use_dynamic); } - if (m_dynamic_value) + if (m_dynamic_value && m_dynamic_value->GetError().Success()) return m_dynamic_value->GetSP(); else return ValueObjectSP(); @@ -2146,7 +2154,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( { child_name.SetString(temp_expression); ValueObjectSP child_valobj_sp = - root->GetChildMemberWithName(child_name, true); + root->GetChildMemberWithName(child_name); if (child_valobj_sp.get()) // we know we are done, so just return { @@ -2165,7 +2173,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( child_valobj_sp = root->GetNonSyntheticValue(); if (child_valobj_sp.get()) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } break; case GetValueForExpressionPathOptions::SyntheticChildrenTraversal:: @@ -2174,7 +2182,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( child_valobj_sp = root->GetSyntheticValue(); if (child_valobj_sp.get()) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } break; case GetValueForExpressionPathOptions::SyntheticChildrenTraversal:: @@ -2183,12 +2191,12 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( child_valobj_sp = root->GetNonSyntheticValue(); if (child_valobj_sp.get()) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } else { child_valobj_sp = root->GetSyntheticValue(); if (child_valobj_sp.get()) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } break; } @@ -2216,7 +2224,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( child_name.SetString(temp_expression.slice(0, next_sep_pos)); ValueObjectSP child_valobj_sp = - root->GetChildMemberWithName(child_name, true); + root->GetChildMemberWithName(child_name); if (child_valobj_sp.get()) // store the new root and move on { root = child_valobj_sp; @@ -2234,7 +2242,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( child_valobj_sp = root->GetNonSyntheticValue(); if (child_valobj_sp.get()) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } break; case GetValueForExpressionPathOptions::SyntheticChildrenTraversal:: @@ -2243,7 +2251,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( child_valobj_sp = root->GetSyntheticValue(); if (child_valobj_sp.get()) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } break; case GetValueForExpressionPathOptions::SyntheticChildrenTraversal:: @@ -2252,12 +2260,12 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( child_valobj_sp = root->GetNonSyntheticValue(); if (child_valobj_sp.get()) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } else { child_valobj_sp = root->GetSyntheticValue(); if (child_valobj_sp.get()) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } break; } @@ -2359,14 +2367,14 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( // from here on we do have a valid index if (root_compiler_type_info.Test(eTypeIsArray)) { - ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index, true); + ValueObjectSP child_valobj_sp = root->GetChildAtIndex(index); if (!child_valobj_sp) child_valobj_sp = root->GetSyntheticArrayMember(index, true); if (!child_valobj_sp) if (root->HasSyntheticValue() && root->GetSyntheticValue()->GetNumChildren() > index) child_valobj_sp = - root->GetSyntheticValue()->GetChildAtIndex(index, true); + root->GetSyntheticValue()->GetChildAtIndex(index); if (child_valobj_sp) { root = child_valobj_sp; remainder = @@ -2414,7 +2422,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( options.m_synthetic_children_traversal == GetValueForExpressionPathOptions:: SyntheticChildrenTraversal::Both)) { - root = root->GetSyntheticValue()->GetChildAtIndex(index, true); + root = root->GetSyntheticValue()->GetChildAtIndex(index); } else root = root->GetSyntheticArrayMember(index, true); if (!root) { @@ -2445,7 +2453,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( return root; } } else if (root_compiler_type_info.Test(eTypeIsVector)) { - root = root->GetChildAtIndex(index, true); + root = root->GetChildAtIndex(index); if (!root) { *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; @@ -2480,7 +2488,7 @@ ValueObjectSP ValueObject::GetValueForExpressionPath_Impl( *final_result = ValueObject::eExpressionPathEndResultTypeInvalid; return nullptr; } - root = root->GetChildAtIndex(index, true); + root = root->GetChildAtIndex(index); if (!root) { *reason_to_stop = ValueObject::eExpressionPathScanEndReasonNoSuchChild; @@ -2704,12 +2712,9 @@ ValueObjectSP ValueObject::Dereference(Status &error) { } else if (HasSyntheticValue()) { m_deref_valobj = - GetSyntheticValue() - ->GetChildMemberWithName(ConstString("$$dereference$$"), true) - .get(); + GetSyntheticValue()->GetChildMemberWithName("$$dereference$$").get(); } else if (IsSynthetic()) { - m_deref_valobj = - GetChildMemberWithName(ConstString("$$dereference$$"), true).get(); + m_deref_valobj = GetChildMemberWithName("$$dereference$$").get(); } if (m_deref_valobj) { @@ -2774,8 +2779,30 @@ ValueObjectSP ValueObject::AddressOf(Status &error) { return m_addr_of_valobj_sp; } +ValueObjectSP ValueObject::DoCast(const CompilerType &compiler_type) { + return ValueObjectCast::Create(*this, GetName(), compiler_type); +} + ValueObjectSP ValueObject::Cast(const CompilerType &compiler_type) { - return ValueObjectCast::Create(*this, GetName(), compiler_type); + // Only allow casts if the original type is equal or larger than the cast + // type. We don't know how to fetch more data for all the ConstResult types, + // so we can't guarantee this will work: + Status error; + CompilerType my_type = GetCompilerType(); + + ExecutionContextScope *exe_scope + = ExecutionContext(GetExecutionContextRef()) + .GetBestExecutionContextScope(); + if (compiler_type.GetByteSize(exe_scope) + <= GetCompilerType().GetByteSize(exe_scope)) { + return DoCast(compiler_type); + } + error.SetErrorString("Can only cast to a type that is equal to or smaller " + "than the orignal type."); + + return ValueObjectConstResult::Create( + ExecutionContext(GetExecutionContextRef()).GetBestExecutionContextScope(), + error); } lldb::ValueObjectSP ValueObject::Clone(ConstString new_name) { @@ -2841,7 +2868,7 @@ ValueObject::EvaluationPoint::EvaluationPoint(ExecutionContextScope *exe_scope, StackFrameSP frame_sp(exe_ctx.GetFrameSP()); if (!frame_sp) { if (use_selected) - frame_sp = thread_sp->GetSelectedFrame(); + frame_sp = thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); } if (frame_sp) m_exe_ctx_ref.SetFrameSP(frame_sp); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp index 640abdddfcad..693da1a551f8 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResult.cpp @@ -287,14 +287,14 @@ ValueObjectConstResult::GetDynamicValue(lldb::DynamicValueType use_dynamic) { if (process && process->IsPossibleDynamicValue(*this)) m_dynamic_value = new ValueObjectDynamicValue(*this, use_dynamic); } - if (m_dynamic_value) + if (m_dynamic_value && m_dynamic_value->GetError().Success()) return m_dynamic_value->GetSP(); } return ValueObjectSP(); } lldb::ValueObjectSP -ValueObjectConstResult::Cast(const CompilerType &compiler_type) { +ValueObjectConstResult::DoCast(const CompilerType &compiler_type) { return m_impl.Cast(compiler_type); } diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultCast.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultCast.cpp index e70d055ac57c..fceb2635f876 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultCast.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultCast.cpp @@ -57,6 +57,6 @@ size_t ValueObjectConstResultCast::GetPointeeData(DataExtractor &data, } lldb::ValueObjectSP -ValueObjectConstResultCast::Cast(const CompilerType &compiler_type) { +ValueObjectConstResultCast::DoCast(const CompilerType &compiler_type) { return m_impl.Cast(compiler_type); } diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultChild.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultChild.cpp index 0fd81410ae54..36bf11a0b73a 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultChild.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultChild.cpp @@ -69,6 +69,6 @@ size_t ValueObjectConstResultChild::GetPointeeData(DataExtractor &data, } lldb::ValueObjectSP -ValueObjectConstResultChild::Cast(const CompilerType &compiler_type) { +ValueObjectConstResultChild::DoCast(const CompilerType &compiler_type) { return m_impl.Cast(compiler_type); } diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp index 0659c771918a..e6e30dce9d1e 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -149,7 +149,18 @@ bool ValueObjectDynamicValue::UpdateValue() { if (known_type != lldb::eLanguageTypeUnknown && known_type != lldb::eLanguageTypeC) { runtime = process->GetLanguageRuntime(known_type); - if (runtime) + if (auto *preferred_runtime = + runtime->GetPreferredLanguageRuntime(*m_parent)) { + // Try the preferred runtime first. + found_dynamic_type = preferred_runtime->GetDynamicTypeAndAddress( + *m_parent, m_use_dynamic, class_type_or_name, dynamic_address, + value_type); + if (found_dynamic_type) + // Set the operative `runtime` for later use in this function. + runtime = preferred_runtime; + } + if (!found_dynamic_type) + // Fallback to the runtime for `known_type`. found_dynamic_type = runtime->GetDynamicTypeAndAddress( *m_parent, m_use_dynamic, class_type_or_name, dynamic_address, value_type); @@ -187,17 +198,19 @@ bool ValueObjectDynamicValue::UpdateValue() { m_type_impl.Clear(); } - // If we don't have a dynamic type, then make ourselves just a echo of our - // parent. Or we could return false, and make ourselves an echo of our - // parent? + // If we don't have a dynamic type, set ourselves to be invalid and return + // false. We used to try to produce a dynamic ValueObject that behaved "like" + // its parent, but that failed for ValueObjectConstResult, which is too + // complex a beast to try to emulate. If we return an invalid ValueObject, + // clients will end up getting the static value instead, which behaves + // correctly. if (!found_dynamic_type) { if (m_dynamic_type_info) SetValueDidChange(true); ClearDynamicTypeInformation(); m_dynamic_type_info.Clear(); - m_value = m_parent->GetValue(); - m_error = m_value.GetValueAsData(&exe_ctx, m_data, GetModule().get()); - return m_error.Success(); + m_error.SetErrorString("no dynamic type found"); + return false; } Value old_value(m_value); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp index a0fbf9a7d25b..c2b84c113473 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp @@ -128,12 +128,11 @@ ValueObject *ValueObjectRegisterSet::CreateChildAtIndex( } lldb::ValueObjectSP -ValueObjectRegisterSet::GetChildMemberWithName(ConstString name, +ValueObjectRegisterSet::GetChildMemberWithName(llvm::StringRef name, bool can_create) { ValueObject *valobj = nullptr; if (m_reg_ctx_sp && m_reg_set) { - const RegisterInfo *reg_info = - m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef()); + const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name); if (reg_info != nullptr) valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info); } @@ -143,11 +142,9 @@ ValueObjectRegisterSet::GetChildMemberWithName(ConstString name, return ValueObjectSP(); } -size_t -ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) { +size_t ValueObjectRegisterSet::GetIndexOfChildWithName(llvm::StringRef name) { if (m_reg_ctx_sp && m_reg_set) { - const RegisterInfo *reg_info = - m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef()); + const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name); if (reg_info != nullptr) return reg_info->kinds[eRegisterKindLLDB]; } @@ -205,7 +202,7 @@ CompilerType ValueObjectRegister::GetCompilerTypeImpl() { exe_module->GetTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err), - "Unable to get CompilerType from TypeSystem"); + "Unable to get CompilerType from TypeSystem: {0}"); } else { if (auto ts = *type_system_or_err) m_compiler_type = ts->GetBuiltinTypeForEncodingAndBitSize( diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp index bd83d5908992..ad29d36ae08a 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -12,6 +12,7 @@ #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSynthetic.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" @@ -33,7 +34,7 @@ public: size_t CalculateNumChildren() override { return m_backend.GetNumChildren(); } lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { - return m_backend.GetChildAtIndex(idx, true); + return m_backend.GetChildAtIndex(idx); } size_t GetIndexOfChildWithName(ConstString name) override { @@ -306,11 +307,11 @@ lldb::ValueObjectSP ValueObjectSynthetic::GetChildAtIndex(size_t idx, } lldb::ValueObjectSP -ValueObjectSynthetic::GetChildMemberWithName(ConstString name, +ValueObjectSynthetic::GetChildMemberWithName(llvm::StringRef name, bool can_create) { UpdateValueIfNeeded(); - uint32_t index = GetIndexOfChildWithName(name); + uint32_t index = GetIndexOfChildWithName(ConstString(name)); if (index == UINT32_MAX) return lldb::ValueObjectSP(); @@ -318,9 +319,11 @@ ValueObjectSynthetic::GetChildMemberWithName(ConstString name, return GetChildAtIndex(index, can_create); } -size_t ValueObjectSynthetic::GetIndexOfChildWithName(ConstString name) { +size_t ValueObjectSynthetic::GetIndexOfChildWithName(llvm::StringRef name_ref) { UpdateValueIfNeeded(); + ConstString name(name_ref); + uint32_t found_index = UINT32_MAX; bool did_find; { diff --git a/contrib/llvm-project/lldb/source/DataFormatters/DumpValueObjectOptions.cpp b/contrib/llvm-project/lldb/source/DataFormatters/DumpValueObjectOptions.cpp index 38de4428bb23..c5e84810cdc8 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/DumpValueObjectOptions.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/DumpValueObjectOptions.cpp @@ -16,13 +16,14 @@ using namespace lldb_private; DumpValueObjectOptions::DumpValueObjectOptions() : m_summary_sp(), m_root_valobj_name(), m_max_ptr_depth(PointerDepth{PointerDepth::Mode::Default, 0}), - m_decl_printing_helper(), m_pointer_as_array(), m_use_synthetic(true), + m_decl_printing_helper(), m_child_printing_decider(), + m_pointer_as_array(), m_use_synthetic(true), m_scope_already_checked(false), m_flat_output(false), m_ignore_cap(false), m_show_types(false), m_show_location(false), m_use_objc(false), - m_hide_root_type(false), m_hide_name(false), m_hide_value(false), - m_run_validator(false), m_use_type_display_name(true), - m_allow_oneliner_mode(true), m_hide_pointer_value(false), - m_reveal_empty_aggregates(true) {} + m_hide_root_type(false), m_hide_root_name(false), m_hide_name(false), + m_hide_value(false), m_run_validator(false), + m_use_type_display_name(true), m_allow_oneliner_mode(true), + m_hide_pointer_value(false), m_reveal_empty_aggregates(true) {} DumpValueObjectOptions::DumpValueObjectOptions(ValueObject &valobj) : DumpValueObjectOptions() { @@ -50,6 +51,12 @@ DumpValueObjectOptions::SetDeclPrintingHelper(DeclPrintingHelper helper) { return *this; } +DumpValueObjectOptions & +DumpValueObjectOptions::SetChildPrintingDecider(ChildPrintingDecider decider) { + m_child_printing_decider = decider; + return *this; +} + DumpValueObjectOptions &DumpValueObjectOptions::SetShowTypes(bool show) { m_show_types = show; return *this; @@ -143,6 +150,12 @@ DumpValueObjectOptions::SetHideRootType(bool hide_root_type) { return *this; } +DumpValueObjectOptions & +DumpValueObjectOptions::SetHideRootName(bool hide_root_name) { + m_hide_root_name = hide_root_name; + return *this; +} + DumpValueObjectOptions &DumpValueObjectOptions::SetHideName(bool hide_name) { m_hide_name = hide_name; return *this; diff --git a/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp b/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp index 166264df9933..f1f135de32ca 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/FormatManager.cpp @@ -103,7 +103,7 @@ static bool GetFormatFromFormatName(llvm::StringRef format_name, if (partial_match_ok) { for (i = 0; i < g_num_format_infos; ++i) { if (llvm::StringRef(g_format_infos[i].format_name) - .startswith_insensitive(format_name)) { + .starts_with_insensitive(format_name)) { format = g_format_infos[i].format; return true; } @@ -476,7 +476,7 @@ bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) { for (size_t idx = 0; idx < valobj.GetNumChildren(); idx++) { bool is_synth_val = false; - ValueObjectSP child_sp(valobj.GetChildAtIndex(idx, true)); + ValueObjectSP child_sp(valobj.GetChildAtIndex(idx)); // something is wrong here - bail out if (!child_sp) return false; @@ -596,6 +596,15 @@ ImplSP FormatManager::GetHardcoded(FormattersMatchData &match_data) { return retval_sp; } +namespace { +template <typename ImplSP> const char *FormatterKind; +template <> const char *FormatterKind<lldb::TypeFormatImplSP> = "format"; +template <> const char *FormatterKind<lldb::TypeSummaryImplSP> = "summary"; +template <> const char *FormatterKind<lldb::SyntheticChildrenSP> = "synthetic"; +} // namespace + +#define FORMAT_LOG(Message) "[%s] " Message, FormatterKind<ImplSP> + template <typename ImplSP> ImplSP FormatManager::Get(ValueObject &valobj, lldb::DynamicValueType use_dynamic) { @@ -605,21 +614,19 @@ ImplSP FormatManager::Get(ValueObject &valobj, Log *log = GetLog(LLDBLog::DataFormatters); - LLDB_LOGF(log, "[%s] Search failed. Giving language a chance.", __FUNCTION__); + LLDB_LOGF(log, FORMAT_LOG("Search failed. Giving language a chance.")); for (lldb::LanguageType lang_type : match_data.GetCandidateLanguages()) { if (LanguageCategory *lang_category = GetCategoryForLanguage(lang_type)) { ImplSP retval_sp; if (lang_category->Get(match_data, retval_sp)) if (retval_sp) { - LLDB_LOGF(log, "[%s] Language search success. Returning.", - __FUNCTION__); + LLDB_LOGF(log, FORMAT_LOG("Language search success. Returning.")); return retval_sp; } } } - LLDB_LOGF(log, "[%s] Search failed. Giving hardcoded a chance.", - __FUNCTION__); + LLDB_LOGF(log, FORMAT_LOG("Search failed. Giving hardcoded a chance.")); return GetHardcoded<ImplSP>(match_data); } @@ -628,24 +635,23 @@ ImplSP FormatManager::GetCached(FormattersMatchData &match_data) { ImplSP retval_sp; Log *log = GetLog(LLDBLog::DataFormatters); if (match_data.GetTypeForCache()) { - LLDB_LOGF(log, "\n\n[%s] Looking into cache for type %s", __FUNCTION__, + LLDB_LOGF(log, "\n\n" FORMAT_LOG("Looking into cache for type %s"), match_data.GetTypeForCache().AsCString("<invalid>")); if (m_format_cache.Get(match_data.GetTypeForCache(), retval_sp)) { if (log) { - LLDB_LOGF(log, "[%s] Cache search success. Returning.", __FUNCTION__); + LLDB_LOGF(log, FORMAT_LOG("Cache search success. Returning.")); LLDB_LOGV(log, "Cache hits: {0} - Cache Misses: {1}", m_format_cache.GetCacheHits(), m_format_cache.GetCacheMisses()); } return retval_sp; } - LLDB_LOGF(log, "[%s] Cache search failed. Going normal route", - __FUNCTION__); + LLDB_LOGF(log, FORMAT_LOG("Cache search failed. Going normal route")); } m_categories_map.Get(match_data, retval_sp); if (match_data.GetTypeForCache() && (!retval_sp || !retval_sp->NonCacheable())) { - LLDB_LOGF(log, "[%s] Caching %p for type %s", __FUNCTION__, + LLDB_LOGF(log, FORMAT_LOG("Caching %p for type %s"), static_cast<void *>(retval_sp.get()), match_data.GetTypeForCache().AsCString("<invalid>")); m_format_cache.Set(match_data.GetTypeForCache(), retval_sp); @@ -655,6 +661,8 @@ ImplSP FormatManager::GetCached(FormattersMatchData &match_data) { return retval_sp; } +#undef FORMAT_LOG + lldb::TypeFormatImplSP FormatManager::GetFormat(ValueObject &valobj, lldb::DynamicValueType use_dynamic) { @@ -740,7 +748,7 @@ void FormatManager::LoadSystemFormatters() { fourchar_flags.SetCascades(true).SetSkipPointers(true).SetSkipReferences( true); - AddFormat(sys_category_sp, lldb::eFormatOSType, ConstString("FourCharCode"), + AddFormat(sys_category_sp, lldb::eFormatOSType, "FourCharCode", fourchar_flags); } @@ -757,32 +765,19 @@ void FormatManager::LoadVectorFormatters() { .SetShowMembersOneLiner(true) .SetHideItemNames(true); - AddStringSummary(vectors_category_sp, "${var.uint128}", - ConstString("builtin_type_vec128"), vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("float[4]"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("int32_t[4]"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("int16_t[8]"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vDouble"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vFloat"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vSInt8"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vSInt16"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vSInt32"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vUInt8"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vUInt16"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vUInt32"), - vector_flags); - AddStringSummary(vectors_category_sp, "", ConstString("vBool32"), + AddStringSummary(vectors_category_sp, "${var.uint128}", "builtin_type_vec128", vector_flags); + AddStringSummary(vectors_category_sp, "", "float[4]", vector_flags); + AddStringSummary(vectors_category_sp, "", "int32_t[4]", vector_flags); + AddStringSummary(vectors_category_sp, "", "int16_t[8]", vector_flags); + AddStringSummary(vectors_category_sp, "", "vDouble", vector_flags); + AddStringSummary(vectors_category_sp, "", "vFloat", vector_flags); + AddStringSummary(vectors_category_sp, "", "vSInt8", vector_flags); + AddStringSummary(vectors_category_sp, "", "vSInt16", vector_flags); + AddStringSummary(vectors_category_sp, "", "vSInt32", vector_flags); + AddStringSummary(vectors_category_sp, "", "vUInt16", vector_flags); + AddStringSummary(vectors_category_sp, "", "vUInt8", vector_flags); + AddStringSummary(vectors_category_sp, "", "vUInt16", vector_flags); + AddStringSummary(vectors_category_sp, "", "vUInt32", vector_flags); + AddStringSummary(vectors_category_sp, "", "vBool32", vector_flags); } diff --git a/contrib/llvm-project/lldb/source/DataFormatters/FormattersHelpers.cpp b/contrib/llvm-project/lldb/source/DataFormatters/FormattersHelpers.cpp index 1f10166d1bc9..085ed3d0a2f2 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/FormattersHelpers.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/FormattersHelpers.cpp @@ -23,77 +23,78 @@ using namespace lldb_private::formatters; void lldb_private::formatters::AddFormat( TypeCategoryImpl::SharedPointer category_sp, lldb::Format format, - ConstString type_name, TypeFormatImpl::Flags flags, bool regex) { + llvm::StringRef type_name, TypeFormatImpl::Flags flags, bool regex) { lldb::TypeFormatImplSP format_sp(new TypeFormatImpl_Format(format, flags)); FormatterMatchType match_type = regex ? eFormatterMatchRegex : eFormatterMatchExact; - category_sp->AddTypeFormat(type_name.GetStringRef(), match_type, format_sp); + category_sp->AddTypeFormat(type_name, match_type, format_sp); } void lldb_private::formatters::AddSummary( TypeCategoryImpl::SharedPointer category_sp, TypeSummaryImplSP summary_sp, - ConstString type_name, bool regex) { + llvm::StringRef type_name, bool regex) { FormatterMatchType match_type = regex ? eFormatterMatchRegex : eFormatterMatchExact; - category_sp->AddTypeSummary(type_name.GetStringRef(), match_type, summary_sp); + category_sp->AddTypeSummary(type_name, match_type, summary_sp); } void lldb_private::formatters::AddStringSummary( TypeCategoryImpl::SharedPointer category_sp, const char *string, - ConstString type_name, TypeSummaryImpl::Flags flags, bool regex) { + llvm::StringRef type_name, TypeSummaryImpl::Flags flags, bool regex) { lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags, string)); FormatterMatchType match_type = regex ? eFormatterMatchRegex : eFormatterMatchExact; - category_sp->AddTypeSummary(type_name.GetStringRef(), match_type, summary_sp); + category_sp->AddTypeSummary(type_name, match_type, summary_sp); } void lldb_private::formatters::AddOneLineSummary( - TypeCategoryImpl::SharedPointer category_sp, ConstString type_name, + TypeCategoryImpl::SharedPointer category_sp, llvm::StringRef type_name, TypeSummaryImpl::Flags flags, bool regex) { flags.SetShowMembersOneLiner(true); lldb::TypeSummaryImplSP summary_sp(new StringSummaryFormat(flags, "")); FormatterMatchType match_type = regex ? eFormatterMatchRegex : eFormatterMatchExact; - category_sp->AddTypeSummary(type_name.GetStringRef(), match_type, summary_sp); + category_sp->AddTypeSummary(type_name, match_type, summary_sp); } void lldb_private::formatters::AddCXXSummary( TypeCategoryImpl::SharedPointer category_sp, CXXFunctionSummaryFormat::Callback funct, const char *description, - ConstString type_name, TypeSummaryImpl::Flags flags, bool regex) { + llvm::StringRef type_name, TypeSummaryImpl::Flags flags, bool regex) { lldb::TypeSummaryImplSP summary_sp( new CXXFunctionSummaryFormat(flags, funct, description)); FormatterMatchType match_type = regex ? eFormatterMatchRegex : eFormatterMatchExact; - category_sp->AddTypeSummary(type_name.GetStringRef(), match_type, summary_sp); + category_sp->AddTypeSummary(type_name, match_type, summary_sp); } void lldb_private::formatters::AddCXXSynthetic( TypeCategoryImpl::SharedPointer category_sp, CXXSyntheticChildren::CreateFrontEndCallback generator, - const char *description, ConstString type_name, + const char *description, llvm::StringRef type_name, ScriptedSyntheticChildren::Flags flags, bool regex) { lldb::SyntheticChildrenSP synth_sp( new CXXSyntheticChildren(flags, description, generator)); FormatterMatchType match_type = regex ? eFormatterMatchRegex : eFormatterMatchExact; - category_sp->AddTypeSynthetic(type_name.GetStringRef(), match_type, synth_sp); + category_sp->AddTypeSynthetic(type_name, match_type, synth_sp); } void lldb_private::formatters::AddFilter( TypeCategoryImpl::SharedPointer category_sp, std::vector<std::string> children, const char *description, - ConstString type_name, ScriptedSyntheticChildren::Flags flags, bool regex) { + llvm::StringRef type_name, ScriptedSyntheticChildren::Flags flags, + bool regex) { TypeFilterImplSP filter_sp(new TypeFilterImpl(flags)); for (auto child : children) filter_sp->AddExpressionPath(child); FormatterMatchType match_type = regex ? eFormatterMatchRegex : eFormatterMatchExact; - category_sp->AddTypeFilter(type_name.GetStringRef(), match_type, filter_sp); + category_sp->AddTypeFilter(type_name, match_type, filter_sp); } size_t lldb_private::formatters::ExtractIndexFromString(const char *item_name) { @@ -125,14 +126,3 @@ lldb_private::formatters::GetArrayAddressOrPointerValue(ValueObject &valobj) { return data_addr; } - -lldb::ValueObjectSP -lldb_private::formatters::GetValueOfLibCXXCompressedPair(ValueObject &pair) { - ValueObjectSP value = - pair.GetChildMemberWithName(ConstString("__value_"), true); - if (!value) { - // pre-r300140 member name - value = pair.GetChildMemberWithName(ConstString("__first_"), true); - } - return value; -} diff --git a/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp b/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp index 0dd5d518f60b..4b57e87b4ccd 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/StringPrinter.cpp @@ -154,11 +154,11 @@ DecodedCharBuffer GetPrintableImpl<StringElementType::ASCII>( switch (escape_style) { case StringPrinter::EscapeStyle::CXX: // Prints 4 characters, then a \0 terminator. - escaped_len = sprintf((char *)data, "\\x%02x", *buffer); + escaped_len = snprintf((char *)data, max_buffer_size, "\\x%02x", *buffer); break; case StringPrinter::EscapeStyle::Swift: // Prints up to 6 characters, then a \0 terminator. - escaped_len = sprintf((char *)data, "\\u{%x}", *buffer); + escaped_len = snprintf((char *)data, max_buffer_size, "\\u{%x}", *buffer); break; } lldbassert(escaped_len > 0 && "unknown string escape style"); @@ -201,11 +201,11 @@ DecodedCharBuffer GetPrintableImpl<StringElementType::UTF8>( switch (escape_style) { case StringPrinter::EscapeStyle::CXX: // Prints 10 characters, then a \0 terminator. - escaped_len = sprintf((char *)data, "\\U%08x", codepoint); + escaped_len = snprintf((char *)data, max_buffer_size, "\\U%08x", codepoint); break; case StringPrinter::EscapeStyle::Swift: // Prints up to 12 characters, then a \0 terminator. - escaped_len = sprintf((char *)data, "\\u{%x}", codepoint); + escaped_len = snprintf((char *)data, max_buffer_size, "\\u{%x}", codepoint); break; } lldbassert(escaped_len > 0 && "unknown string escape style"); diff --git a/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp index 6fd6308ded5d..074d0b648e6f 100644 --- a/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ b/contrib/llvm-project/lldb/source/DataFormatters/ValueObjectPrinter.cpp @@ -71,6 +71,18 @@ void ValueObjectPrinter::Init( } bool ValueObjectPrinter::PrintValueObject() { + if (!m_orig_valobj) + return false; + + // If the incoming ValueObject is in an error state, the best we're going to + // get out of it is its type. But if we don't even have that, just print + // the error and exit early. + if (m_orig_valobj->GetError().Fail() + && !m_orig_valobj->GetCompilerType().IsValid()) { + m_stream->Printf("Error: '%s'", m_orig_valobj->GetError().AsCString()); + return true; + } + if (!GetMostSpecializedValue() || m_valobj == nullptr) return false; @@ -263,7 +275,7 @@ void ValueObjectPrinter::PrintDecl() { StreamString varName; - if (!m_options.m_hide_name) { + if (ShouldShowName()) { if (m_options.m_flat_output) m_valobj->GetExpressionPath(varName); else @@ -288,9 +300,14 @@ void ValueObjectPrinter::PrintDecl() { ConstString type_name_cstr(typeName.GetString()); ConstString var_name_cstr(varName.GetString()); + DumpValueObjectOptions decl_print_options = m_options; + // Pass printing helpers an option object that indicates whether the name + // should be shown or hidden. + decl_print_options.SetHideName(!ShouldShowName()); + StreamString dest_stream; if (m_options.m_decl_printing_helper(type_name_cstr, var_name_cstr, - m_options, dest_stream)) { + decl_print_options, dest_stream)) { decl_printed = true; m_stream->PutCString(dest_stream.GetString()); } @@ -302,7 +319,7 @@ void ValueObjectPrinter::PrintDecl() { m_stream->Printf("(%s) ", typeName.GetData()); if (!varName.Empty()) m_stream->Printf("%s =", varName.GetData()); - else if (!m_options.m_hide_name) + else if (ShouldShowName()) m_stream->Printf(" ="); } } @@ -425,13 +442,17 @@ bool ValueObjectPrinter::PrintValueAndSummaryIfNeeded(bool &value_printed, if (m_options.m_hide_pointer_value && IsPointerValue(m_valobj->GetCompilerType())) { } else { - m_stream->Printf(" %s", m_value.c_str()); + if (ShouldShowName()) + m_stream->PutChar(' '); + m_stream->PutCString(m_value); value_printed = true; } } if (m_summary.size()) { - m_stream->Printf(" %s", m_summary.c_str()); + if (ShouldShowName() || value_printed) + m_stream->PutChar(' '); + m_stream->PutCString(m_summary); summary_printed = true; } } @@ -445,7 +466,7 @@ bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed, // let's avoid the overly verbose no description error for a nil thing if (m_options.m_use_objc && !IsNil() && !IsUninitialized() && (!m_options.m_pointer_as_array)) { - if (!m_options.m_hide_value || !m_options.m_hide_name) + if (!m_options.m_hide_value || ShouldShowName()) m_stream->Printf(" "); const char *object_desc = nullptr; if (value_printed || summary_printed) @@ -481,7 +502,6 @@ bool DumpValueObjectOptions::PointerDepth::CanAllowExpansion() const { } bool ValueObjectPrinter::ShouldPrintChildren( - bool is_failed_description, DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { const bool is_ref = IsRef(); const bool is_ptr = IsPtr(); @@ -490,47 +510,50 @@ bool ValueObjectPrinter::ShouldPrintChildren( if (is_uninit) return false; + // If we have reached the maximum depth we shouldn't print any more children. + if (HasReachedMaximumDepth()) + return false; + // if the user has specified an element count, always print children as it is // explicit user demand being honored if (m_options.m_pointer_as_array) return true; - TypeSummaryImpl *entry = GetSummaryFormatter(); - if (m_options.m_use_objc) return false; - 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). + bool print_children = true; + if (TypeSummaryImpl *type_summary = GetSummaryFormatter()) + print_children = type_summary->DoesPrintChildren(m_valobj); - // Use a new temporary pointer depth in case we override the current - // pointer depth below... + // 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). - if (is_ptr || is_ref) { - // We have a pointer or reference whose value is an address. Make sure - // that address is not NULL - AddressType ptr_address_type; - if (m_valobj->GetPointerValue(&ptr_address_type) == 0) - return false; + // Use a new temporary pointer depth in case we override the current + // pointer depth below... - const bool is_root_level = m_curr_depth == 0; + if (is_ptr || is_ref) { + // We have a pointer or reference whose value is an address. Make sure + // that address is not NULL + AddressType ptr_address_type; + if (m_valobj->GetPointerValue(&ptr_address_type) == 0) + return false; - if (is_ref && is_root_level) { - // If this is the root object (depth is zero) that we are showing and - // it is a reference, and no pointer depth has been supplied print out - // what it references. Don't do this at deeper depths otherwise we can - // end up with infinite recursion... - return true; - } + const bool is_root_level = m_curr_depth == 0; - return curr_ptr_depth.CanAllowExpansion(); + if (is_ref && is_root_level && print_children) { + // If this is the root object (depth is zero) that we are showing and + // it is a reference, and no pointer depth has been supplied print out + // what it references. Don't do this at deeper depths otherwise we can + // end up with infinite recursion... + return true; } - return (!entry || entry->DoesPrintChildren(m_valobj) || m_summary.empty()); + return curr_ptr_depth.CanAllowExpansion(); } - return false; + + return print_children || m_summary.empty(); } bool ValueObjectPrinter::ShouldExpandEmptyAggregates() { @@ -546,13 +569,20 @@ ValueObject *ValueObjectPrinter::GetValueObjectForChildrenGeneration() { return m_valobj; } -void ValueObjectPrinter::PrintChildrenPreamble() { +void ValueObjectPrinter::PrintChildrenPreamble(bool value_printed, + bool summary_printed) { if (m_options.m_flat_output) { if (ShouldPrintValueObject()) m_stream->EOL(); } else { - if (ShouldPrintValueObject()) - m_stream->PutCString(IsRef() ? ": {\n" : " {\n"); + if (ShouldPrintValueObject()) { + if (IsRef()) { + m_stream->PutCString(": "); + } else if (value_printed || summary_printed || ShouldShowName()) { + m_stream->PutChar(' '); + } + m_stream->PutCString("{\n"); + } m_stream->IndentMore(); } } @@ -560,7 +590,7 @@ void ValueObjectPrinter::PrintChildrenPreamble() { void ValueObjectPrinter::PrintChild( ValueObjectSP child_sp, const DumpValueObjectOptions::PointerDepth &curr_ptr_depth) { - const uint32_t consumed_depth = (!m_options.m_pointer_as_array) ? 1 : 0; + const uint32_t consumed_summary_depth = m_options.m_pointer_as_array ? 0 : 1; const bool does_consume_ptr_depth = ((IsPtr() && !m_options.m_pointer_as_array) || IsRef()); @@ -573,15 +603,18 @@ void ValueObjectPrinter::PrintChild( .SetHideValue(m_options.m_hide_value) .SetOmitSummaryDepth(child_options.m_omit_summary_depth > 1 ? child_options.m_omit_summary_depth - - consumed_depth + consumed_summary_depth : 0) .SetElementCount(0); if (child_sp.get()) { - ValueObjectPrinter child_printer( - child_sp.get(), m_stream, child_options, - does_consume_ptr_depth ? --curr_ptr_depth : curr_ptr_depth, - m_curr_depth + consumed_depth, m_printed_instance_pointers); + auto ptr_depth = curr_ptr_depth; + if (does_consume_ptr_depth) + ptr_depth = curr_ptr_depth.Decremented(); + + ValueObjectPrinter child_printer(child_sp.get(), m_stream, child_options, + ptr_depth, m_curr_depth + 1, + m_printed_instance_pointers); child_printer.PrintValueObject(); } } @@ -657,7 +690,7 @@ ValueObjectSP ValueObjectPrinter::GenerateChild(ValueObject *synth_valobj, true); } else { // otherwise, do the usual thing - return synth_valobj->GetChildAtIndex(idx, true); + return synth_valobj->GetChildAtIndex(idx); } } @@ -673,8 +706,11 @@ void ValueObjectPrinter::PrintChildren( for (size_t idx = 0; idx < num_children; ++idx) { if (ValueObjectSP child_sp = GenerateChild(synth_m_valobj, idx)) { + if (m_options.m_child_printing_decider && + !m_options.m_child_printing_decider(child_sp->GetName())) + continue; if (!any_children_printed) { - PrintChildrenPreamble(); + PrintChildrenPreamble(value_printed, summary_printed); any_children_printed = true; } PrintChild(child_sp, curr_ptr_depth); @@ -721,14 +757,19 @@ bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) { if (num_children) { m_stream->PutChar('('); + bool did_print_children = false; for (uint32_t idx = 0; idx < num_children; ++idx) { - lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx, true)); + lldb::ValueObjectSP child_sp(synth_m_valobj->GetChildAtIndex(idx)); if (child_sp) child_sp = child_sp->GetQualifiedRepresentationIfAvailable( m_options.m_use_dynamic, m_options.m_use_synthetic); if (child_sp) { - if (idx) + if (m_options.m_child_printing_decider && + !m_options.m_child_printing_decider(child_sp->GetName())) + continue; + if (idx && did_print_children) m_stream->PutCString(", "); + did_print_children = true; if (!hide_names) { const char *name = child_sp.get()->GetName().AsCString(); if (name && *name) { @@ -753,14 +794,10 @@ bool ValueObjectPrinter::PrintChildrenOneLiner(bool hide_names) { void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed, bool summary_printed) { - // This flag controls whether we tried to display a description for this - // object and failed if that happens, we want to display the children if any. - bool is_failed_description = - !PrintObjectDescriptionIfNeeded(value_printed, summary_printed); + PrintObjectDescriptionIfNeeded(value_printed, summary_printed); DumpValueObjectOptions::PointerDepth curr_ptr_depth = m_ptr_depth; - const bool print_children = - ShouldPrintChildren(is_failed_description, curr_ptr_depth); + const bool print_children = ShouldPrintChildren(curr_ptr_depth); const bool print_oneline = (curr_ptr_depth.CanAllowExpansion() || m_options.m_show_types || !m_options.m_allow_oneliner_mode || m_options.m_flat_output || @@ -805,3 +842,9 @@ void ValueObjectPrinter::PrintChildrenIfNeeded(bool value_printed, bool ValueObjectPrinter::HasReachedMaximumDepth() { return m_curr_depth >= m_options.m_max_depth; } + +bool ValueObjectPrinter::ShouldShowName() const { + if (m_curr_depth == 0) + return !m_options.m_hide_root_name && !m_options.m_hide_name; + return !m_options.m_hide_name; +} diff --git a/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp b/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp index 47cef1b35180..93fcf0579be0 100644 --- a/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/DWARFExpression.cpp @@ -355,39 +355,28 @@ static offset_t GetOpcodeDataSize(const DataExtractor &data, } lldb::addr_t DWARFExpression::GetLocation_DW_OP_addr(const DWARFUnit *dwarf_cu, - uint32_t op_addr_idx, bool &error) const { error = false; lldb::offset_t offset = 0; - uint32_t curr_op_addr_idx = 0; while (m_data.ValidOffset(offset)) { const uint8_t op = m_data.GetU8(&offset); - if (op == DW_OP_addr) { - const lldb::addr_t op_file_addr = m_data.GetAddress(&offset); - if (curr_op_addr_idx == op_addr_idx) - return op_file_addr; - ++curr_op_addr_idx; - } else if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) { + if (op == DW_OP_addr) + return m_data.GetAddress(&offset); + if (op == DW_OP_GNU_addr_index || op == DW_OP_addrx) { uint64_t index = m_data.GetULEB128(&offset); - if (curr_op_addr_idx == op_addr_idx) { - if (!dwarf_cu) { - error = true; - break; - } - + if (dwarf_cu) return dwarf_cu->ReadAddressFromDebugAddrSection(index); - } - ++curr_op_addr_idx; - } else { - const offset_t op_arg_size = - GetOpcodeDataSize(m_data, offset, op, dwarf_cu); - if (op_arg_size == LLDB_INVALID_OFFSET) { - error = true; - break; - } - offset += op_arg_size; + error = true; + break; } + const offset_t op_arg_size = + GetOpcodeDataSize(m_data, offset, op, dwarf_cu); + if (op_arg_size == LLDB_INVALID_OFFSET) { + error = true; + break; + } + offset += op_arg_size; } return LLDB_INVALID_ADDRESS; } @@ -419,13 +408,33 @@ bool DWARFExpression::Update_DW_OP_addr(const DWARFUnit *dwarf_cu, // the heap data so "m_data" will now correctly manage the heap data. m_data.SetData(encoder.GetDataBuffer()); return true; - } else { - const offset_t op_arg_size = - GetOpcodeDataSize(m_data, offset, op, dwarf_cu); - if (op_arg_size == LLDB_INVALID_OFFSET) - break; - offset += op_arg_size; } + if (op == DW_OP_addrx) { + // Replace DW_OP_addrx with DW_OP_addr, since we can't modify the + // read-only debug_addr table. + // Subtract one to account for the opcode. + llvm::ArrayRef data_before_op = m_data.GetData().take_front(offset - 1); + + // Read the addrx index to determine how many bytes it needs. + const lldb::offset_t old_offset = offset; + m_data.GetULEB128(&offset); + if (old_offset == offset) + return false; + llvm::ArrayRef data_after_op = m_data.GetData().drop_front(offset); + + DataEncoder encoder(m_data.GetByteOrder(), m_data.GetAddressByteSize()); + encoder.AppendData(data_before_op); + encoder.AppendU8(DW_OP_addr); + encoder.AppendAddress(file_addr); + encoder.AppendData(data_after_op); + m_data.SetData(encoder.GetDataBuffer()); + return true; + } + const offset_t op_arg_size = + GetOpcodeDataSize(m_data, offset, op, dwarf_cu); + if (op_arg_size == LLDB_INVALID_OFFSET) + break; + offset += op_arg_size; } return false; } @@ -1080,6 +1089,13 @@ bool DWARFExpression::Evaluate( return false; } uint8_t size = opcodes.GetU8(&offset); + if (size > 8) { + if (error_ptr) + error_ptr->SetErrorStringWithFormat( + "Invalid address size for DW_OP_deref_size: %d\n", + size); + return false; + } Value::ValueType value_type = stack.back().GetValueType(); switch (value_type) { case Value::ValueType::HostAddress: { @@ -1140,9 +1156,9 @@ bool DWARFExpression::Evaluate( uint8_t addr_bytes[8]; Status error; - if (exe_ctx->GetTargetRef().ReadMemory( - so_addr, &addr_bytes, size, error, - /*force_live_memory=*/false) == size) { + if (target && + target->ReadMemory(so_addr, &addr_bytes, size, error, + /*force_live_memory=*/false) == size) { ObjectFile *objfile = module_sp->GetObjectFile(); stack.back().GetScalar() = DerefSizeExtractDataHelper( @@ -1152,7 +1168,7 @@ bool DWARFExpression::Evaluate( } else { if (error_ptr) error_ptr->SetErrorStringWithFormat( - "Failed to dereference pointer for for DW_OP_deref_size: " + "Failed to dereference pointer for DW_OP_deref_size: " "%s\n", error.AsCString()); return false; @@ -1436,8 +1452,12 @@ bool DWARFExpression::Evaluate( return false; } else { stack.pop_back(); - stack.back() = - stack.back().ResolveValue(exe_ctx) / tmp.ResolveValue(exe_ctx); + Scalar divisor, dividend; + divisor = tmp.ResolveValue(exe_ctx); + dividend = stack.back().ResolveValue(exe_ctx); + divisor.MakeSigned(); + dividend.MakeSigned(); + stack.back() = dividend / divisor; if (!stack.back().ResolveValue(exe_ctx).IsValid()) { if (error_ptr) error_ptr->SetErrorString("Divide failed."); diff --git a/contrib/llvm-project/lldb/source/Expression/ExpressionTypeSystemHelper.cpp b/contrib/llvm-project/lldb/source/Expression/ExpressionTypeSystemHelper.cpp new file mode 100644 index 000000000000..dbac376f5f1c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Expression/ExpressionTypeSystemHelper.cpp @@ -0,0 +1,13 @@ +//===-- ExpressionTypeSystemHelper.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/Expression/ExpressionTypeSystemHelper.h" + +using namespace lldb_private; + +char ExpressionTypeSystemHelper::ID; diff --git a/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp b/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp index a397a34601d0..f0a28988822f 100644 --- a/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp +++ b/contrib/llvm-project/lldb/source/Expression/ExpressionVariable.cpp @@ -15,7 +15,9 @@ using namespace lldb_private; -ExpressionVariable::~ExpressionVariable() = default; +char ExpressionVariable::ID; + +ExpressionVariable::ExpressionVariable() : m_flags(0) {} uint8_t *ExpressionVariable::GetValueBytes() { std::optional<uint64_t> byte_size = m_frozen_sp->GetByteSize(); @@ -30,6 +32,10 @@ uint8_t *ExpressionVariable::GetValueBytes() { return nullptr; } +char PersistentExpressionState::ID; + +PersistentExpressionState::PersistentExpressionState() = default; + PersistentExpressionState::~PersistentExpressionState() = default; lldb::addr_t PersistentExpressionState::LookupSymbol(ConstString name) { diff --git a/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm-project/lldb/source/Expression/IRExecutionUnit.cpp index c8068eca5c1b..5a4ba04bff04 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/Expression/ObjectFileJIT.h" #include "lldb/Host/HostInfo.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/SymbolContext.h" @@ -36,7 +37,6 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "lldb/../../source/Plugins/ObjectFile/JIT/ObjectFileJIT.h" #include <optional> using namespace lldb_private; @@ -406,11 +406,11 @@ void IRExecutionUnit::GetRunnableInfo(Status &error, lldb::addr_t &func_addr, } }; - for (llvm::GlobalVariable &global_var : m_module->getGlobalList()) { + for (llvm::GlobalVariable &global_var : m_module->globals()) { RegisterOneValue(global_var); } - for (llvm::GlobalAlias &global_alias : m_module->getAliasList()) { + for (llvm::GlobalAlias &global_alias : m_module->aliases()) { RegisterOneValue(global_alias); } diff --git a/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp b/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp index 3c102dd4eaef..de631370bb04 100644 --- a/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp +++ b/contrib/llvm-project/lldb/source/Expression/IRMemoryMap.cpp @@ -92,17 +92,26 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) { ret = llvm::alignTo(addr + alloc_size, 4096); } + uint64_t end_of_memory; + switch (GetAddressByteSize()) { + case 2: + end_of_memory = 0xffffull; + break; + case 4: + end_of_memory = 0xffffffffull; + break; + case 8: + end_of_memory = 0xffffffffffffffffull; + break; + default: + lldbassert(false && "Invalid address size."); + return LLDB_INVALID_ADDRESS; + } + // Now, if it's possible to use the GetMemoryRegionInfo API to detect mapped // regions, walk forward through memory until a region is found that has // adequate space for our allocation. if (process_is_alive) { - const uint64_t end_of_memory = process_sp->GetAddressByteSize() == 8 - ? 0xffffffffffffffffull - : 0xffffffffull; - - lldbassert(process_sp->GetAddressByteSize() == 4 || - end_of_memory != 0xffffffffull); - MemoryRegionInfo region_info; Status err = process_sp->GetMemoryRegionInfo(ret, region_info); if (err.Success()) { @@ -137,26 +146,42 @@ lldb::addr_t IRMemoryMap::FindSpace(size_t size) { // We've tried our algorithm, and it didn't work. Now we have to reset back // to the end of the allocations we've already reported, or use a 'sensible' // default if this is our first allocation. - if (m_allocations.empty()) { - uint32_t address_byte_size = GetAddressByteSize(); - if (address_byte_size != UINT32_MAX) { - switch (address_byte_size) { - case 8: - ret = 0xdead0fff00000000ull; - break; - case 4: - ret = 0xee000000ull; - break; - default: - break; + uint64_t alloc_address = target_sp->GetExprAllocAddress(); + if (alloc_address > 0) { + if (alloc_address >= end_of_memory) { + lldbassert(0 && "The allocation address for expression evaluation must " + "be within process address space"); + return LLDB_INVALID_ADDRESS; + } + ret = alloc_address; + } else { + uint32_t address_byte_size = GetAddressByteSize(); + if (address_byte_size != UINT32_MAX) { + switch (address_byte_size) { + case 2: + ret = 0x8000ull; + break; + case 4: + ret = 0xee000000ull; + break; + case 8: + ret = 0xdead0fff00000000ull; + break; + default: + lldbassert(false && "Invalid address size."); + return LLDB_INVALID_ADDRESS; + } } } } else { auto back = m_allocations.rbegin(); lldb::addr_t addr = back->first; size_t alloc_size = back->second.m_size; - ret = llvm::alignTo(addr + alloc_size, 4096); + uint64_t align = target_sp->GetExprAllocAlign(); + if (align == 0) + align = 4096; + ret = llvm::alignTo(addr + alloc_size, align); } return ret; diff --git a/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp b/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp index 6d11abbf876f..9d01bfcb7220 100644 --- a/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/LLVMUserExpression.cpp @@ -23,6 +23,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" @@ -34,6 +35,7 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" +using namespace lldb; using namespace lldb_private; char LLVMUserExpression::ID; @@ -333,7 +335,14 @@ bool LLVMUserExpression::PrepareToExecuteJITExpression( if (m_can_interpret && m_stack_frame_bottom == LLDB_INVALID_ADDRESS) { Status alloc_error; - const size_t stack_frame_size = 512 * 1024; + size_t stack_frame_size = target->GetExprAllocSize(); + if (stack_frame_size == 0) { + ABISP abi_sp; + if (process && (abi_sp = process->GetABI())) + stack_frame_size = abi_sp->GetStackFrameSize(); + else + stack_frame_size = 512 * 1024; + } const bool zero_memory = false; diff --git a/contrib/llvm-project/lldb/source/Expression/Materializer.cpp b/contrib/llvm-project/lldb/source/Expression/Materializer.cpp index 0932dc6f95b1..6e344dfd57c4 100644 --- a/contrib/llvm-project/lldb/source/Expression/Materializer.cpp +++ b/contrib/llvm-project/lldb/source/Expression/Materializer.cpp @@ -1598,5 +1598,7 @@ void Materializer::Dematerializer::Wipe() { m_process_address = LLDB_INVALID_ADDRESS; } +Materializer::PersistentVariableDelegate::PersistentVariableDelegate() = + default; Materializer::PersistentVariableDelegate::~PersistentVariableDelegate() = default; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/contrib/llvm-project/lldb/source/Expression/ObjectFileJIT.cpp index 2ea83e4b6883..10fac9a9a445 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/contrib/llvm-project/lldb/source/Expression/ObjectFileJIT.cpp @@ -8,17 +8,11 @@ #include "llvm/ADT/StringRef.h" -#include "ObjectFileJIT.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Host/Host.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Target/Platform.h" +#include "lldb/Expression/ObjectFileJIT.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" @@ -26,9 +20,8 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/RangeMap.h" -#include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #include "lldb/Utility/UUID.h" @@ -39,8 +32,6 @@ using namespace lldb; using namespace lldb_private; -LLDB_PLUGIN_DEFINE(ObjectFileJIT) - char ObjectFileJIT::ID; void ObjectFileJIT::Initialize() { @@ -217,9 +208,9 @@ size_t ObjectFileJIT::ReadSectionData(lldb_private::Section *section, return 0; } -size_t ObjectFileJIT::ReadSectionData( - lldb_private::Section *section, - lldb_private::DataExtractor §ion_data) { +size_t +ObjectFileJIT::ReadSectionData(lldb_private::Section *section, + lldb_private::DataExtractor §ion_data) { if (section->GetFileSize()) { const void *src = (void *)(uintptr_t)section->GetFileOffset(); diff --git a/contrib/llvm-project/lldb/source/Expression/REPL.cpp b/contrib/llvm-project/lldb/source/Expression/REPL.cpp index ae80f9ad97dc..052714f0a670 100644 --- a/contrib/llvm-project/lldb/source/Expression/REPL.cpp +++ b/contrib/llvm-project/lldb/source/Expression/REPL.cpp @@ -22,7 +22,9 @@ using namespace lldb_private; -REPL::REPL(LLVMCastKind kind, Target &target) : m_target(target), m_kind(kind) { +char REPL::ID; + +REPL::REPL(Target &target) : m_target(target) { // Make sure all option values have sane defaults Debugger &debugger = m_target.GetDebugger(); debugger.SetShowProgress(false); @@ -55,14 +57,14 @@ lldb::REPLSP REPL::Create(Status &err, lldb::LanguageType language, } std::string REPL::GetSourcePath() { - ConstString file_basename = GetSourceFileBasename(); + llvm::StringRef file_basename = GetSourceFileBasename(); FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir(); if (tmpdir_file_spec) { tmpdir_file_spec.SetFilename(file_basename); m_repl_source_path = tmpdir_file_spec.GetPath(); } else { tmpdir_file_spec = FileSpec("/tmp"); - tmpdir_file_spec.AppendPathComponent(file_basename.GetStringRef()); + tmpdir_file_spec.AppendPathComponent(file_basename); } return tmpdir_file_spec.GetPath(); @@ -115,10 +117,11 @@ const char *REPL::IOHandlerGetFixIndentationCharacters() { return (m_enable_auto_indent ? GetAutoIndentCharacters() : nullptr); } -ConstString REPL::IOHandlerGetControlSequence(char ch) { +llvm::StringRef REPL::IOHandlerGetControlSequence(char ch) { + static constexpr llvm::StringLiteral control_sequence(":quit\n"); if (ch == 'd') - return ConstString(":quit\n"); - return ConstString(); + return control_sequence; + return {}; } const char *REPL::IOHandlerGetCommandPrefix() { return ":"; } @@ -233,7 +236,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { ExecutionContext exe_ctx(m_target.GetProcessSP() ->GetThreadList() .GetSelectedThread() - ->GetSelectedFrame() + ->GetSelectedFrame(DoNoSelectMostRelevantFrame) .get()); lldb::ProcessSP process_sp(exe_ctx.GetProcessSP()); @@ -308,7 +311,8 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { Thread *thread = exe_ctx.GetThreadPtr(); if (thread && thread->UnwindInnermostExpression().Success()) { thread->SetSelectedFrameByIndex(0, false); - exe_ctx.SetFrameSP(thread->GetSelectedFrame()); + exe_ctx.SetFrameSP( + thread->GetSelectedFrame(DoNoSelectMostRelevantFrame)); } } @@ -341,9 +345,11 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { expr_prefix, result_valobj_sp, error, nullptr); // fixed expression - // CommandInterpreter &ci = debugger.GetCommandInterpreter(); - - if (process_sp && process_sp->IsAlive()) { + if (llvm::Error err = OnExpressionEvaluated(exe_ctx, code, expr_options, + execution_results, + result_valobj_sp, error)) { + *error_sp << llvm::toString(std::move(err)) << "\n"; + } else if (process_sp && process_sp->IsAlive()) { bool add_to_code = true; bool handled = false; if (result_valobj_sp) { diff --git a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp index c1515b0ace81..8e1cac7099dc 100644 --- a/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Expression/UserExpression.cpp @@ -39,6 +39,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" using namespace lldb_private; @@ -202,15 +203,18 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx, return execution_results; } - // Since we might need to call allocate memory and maybe call code to make - // the caller, we need to be stopped. + + // Since we might need to allocate memory, we need to be stopped to run + // an expression. if (process != nullptr && process->GetState() != lldb::eStateStopped) { - error.SetErrorString("Can't make a function caller while the process is " - "running"); + error.SetErrorStringWithFormatv( + "unable to evaluate expression while the process is {0}: the process " + "must be stopped because the expression might require allocating " + "memory.", + StateAsCString(process->GetState())); return execution_results; } - // Explicitly force the IR interpreter to evaluate the expression when the // there is no process that supports running the expression for us. Don't // change the execution policy if we have the special top-level policy that @@ -326,11 +330,10 @@ UserExpression::Evaluate(ExecutionContext &exe_ctx, std::string msg; { llvm::raw_string_ostream os(msg); - os << "expression failed to parse:\n"; if (!diagnostic_manager.Diagnostics().empty()) os << diagnostic_manager.GetString(); else - os << "unknown error"; + os << "expression failed to parse (no further compiler diagnostics)"; if (target->GetEnableNotifyAboutFixIts() && fixed_expression && !fixed_expression->empty()) os << "\nfixed expression suggested:\n " << *fixed_expression; @@ -424,7 +427,7 @@ UserExpression::Execute(DiagnosticManager &diagnostic_manager, lldb::ExpressionResults expr_result = DoExecute( diagnostic_manager, exe_ctx, options, shared_ptr_to_me, result_var); Target *target = exe_ctx.GetTargetPtr(); - if (options.GetResultIsInternal() && result_var && target) { + if (options.GetSuppressPersistentResult() && result_var && target) { if (auto *persistent_state = target->GetPersistentExpressionStateForLanguage(m_language)) persistent_state->RemovePersistentVariable(result_var); diff --git a/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp b/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp index 5d55d9a5c2c1..d317c1cd6c15 100644 --- a/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp +++ b/contrib/llvm-project/lldb/source/Expression/UtilityFunction.cpp @@ -21,6 +21,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" using namespace lldb_private; @@ -64,11 +65,13 @@ FunctionCaller *UtilityFunction::MakeFunctionCaller( error.SetErrorString("Can't make a function caller without a process."); return nullptr; } - // Since we might need to call allocate memory and maybe call code to make + // Since we might need to allocate memory and maybe call code to make // the caller, we need to be stopped. if (process_sp->GetState() != lldb::eStateStopped) { - error.SetErrorString("Can't make a function caller while the process is " - "running"); + error.SetErrorStringWithFormatv( + "Can't make a function caller while the process is {0}: the process " + "must be stopped to allocate memory.", + StateAsCString(process_sp->GetState())); return nullptr; } diff --git a/contrib/llvm-project/lldb/source/Host/common/File.cpp b/contrib/llvm-project/lldb/source/Host/common/File.cpp index 15e7a211e353..7c5d71d9426e 100644 --- a/contrib/llvm-project/lldb/source/Host/common/File.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/File.cpp @@ -31,6 +31,7 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/VASPrintf.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" diff --git a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp index 96ff1bf13bd7..52227a9f63a5 100644 --- a/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/FileSystem.cpp @@ -9,8 +9,6 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Utility/DataBufferLLVM.h" -#include "lldb/Utility/LLDBAssert.h" -#include "lldb/Utility/TildeExpressionResolver.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Errno.h" @@ -46,16 +44,6 @@ using namespace llvm; FileSystem &FileSystem::Instance() { return *InstanceImpl(); } -void FileSystem::Initialize() { - lldbassert(!InstanceImpl() && "Already initialized."); - InstanceImpl().emplace(); -} - -void FileSystem::Initialize(IntrusiveRefCntPtr<vfs::FileSystem> fs) { - lldbassert(!InstanceImpl() && "Already initialized."); - InstanceImpl().emplace(fs); -} - void FileSystem::Terminate() { lldbassert(InstanceImpl() && "Already terminated."); InstanceImpl().reset(); @@ -192,7 +180,7 @@ void FileSystem::EnumerateDirectory(Twine path, bool find_directories, const auto &Item = *Iter; ErrorOr<vfs::Status> Status = m_fs->status(Item.path()); if (!Status) - break; + continue; if (!find_files && Status->isRegularFile()) continue; if (!find_directories && Status->isDirectory()) @@ -239,9 +227,9 @@ void FileSystem::Resolve(SmallVectorImpl<char> &path) { // Resolve tilde in path. SmallString<128> resolved(path.begin(), path.end()); - StandardTildeExpressionResolver Resolver; - Resolver.ResolveFullPath(llvm::StringRef(path.begin(), path.size()), - resolved); + assert(m_tilde_resolver && "must initialize tilde resolver in constructor"); + m_tilde_resolver->ResolveFullPath(llvm::StringRef(path.begin(), path.size()), + resolved); // Try making the path absolute if it exists. SmallString<128> absolute(resolved.begin(), resolved.end()); diff --git a/contrib/llvm-project/lldb/source/Host/common/Host.cpp b/contrib/llvm-project/lldb/source/Host/common/Host.cpp index 33b550008b74..49eac0b0fa7b 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Host.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Host.cpp @@ -546,9 +546,11 @@ void Host::Kill(lldb::pid_t pid, int signo) { ::kill(pid, signo); } #endif #if !defined(__APPLE__) -bool Host::OpenFileInExternalEditor(const FileSpec &file_spec, - uint32_t line_no) { - return false; +llvm::Error Host::OpenFileInExternalEditor(llvm::StringRef editor, + const FileSpec &file_spec, + uint32_t line_no) { + return llvm::errorCodeToError( + std::error_code(ENOTSUP, std::system_category())); } bool Host::IsInteractiveGraphicSession() { return false; } diff --git a/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp b/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp index d5e5628e5559..5c44c2f38b28 100644 --- a/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/HostInfoBase.cpp @@ -18,12 +18,12 @@ #include "lldb/Utility/StreamString.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Support/Host.h" #include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/Threading.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/Triple.h" #include <mutex> #include <optional> @@ -225,24 +225,20 @@ bool HostInfoBase::ComputePathRelativeToLibrary(FileSpec &file_spec, return false; std::string raw_path = lldb_file_spec.GetPath(); - LLDB_LOGF(log, - "HostInfo::%s() attempting to " - "derive the path %s relative to liblldb install path: %s", - __FUNCTION__, dir.data(), raw_path.c_str()); + LLDB_LOG( + log, + "Attempting to derive the path {0} relative to liblldb install path: {1}", + dir, raw_path); // Drop bin (windows) or lib llvm::StringRef parent_path = llvm::sys::path::parent_path(raw_path); if (parent_path.empty()) { - LLDB_LOGF(log, - "HostInfo::%s() failed to find liblldb within the shared " - "lib path", - __FUNCTION__); + LLDB_LOG(log, "Failed to find liblldb within the shared lib path"); return false; } raw_path = (parent_path + dir).str(); - LLDB_LOGF(log, "HostInfo::%s() derived the path as: %s", __FUNCTION__, - raw_path.c_str()); + LLDB_LOG(log, "Derived the path as: {0}", raw_path); file_spec.SetDirectory(raw_path); return (bool)file_spec.GetDirectory(); } diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp index 975b3d0f7d53..b3ef8f027bcf 100644 --- a/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp @@ -503,6 +503,7 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { static const uint8_t g_i386_opcode[] = {0xCC}; static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d}; static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00}; + static const uint8_t g_msp430_opcode[] = {0x43, 0x43}; static const uint8_t g_s390x_opcode[] = {0x00, 0x01}; static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; // trap static const uint8_t g_ppcle_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap @@ -528,6 +529,9 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { case llvm::Triple::mips64el: return llvm::ArrayRef(g_mips64el_opcode); + case llvm::Triple::msp430: + return llvm::ArrayRef(g_msp430_opcode); + case llvm::Triple::systemz: return llvm::ArrayRef(g_s390x_opcode); @@ -759,4 +763,4 @@ void NativeProcessProtocol::DoStopIDBumped(uint32_t /* newBumpId */) { // Default implementation does nothing. } -NativeProcessProtocol::Factory::~Factory() = default; +NativeProcessProtocol::Manager::~Manager() = default; diff --git a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp index 1be519d129ee..40a57f3d5c82 100644 --- a/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/NativeRegisterContext.cpp @@ -125,15 +125,12 @@ lldb::addr_t NativeRegisterContext::GetPC(lldb::addr_t fail_value) { uint32_t reg = ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); - LLDB_LOGF(log, - "NativeRegisterContext::%s using reg index %" PRIu32 - " (default %" PRIu64 ")", - __FUNCTION__, reg, fail_value); + LLDB_LOGF(log, "Using reg index %" PRIu32 " (default %" PRIu64 ")", reg, + fail_value); const uint64_t retval = ReadRegisterAsUnsigned(reg, fail_value); - LLDB_LOGF(log, "NativeRegisterContext::%s " PRIu32 " retval %" PRIu64, - __FUNCTION__, retval); + LLDB_LOGF(log, PRIu32 " retval %" PRIu64, retval); return retval; } @@ -203,18 +200,15 @@ NativeRegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info, Status error = ReadRegister(reg_info, value); if (error.Success()) { LLDB_LOGF(log, - "NativeRegisterContext::%s ReadRegister() succeeded, value " + "Read register succeeded: value " "%" PRIu64, - __FUNCTION__, value.GetAsUInt64()); + value.GetAsUInt64()); return value.GetAsUInt64(); } else { - LLDB_LOGF(log, - "NativeRegisterContext::%s ReadRegister() failed, error %s", - __FUNCTION__, error.AsCString()); + LLDB_LOGF(log, "Read register failed: error %s", error.AsCString()); } } else { - LLDB_LOGF(log, "NativeRegisterContext::%s ReadRegister() null reg_info", - __FUNCTION__); + LLDB_LOGF(log, "Read register failed: null reg_info"); } return fail_value; } @@ -222,7 +216,7 @@ NativeRegisterContext::ReadRegisterAsUnsigned(const RegisterInfo *reg_info, Status NativeRegisterContext::WriteRegisterFromUnsigned(uint32_t reg, uint64_t uval) { if (reg == LLDB_INVALID_REGNUM) - return Status("NativeRegisterContext::%s (): reg is invalid", __FUNCTION__); + return Status("Write register failed: reg is invalid"); return WriteRegisterFromUnsigned(GetRegisterInfoAtIndex(reg), uval); } @@ -337,11 +331,6 @@ Status NativeRegisterContext::ReadRegisterValueFromMemory( // |AABB| Address contents // |AABB0000| Register contents [on little-endian hardware] // |0000AABB| Register contents [on big-endian hardware] - if (src_len > RegisterValue::kMaxRegisterByteSize) { - error.SetErrorString("register too small to receive memory data"); - return error; - } - const size_t dst_len = reg_info->byte_size; if (src_len > dst_len) { @@ -354,11 +343,11 @@ Status NativeRegisterContext::ReadRegisterValueFromMemory( } NativeProcessProtocol &process = m_thread.GetProcess(); - uint8_t src[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer src(src_len); // Read the memory size_t bytes_read; - error = process.ReadMemory(src_addr, src, src_len, bytes_read); + error = process.ReadMemory(src_addr, src.data(), src_len, bytes_read); if (error.Fail()) return error; @@ -376,8 +365,8 @@ Status NativeRegisterContext::ReadRegisterValueFromMemory( // TODO: we might need to add a parameter to this function in case the byte // order of the memory data doesn't match the process. For now we are // assuming they are the same. - reg_value.SetFromMemoryData(*reg_info, src, src_len, process.GetByteOrder(), - error); + reg_value.SetFromMemoryData(*reg_info, src.data(), src_len, + process.GetByteOrder(), error); return error; } @@ -391,21 +380,22 @@ Status NativeRegisterContext::WriteRegisterValueToMemory( return error; } - uint8_t dst[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer dst(dst_len); NativeProcessProtocol &process = m_thread.GetProcess(); // TODO: we might need to add a parameter to this function in case the byte // order of the memory data doesn't match the process. For now we are // assuming they are the same. const size_t bytes_copied = reg_value.GetAsMemoryData( - *reg_info, dst, dst_len, process.GetByteOrder(), error); + *reg_info, dst.data(), dst_len, process.GetByteOrder(), error); if (error.Success()) { if (bytes_copied == 0) { error.SetErrorString("byte copy failed."); } else { size_t bytes_written; - error = process.WriteMemory(dst_addr, dst, bytes_copied, bytes_written); + error = process.WriteMemory(dst_addr, dst.data(), bytes_copied, + bytes_written); if (error.Fail()) return error; diff --git a/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp b/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp index b8827992bc7a..a1866b2a99fd 100644 --- a/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/ProcessLaunchInfo.cpp @@ -31,9 +31,8 @@ using namespace lldb_private; ProcessLaunchInfo::ProcessLaunchInfo() : ProcessInfo(), m_working_dir(), m_plugin_name(), m_flags(0), - m_file_actions(), m_pty(new PseudoTerminal), m_monitor_callback(nullptr), - m_listener_sp(), m_hijack_listener_sp(), m_scripted_process_class_name(), - m_scripted_process_dictionary_sp() {} + m_file_actions(), m_pty(new PseudoTerminal), m_monitor_callback(nullptr) { +} ProcessLaunchInfo::ProcessLaunchInfo(const FileSpec &stdin_file_spec, const FileSpec &stdout_file_spec, @@ -41,8 +40,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_scripted_process_class_name(), m_scripted_process_dictionary_sp() { + m_file_actions(), m_pty(new PseudoTerminal) { if (stdin_file_spec) { FileAction file_action; const bool read = true; @@ -128,8 +126,8 @@ void ProcessLaunchInfo::SetWorkingDirectory(const FileSpec &working_dir) { m_working_dir = working_dir; } -const char *ProcessLaunchInfo::GetProcessPluginName() const { - return (m_plugin_name.empty() ? nullptr : m_plugin_name.c_str()); +llvm::StringRef ProcessLaunchInfo::GetProcessPluginName() const { + return llvm::StringRef(m_plugin_name); } void ProcessLaunchInfo::SetProcessPluginName(llvm::StringRef plugin) { @@ -171,8 +169,6 @@ void ProcessLaunchInfo::Clear() { m_resume_count = 0; m_listener_sp.reset(); m_hijack_listener_sp.reset(); - m_scripted_process_class_name.clear(); - m_scripted_process_dictionary_sp.reset(); } void ProcessLaunchInfo::NoOpMonitorCallback(lldb::pid_t pid, int signal, @@ -186,8 +182,8 @@ bool ProcessLaunchInfo::MonitorProcess() const { llvm::Expected<HostThread> maybe_thread = Host::StartMonitoringChildProcess(m_monitor_callback, GetProcessID()); if (!maybe_thread) - LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", - llvm::toString(maybe_thread.takeError())); + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), maybe_thread.takeError(), + "failed to launch host thread: {0}"); return true; } return false; @@ -325,6 +321,8 @@ bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell( } else { for (size_t i = 0; argv[i] != nullptr; ++i) { std::string safe_arg = Args::GetShellSafeArgument(m_shell, argv[i]); + if (safe_arg.empty()) + safe_arg = "\"\""; // Add a space to separate this arg from the previous one. shell_command.PutCString(" "); shell_command.PutCString(safe_arg); diff --git a/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp b/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp index be4c3c7928df..de49058beeb7 100644 --- a/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/PseudoTerminal.cpp @@ -8,6 +8,7 @@ #include "lldb/Host/PseudoTerminal.h" #include "lldb/Host/Config.h" +#include "lldb/Host/FileSystem.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Errno.h" #include <cassert> @@ -95,7 +96,7 @@ llvm::Error PseudoTerminal::OpenSecondary(int oflag) { CloseSecondaryFileDescriptor(); std::string name = GetSecondaryName(); - m_secondary_fd = llvm::sys::RetryAfterSignal(-1, ::open, name.c_str(), oflag); + m_secondary_fd = FileSystem::Instance().Open(name.c_str(), oflag); if (m_secondary_fd >= 0) return llvm::Error::success(); diff --git a/contrib/llvm-project/lldb/source/Host/common/Socket.cpp b/contrib/llvm-project/lldb/source/Host/common/Socket.cpp index c2fb5509034e..8ccb27fdd7f4 100644 --- a/contrib/llvm-project/lldb/source/Host/common/Socket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/Socket.cpp @@ -17,6 +17,7 @@ #include "lldb/Utility/Log.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/Errno.h" #include "llvm/Support/Error.h" #include "llvm/Support/Regex.h" diff --git a/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp b/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp index 82b00ac561f9..df4737216ed3 100644 --- a/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/TCPSocket.cpp @@ -150,7 +150,7 @@ Status TCPSocket::CreateSocket(int domain) { Status TCPSocket::Connect(llvm::StringRef name) { Log *log = GetLog(LLDBLog::Communication); - LLDB_LOGF(log, "TCPSocket::%s (host/port = %s)", __FUNCTION__, name.data()); + LLDB_LOG(log, "Connect to host/port {0}", name); Status error; llvm::Expected<HostAndPort> host_port = DecodeHostAndPort(name); @@ -189,7 +189,7 @@ Status TCPSocket::Connect(llvm::StringRef name) { Status TCPSocket::Listen(llvm::StringRef name, int backlog) { Log *log = GetLog(LLDBLog::Connection); - LLDB_LOGF(log, "TCPSocket::%s (%s)", __FUNCTION__, name.data()); + LLDB_LOG(log, "Listen to {0}", name); Status error; llvm::Expected<HostAndPort> host_port = DecodeHostAndPort(name); diff --git a/contrib/llvm-project/lldb/source/Host/common/XML.cpp b/contrib/llvm-project/lldb/source/Host/common/XML.cpp index 2d48175a8234..f480ef3166a4 100644 --- a/contrib/llvm-project/lldb/source/Host/common/XML.cpp +++ b/contrib/llvm-project/lldb/source/Host/common/XML.cpp @@ -9,6 +9,8 @@ #include "lldb/Host/Config.h" #include "lldb/Host/XML.h" +#include "llvm/ADT/StringExtras.h" + using namespace lldb; using namespace lldb_private; @@ -490,7 +492,7 @@ static StructuredData::ObjectSP CreatePlistValue(XMLNode node) { } else if (element_name == "integer") { uint64_t value = 0; node.GetElementTextAsUnsigned(value, 0, 0); - return StructuredData::ObjectSP(new StructuredData::Integer(value)); + return StructuredData::ObjectSP(new StructuredData::UnsignedInteger(value)); } else if ((element_name == "string") || (element_name == "data") || (element_name == "date")) { std::string text; diff --git a/contrib/llvm-project/lldb/source/Host/common/ZipFileResolver.cpp b/contrib/llvm-project/lldb/source/Host/common/ZipFileResolver.cpp new file mode 100644 index 000000000000..f70ccb79d089 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Host/common/ZipFileResolver.cpp @@ -0,0 +1,72 @@ +//===-- ZipFileResolver.cpp -----------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Host/common/ZipFileResolver.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/ZipFile.h" + +using namespace lldb_private; +using namespace llvm::support; + +bool ZipFileResolver::ResolveSharedLibraryPath(const FileSpec &file_spec, + FileKind &file_kind, + std::string &file_path, + lldb::offset_t &so_file_offset, + lldb::offset_t &so_file_size) { + // When bionic loads .so file from APK or zip file, this file_spec will be + // "zip_path!/so_path". Otherwise it is just a normal file path. + static constexpr llvm::StringLiteral k_zip_separator("!/"); + std::string path(file_spec.GetPath()); + size_t pos = path.find(k_zip_separator); + +#if defined(_WIN32) + // When the file_spec is resolved as a Windows path, the zip .so path will be + // "zip_path!\so_path". Support both patterns on Windows. + static constexpr llvm::StringLiteral k_zip_separator_win("!\\"); + if (pos == std::string::npos) + pos = path.find(k_zip_separator_win); +#endif + + if (pos == std::string::npos) { + // This file_spec does not contain the zip separator. + // Treat this file_spec as a normal file. + // so_file_offset and so_file_size should be 0. + file_kind = FileKind::eFileKindNormal; + file_path = path; + so_file_offset = 0; + so_file_size = 0; + return true; + } + + // This file_spec is a zip .so path. Extract the zip path and the .so path. + std::string zip_path(path.substr(0, pos)); + std::string so_path(path.substr(pos + k_zip_separator.size())); + +#if defined(_WIN32) + // Replace the .so path to use POSIX file separator for file searching inside + // the zip file. + std::replace(so_path.begin(), so_path.end(), '\\', '/'); +#endif + + // Try to find the .so file from the zip file. + FileSpec zip_file_spec(zip_path); + uint64_t zip_file_size = FileSystem::Instance().GetByteSize(zip_file_spec); + lldb::DataBufferSP zip_data = + FileSystem::Instance().CreateDataBuffer(zip_file_spec, zip_file_size); + if (ZipFile::Find(zip_data, so_path, so_file_offset, so_file_size)) { + // Found the .so file from the zip file and got the file offset and size. + // Return the zip path. so_file_offset and so_file_size are already set. + file_kind = FileKind::eFileKindZip; + file_path = zip_path; + return true; + } + + return false; +} diff --git a/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp b/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp index f93581651273..110e803b3354 100644 --- a/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp +++ b/contrib/llvm-project/lldb/source/Host/freebsd/Host.cpp @@ -31,7 +31,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" -#include "llvm/Support/Host.h" +#include "llvm/TargetParser/Host.h" extern "C" { extern char **environ; diff --git a/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp b/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp index 9168ed97b77e..c47b96a5ceda 100644 --- a/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Host/netbsd/HostNetBSD.cpp @@ -33,7 +33,7 @@ #include "lldb/Utility/StreamString.h" #include "llvm/Object/ELF.h" -#include "llvm/Support/Host.h" +#include "llvm/TargetParser/Host.h" extern "C" { extern char **environ; diff --git a/contrib/llvm-project/lldb/source/Host/openbsd/Host.cpp b/contrib/llvm-project/lldb/source/Host/openbsd/Host.cpp index 799a61adbf26..9a7953e2bea4 100644 --- a/contrib/llvm-project/lldb/source/Host/openbsd/Host.cpp +++ b/contrib/llvm-project/lldb/source/Host/openbsd/Host.cpp @@ -28,7 +28,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" -#include "llvm/Support/Host.h" +#include "llvm/TargetParser/Host.h" extern "C" { extern char **environ; diff --git a/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp index dc5b24979fb5..825da09d7602 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -15,6 +15,7 @@ #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" #include "lldb/Host/Config.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Socket.h" #include "lldb/Host/SocketAddress.h" #include "lldb/Utility/LLDBLog.h" @@ -726,7 +727,7 @@ ConnectionStatus ConnectionFileDescriptor::ConnectFile( #if LLDB_ENABLE_POSIX std::string addr_str = s.str(); // file:///PATH - int fd = llvm::sys::RetryAfterSignal(-1, ::open, addr_str.c_str(), O_RDWR); + int fd = FileSystem::Instance().Open(addr_str.c_str(), O_RDWR); if (fd == -1) { if (error_ptr) error_ptr->SetErrorToErrno(); @@ -776,7 +777,7 @@ ConnectionStatus ConnectionFileDescriptor::ConnectSerialPort( return eConnectionStatusError; } - int fd = llvm::sys::RetryAfterSignal(-1, ::open, path.str().c_str(), O_RDWR); + int fd = FileSystem::Instance().Open(path.str().c_str(), O_RDWR); if (fd == -1) { if (error_ptr) error_ptr->SetErrorToErrno(); diff --git a/contrib/llvm-project/lldb/source/Host/posix/FileSystemPosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/FileSystemPosix.cpp index 26a266e86382..cdb76da626bc 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/FileSystemPosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/FileSystemPosix.cpp @@ -77,5 +77,8 @@ FILE *FileSystem::Fopen(const char *path, const char *mode) { } int FileSystem::Open(const char *path, int flags, int mode) { - return llvm::sys::RetryAfterSignal(-1, ::open, path, flags, mode); + // Call ::open in a lambda to avoid overload resolution in RetryAfterSignal + // when open is overloaded, such as in Bionic. + auto lambda = [&]() { return ::open(path, flags, mode); }; + return llvm::sys::RetryAfterSignal(-1, lambda); } diff --git a/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp b/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp index bd311ad8769a..5e4e8618fa4f 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/PipePosix.cpp @@ -7,11 +7,11 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/posix/PipePosix.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/SelectHelper.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/Errno.h" -#include "llvm/Support/FileSystem.h" #include <functional> #include <thread> @@ -148,7 +148,7 @@ Status PipePosix::OpenAsReader(llvm::StringRef name, flags |= O_CLOEXEC; Status error; - int fd = llvm::sys::RetryAfterSignal(-1, ::open, name.str().c_str(), flags); + int fd = FileSystem::Instance().Open(name.str().c_str(), flags); if (fd != -1) m_fds[READ] = fd; else diff --git a/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index a148c110e87b..0a832ebad13a 100644 --- a/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/contrib/llvm-project/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/posix/ProcessLauncherPosixFork.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/Pipe.h" @@ -14,7 +15,6 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" #include "llvm/Support/Errno.h" -#include "llvm/Support/FileSystem.h" #include <climits> #include <sys/ptrace.h> @@ -71,7 +71,7 @@ static void DisableASLR(int error_fd) { } static void DupDescriptor(int error_fd, const char *file, int fd, int flags) { - int target_fd = llvm::sys::RetryAfterSignal(-1, ::open, file, flags, 0666); + int target_fd = FileSystem::Instance().Open(file, flags, 0666); if (target_fd == -1) ExitWithError(error_fd, "DupDescriptor-open"); diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandAlias.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandAlias.cpp index e36edcac15a5..f6eaeacff81e 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandAlias.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandAlias.cpp @@ -8,6 +8,7 @@ #include "lldb/Interpreter/CommandAlias.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/ErrorHandling.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -211,9 +212,9 @@ std::pair<lldb::CommandObjectSP, OptionArgVectorSP> CommandAlias::Desugar() { // FIXME: This doesn't work if the original alias fills a slot in the // underlying alias, since this just appends the two lists. auto desugared = ((CommandAlias *)underlying.get())->Desugar(); - auto options = GetOptionArguments(); - options->insert(options->begin(), desugared.second->begin(), - desugared.second->end()); + OptionArgVectorSP options = std::make_shared<OptionArgVector>(); + llvm::append_range(*options, *desugared.second); + llvm::append_range(*options, *GetOptionArguments()); return {desugared.first, options}; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp index 8b24c72d7733..f78fc728c898 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandInterpreter.cpp @@ -146,73 +146,73 @@ CommandInterpreter::CommandInterpreter(Debugger &debugger, bool CommandInterpreter::GetExpandRegexAliases() const { const uint32_t idx = ePropertyExpandRegexAliases; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } bool CommandInterpreter::GetPromptOnQuit() const { const uint32_t idx = ePropertyPromptOnQuit; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } void CommandInterpreter::SetPromptOnQuit(bool enable) { const uint32_t idx = ePropertyPromptOnQuit; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); + SetPropertyAtIndex(idx, enable); } bool CommandInterpreter::GetSaveSessionOnQuit() const { const uint32_t idx = ePropertySaveSessionOnQuit; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } void CommandInterpreter::SetSaveSessionOnQuit(bool enable) { const uint32_t idx = ePropertySaveSessionOnQuit; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); + SetPropertyAtIndex(idx, enable); } bool CommandInterpreter::GetOpenTranscriptInEditor() const { const uint32_t idx = ePropertyOpenTranscriptInEditor; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } void CommandInterpreter::SetOpenTranscriptInEditor(bool enable) { const uint32_t idx = ePropertyOpenTranscriptInEditor; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); + SetPropertyAtIndex(idx, enable); } FileSpec CommandInterpreter::GetSaveSessionDirectory() const { const uint32_t idx = ePropertySaveSessionDirectory; - return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } void CommandInterpreter::SetSaveSessionDirectory(llvm::StringRef path) { const uint32_t idx = ePropertySaveSessionDirectory; - m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); + SetPropertyAtIndex(idx, path); } bool CommandInterpreter::GetEchoCommands() const { const uint32_t idx = ePropertyEchoCommands; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } void CommandInterpreter::SetEchoCommands(bool enable) { const uint32_t idx = ePropertyEchoCommands; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); + SetPropertyAtIndex(idx, enable); } bool CommandInterpreter::GetEchoCommentCommands() const { const uint32_t idx = ePropertyEchoCommentCommands; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } void CommandInterpreter::SetEchoCommentCommands(bool enable) { const uint32_t idx = ePropertyEchoCommentCommands; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, enable); + SetPropertyAtIndex(idx, enable); } void CommandInterpreter::AllowExitCodeOnQuit(bool allow) { @@ -246,26 +246,26 @@ void CommandInterpreter::ResolveCommand(const char *command_line, bool CommandInterpreter::GetStopCmdSourceOnError() const { const uint32_t idx = ePropertyStopCmdSourceOnError; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } bool CommandInterpreter::GetSpaceReplPrompts() const { const uint32_t idx = ePropertySpaceReplPrompts; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } bool CommandInterpreter::GetRepeatPreviousCommand() const { const uint32_t idx = ePropertyRepeatPreviousCommand; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_interpreter_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + 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); + return GetPropertyAtIndexAs<bool>( + idx, g_interpreter_properties[idx].default_uint_value != 0); } void CommandInterpreter::Initialize() { @@ -413,17 +413,21 @@ void CommandInterpreter::Initialize() { alias_arguments_vector_sp = std::make_shared<OptionArgVector>(); - cmd_obj_sp = GetCommandSPExact("expression"); + cmd_obj_sp = GetCommandSPExact("dwim-print"); if (cmd_obj_sp) { AddAlias("p", cmd_obj_sp, "--")->SetHelpLong(""); AddAlias("print", cmd_obj_sp, "--")->SetHelpLong(""); - AddAlias("call", cmd_obj_sp, "--")->SetHelpLong(""); if (auto *po = AddAlias("po", cmd_obj_sp, "-O --")) { po->SetHelp("Evaluate an expression on the current thread. Displays any " "returned value with formatting " "controlled by the type's author."); po->SetHelpLong(""); } + } + + cmd_obj_sp = GetCommandSPExact("expression"); + if (cmd_obj_sp) { + AddAlias("call", cmd_obj_sp, "--")->SetHelpLong(""); CommandAlias *parray_alias = AddAlias("parray", cmd_obj_sp, "--element-count %1 --"); if (parray_alias) { @@ -612,10 +616,7 @@ void CommandInterpreter::LoadCommandDictionary() { "current file\n" " // containing text 'break " "here'.\n", - 3, - CommandCompletions::eSymbolCompletion | - CommandCompletions::eSourceFileCompletion, - false)); + lldb::eSymbolCompletion | lldb::eSourceFileCompletion, false)); if (break_regex_cmd_up) { bool success = true; @@ -666,10 +667,7 @@ void CommandInterpreter::LoadCommandDictionary() { "current file\n" " // containing text 'break " "here'.\n", - 2, - CommandCompletions::eSymbolCompletion | - CommandCompletions::eSourceFileCompletion, - false)); + lldb::eSymbolCompletion | lldb::eSourceFileCompletion, false)); if (tbreak_regex_cmd_up) { bool success = true; @@ -694,7 +692,7 @@ void CommandInterpreter::LoadCommandDictionary() { std::unique_ptr<CommandObjectRegexCommand> attach_regex_cmd_up( new CommandObjectRegexCommand( *this, "_regexp-attach", "Attach to process by ID or name.", - "_regexp-attach <pid> | <process-name>", 2, 0, false)); + "_regexp-attach <pid> | <process-name>", 0, false)); if (attach_regex_cmd_up) { if (attach_regex_cmd_up->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") && @@ -716,7 +714,7 @@ void CommandInterpreter::LoadCommandDictionary() { "Select a newer stack frame. Defaults to " "moving one frame, a numeric argument can " "specify an arbitrary number.", - "_regexp-down [<count>]", 2, 0, false)); + "_regexp-down [<count>]", 0, false)); if (down_regex_cmd_up) { if (down_regex_cmd_up->AddRegexCommand("^$", "frame select -r -1") && down_regex_cmd_up->AddRegexCommand("^([0-9]+)$", @@ -732,7 +730,7 @@ void CommandInterpreter::LoadCommandDictionary() { *this, "_regexp-up", "Select an older stack frame. Defaults to moving one " "frame, a numeric argument can specify an arbitrary number.", - "_regexp-up [<count>]", 2, 0, false)); + "_regexp-up [<count>]", 0, false)); if (up_regex_cmd_up) { if (up_regex_cmd_up->AddRegexCommand("^$", "frame select -r 1") && up_regex_cmd_up->AddRegexCommand("^([0-9]+)$", "frame select -r %1")) { @@ -746,7 +744,7 @@ void CommandInterpreter::LoadCommandDictionary() { new CommandObjectRegexCommand( *this, "_regexp-display", "Evaluate an expression at every stop (see 'help target stop-hook'.)", - "_regexp-display expression", 2, 0, false)); + "_regexp-display expression", 0, false)); if (display_regex_cmd_up) { if (display_regex_cmd_up->AddRegexCommand( "^(.+)$", "target stop-hook add -o \"expr -- %1\"")) { @@ -760,7 +758,7 @@ void CommandInterpreter::LoadCommandDictionary() { new CommandObjectRegexCommand(*this, "_regexp-undisplay", "Stop displaying expression at every " "stop (specified by stop-hook index.)", - "_regexp-undisplay stop-hook-number", 2, 0, + "_regexp-undisplay stop-hook-number", 0, false)); if (undisplay_regex_cmd_up) { if (undisplay_regex_cmd_up->AddRegexCommand("^([0-9]+)$", @@ -778,7 +776,7 @@ void CommandInterpreter::LoadCommandDictionary() { "If no host is specifed, localhost is assumed.\n" "gdb-remote is an abbreviation for 'process connect --plugin " "gdb-remote connect://<hostname>:<port>'\n", - "gdb-remote [<hostname>:]<portnum>", 2, 0, false)); + "gdb-remote [<hostname>:]<portnum>", 0, false)); if (connect_gdb_remote_cmd_up) { if (connect_gdb_remote_cmd_up->AddRegexCommand( "^([^:]+|\\[[0-9a-fA-F:]+.*\\]):([0-9]+)$", @@ -798,7 +796,7 @@ void CommandInterpreter::LoadCommandDictionary() { "If no UDP port is specified, port 41139 is assumed.\n" "kdp-remote is an abbreviation for 'process connect --plugin " "kdp-remote udp://<hostname>:<port>'\n", - "kdp-remote <hostname>[:<portnum>]", 2, 0, false)); + "kdp-remote <hostname>[:<portnum>]", 0, false)); if (connect_kdp_remote_cmd_up) { if (connect_kdp_remote_cmd_up->AddRegexCommand( "^([^:]+:[[:digit:]]+)$", @@ -818,7 +816,7 @@ void CommandInterpreter::LoadCommandDictionary() { "frames. The argument 'all' displays all threads. Use 'settings" " set frame-format' to customize the printing of individual frames " "and 'settings set thread-format' to customize the thread header.", - "bt [<digit> | all]", 2, 0, false)); + "bt [<digit> | all]", 0, false)); if (bt_regex_cmd_up) { // accept but don't document "bt -c <number>" -- before bt was a regex // command if you wanted to backtrace three frames you would do "bt -c 3" @@ -847,7 +845,7 @@ void CommandInterpreter::LoadCommandDictionary() { "_regexp-list 0x<address> // List around specified address\n" "_regexp-list -[<count>] // List previous <count> lines\n" "_regexp-list // List subsequent lines", - 2, CommandCompletions::eSourceFileCompletion, false)); + lldb::eSourceFileCompletion, false)); if (list_regex_cmd_up) { if (list_regex_cmd_up->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") && @@ -879,7 +877,7 @@ void CommandInterpreter::LoadCommandDictionary() { "\n" "_regexp-env // Show environment\n" "_regexp-env <name>=<value> // Set an environment variable", - 2, 0, false)); + 0, false)); if (env_regex_cmd_up) { if (env_regex_cmd_up->AddRegexCommand("^$", "settings show target.env-vars") && @@ -899,7 +897,7 @@ void CommandInterpreter::LoadCommandDictionary() { "_regexp-jump +<line-offset> | -<line-offset>\n" "_regexp-jump <file>:<line>\n" "_regexp-jump *<addr>\n", - 2, 0, false)); + 0, false)); if (jump_regex_cmd_up) { if (jump_regex_cmd_up->AddRegexCommand("^\\*(.*)$", "thread jump --addr %1") && @@ -1372,11 +1370,12 @@ bool CommandInterpreter::RemoveAlias(llvm::StringRef alias_name) { return false; } -bool CommandInterpreter::RemoveCommand(llvm::StringRef cmd) { +bool CommandInterpreter::RemoveCommand(llvm::StringRef cmd, bool force) { auto pos = m_command_dict.find(std::string(cmd)); if (pos != m_command_dict.end()) { - if (pos->second->IsRemovable()) { - // Only regular expression objects or python commands are removable + if (force || pos->second->IsRemovable()) { + // Only regular expression objects or python commands are removable under + // normal circumstances. m_command_dict.erase(pos); return true; } @@ -1687,20 +1686,19 @@ CommandObject *CommandInterpreter::BuildAliasResult( return nullptr; } llvm::StringRef arg_text = entry.ref(); - if (strpos - start_fudge + arg_text.size() + len_fudge - > raw_input_string.size()) { + if (strpos - start_fudge + arg_text.size() + len_fudge > + raw_input_string.size()) { result.AppendError("Unmatched quote at command end."); - return nullptr; + return nullptr; } raw_input_string = raw_input_string.erase( - strpos - start_fudge, + strpos - start_fudge, strlen(cmd_args.GetArgumentAtIndex(index)) + len_fudge); } if (quote_char == '\0') result_str.Printf("%s", cmd_args.GetArgumentAtIndex(index)); else - result_str.Printf("%c%s%c", quote_char, - entry.c_str(), quote_char); + result_str.Printf("%c%s%c", quote_char, entry.c_str(), quote_char); } } @@ -1748,112 +1746,124 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) { std::string expr_str(command, expr_content_start, end_backtick - expr_content_start); + error = PreprocessToken(expr_str); + // We always stop at the first error: + if (error.Fail()) + break; - ExecutionContext exe_ctx(GetExecutionContext()); + command.erase(start_backtick, end_backtick - start_backtick + 1); + command.insert(start_backtick, std::string(expr_str)); + pos = start_backtick + expr_str.size(); + } + return error; +} - // Get a dummy target to allow for calculator mode while processing - // backticks. This also helps break the infinite loop caused when target is - // null. - Target *exe_target = exe_ctx.GetTargetPtr(); - Target &target = exe_target ? *exe_target : m_debugger.GetDummyTarget(); - - ValueObjectSP expr_result_valobj_sp; - - EvaluateExpressionOptions options; - options.SetCoerceToId(false); - options.SetUnwindOnError(true); - options.SetIgnoreBreakpoints(true); - options.SetKeepInMemory(false); - options.SetTryAllThreads(true); - options.SetTimeout(std::nullopt); - - ExpressionResults expr_result = - target.EvaluateExpression(expr_str.c_str(), exe_ctx.GetFramePtr(), - expr_result_valobj_sp, options); - - if (expr_result == eExpressionCompleted) { - Scalar scalar; - if (expr_result_valobj_sp) - expr_result_valobj_sp = - expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable( - expr_result_valobj_sp->GetDynamicValueType(), true); - if (expr_result_valobj_sp->ResolveValue(scalar)) { - command.erase(start_backtick, end_backtick - start_backtick + 1); - StreamString value_strm; - const bool show_type = false; - scalar.GetValue(&value_strm, show_type); - size_t value_string_size = value_strm.GetSize(); - if (value_string_size) { - command.insert(start_backtick, std::string(value_strm.GetString())); - pos = start_backtick + value_string_size; - continue; - } else { - error.SetErrorStringWithFormat("expression value didn't result " - "in a scalar value for the " - "expression '%s'", - expr_str.c_str()); - break; - } - } else { - error.SetErrorStringWithFormat("expression value didn't result " - "in a scalar value for the " - "expression '%s'", - expr_str.c_str()); - break; - } +Status +CommandInterpreter::PreprocessToken(std::string &expr_str) { + Status error; + ExecutionContext exe_ctx(GetExecutionContext()); - continue; - } + // Get a dummy target to allow for calculator mode while processing + // backticks. This also helps break the infinite loop caused when target is + // null. + Target *exe_target = exe_ctx.GetTargetPtr(); + Target &target = exe_target ? *exe_target : m_debugger.GetDummyTarget(); - if (expr_result_valobj_sp) - error = expr_result_valobj_sp->GetError(); + ValueObjectSP expr_result_valobj_sp; - if (error.Success()) { - switch (expr_result) { - case eExpressionSetupError: - error.SetErrorStringWithFormat( - "expression setup error for the expression '%s'", expr_str.c_str()); - break; - case eExpressionParseError: - error.SetErrorStringWithFormat( - "expression parse error for the expression '%s'", expr_str.c_str()); - break; - case eExpressionResultUnavailable: - error.SetErrorStringWithFormat( - "expression error fetching result for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionCompleted: - break; - case eExpressionDiscarded: - error.SetErrorStringWithFormat( - "expression discarded for the expression '%s'", expr_str.c_str()); - break; - case eExpressionInterrupted: - error.SetErrorStringWithFormat( - "expression interrupted for the expression '%s'", expr_str.c_str()); - break; - case eExpressionHitBreakpoint: - error.SetErrorStringWithFormat( - "expression hit breakpoint for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionTimedOut: - error.SetErrorStringWithFormat( - "expression timed out for the expression '%s'", expr_str.c_str()); - break; - case eExpressionStoppedForDebug: - error.SetErrorStringWithFormat("expression stop at entry point " - "for debugging for the " + EvaluateExpressionOptions options; + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetKeepInMemory(false); + options.SetTryAllThreads(true); + options.SetTimeout(std::nullopt); + + ExpressionResults expr_result = + target.EvaluateExpression(expr_str.c_str(), exe_ctx.GetFramePtr(), + expr_result_valobj_sp, options); + + if (expr_result == eExpressionCompleted) { + Scalar scalar; + if (expr_result_valobj_sp) + expr_result_valobj_sp = + expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable( + expr_result_valobj_sp->GetDynamicValueType(), true); + if (expr_result_valobj_sp->ResolveValue(scalar)) { + + StreamString value_strm; + const bool show_type = false; + scalar.GetValue(&value_strm, show_type); + size_t value_string_size = value_strm.GetSize(); + if (value_string_size) { + expr_str = value_strm.GetData(); + } else { + error.SetErrorStringWithFormat("expression value didn't result " + "in a scalar value for the " "expression '%s'", expr_str.c_str()); - break; - case eExpressionThreadVanished: - error.SetErrorStringWithFormat( - "expression thread vanished for the expression '%s'", - expr_str.c_str()); - break; } + } else { + error.SetErrorStringWithFormat("expression value didn't result " + "in a scalar value for the " + "expression '%s'", + expr_str.c_str()); + } + return error; + } + + // If we have an error from the expression evaluation it will be in the + // ValueObject error, which won't be success and we will just report it. + // But if for some reason we didn't get a value object at all, then we will + // make up some helpful errors from the expression result. + if (expr_result_valobj_sp) + error = expr_result_valobj_sp->GetError(); + + if (error.Success()) { + switch (expr_result) { + case eExpressionSetupError: + error.SetErrorStringWithFormat( + "expression setup error for the expression '%s'", expr_str.c_str()); + break; + case eExpressionParseError: + error.SetErrorStringWithFormat( + "expression parse error for the expression '%s'", expr_str.c_str()); + break; + case eExpressionResultUnavailable: + error.SetErrorStringWithFormat( + "expression error fetching result for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionCompleted: + break; + case eExpressionDiscarded: + error.SetErrorStringWithFormat( + "expression discarded for the expression '%s'", expr_str.c_str()); + break; + case eExpressionInterrupted: + error.SetErrorStringWithFormat( + "expression interrupted for the expression '%s'", expr_str.c_str()); + break; + case eExpressionHitBreakpoint: + error.SetErrorStringWithFormat( + "expression hit breakpoint for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionTimedOut: + error.SetErrorStringWithFormat( + "expression timed out for the expression '%s'", expr_str.c_str()); + break; + case eExpressionStoppedForDebug: + error.SetErrorStringWithFormat("expression stop at entry point " + "for debugging for the " + "expression '%s'", + expr_str.c_str()); + break; + case eExpressionThreadVanished: + error.SetErrorStringWithFormat( + "expression thread vanished for the expression '%s'", + expr_str.c_str()); + break; } } return error; @@ -1872,8 +1882,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line, bool CommandInterpreter::HandleCommand(const char *command_line, LazyBool lazy_add_to_history, - CommandReturnObject &result) { - + CommandReturnObject &result, + bool force_repeat_command) { std::string command_string(command_line); std::string original_command_string(command_line); @@ -1884,8 +1894,8 @@ bool CommandInterpreter::HandleCommand(const char *command_line, LLDB_LOGF(log, "Processing command: %s", command_line); LLDB_SCOPED_TIMERF("Processing command: %s.", command_line); - if (WasInterrupted()) { - result.AppendError("interrupted"); + if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted initiating command")) { + result.AppendError("... Interrupted"); return false; } @@ -1968,11 +1978,11 @@ bool CommandInterpreter::HandleCommand(const char *command_line, CommandObject *cmd_obj = ResolveCommandImpl(command_string, result); - // We have to preprocess the whole command string for Raw commands, since we + // We have to preprocess the whole command string for Raw commands, since we // don't know the structure of the command. For parsed commands, we only // treat backticks as quote characters specially. // FIXME: We probably want to have raw commands do their own preprocessing. - // For instance, I don't think people expect substitution in expr expressions. + // For instance, I don't think people expect substitution in expr expressions. if (cmd_obj && cmd_obj->WantsRawCommandString()) { Status error(PreprocessCommand(command_string)); @@ -2002,17 +2012,26 @@ bool CommandInterpreter::HandleCommand(const char *command_line, // arguments. if (cmd_obj != nullptr) { + bool generate_repeat_command = 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) { + generate_repeat_command |= empty_command; + // For `command regex`, the regex command (ex `bt`) is added to history, but + // the resolved command (ex `thread backtrace`) is _not_ added to history. + // However, the resolved command must be given the opportunity to provide a + // repeat command. `force_repeat_command` supports this case. + generate_repeat_command |= force_repeat_command; + if (generate_repeat_command) { Args command_args(command_string); std::optional<std::string> repeat_command = cmd_obj->GetRepeatCommand(command_args, 0); - if (repeat_command) + if (repeat_command) { + LLDB_LOGF(log, "Repeat command: %s", repeat_command->data()); m_repeat_command.assign(*repeat_command); - else + } else { m_repeat_command.assign(original_command_string); + } } if (add_to_history) @@ -2544,7 +2563,7 @@ void CommandInterpreter::HandleCommands(const StringList &commands, m_debugger.SetAsyncExecution(false); } - for (size_t idx = 0; idx < num_lines && !WasInterrupted(); idx++) { + for (size_t idx = 0; idx < num_lines; idx++) { const char *cmd = commands.GetStringAtIndex(idx); if (cmd[0] == '\0') continue; @@ -3024,6 +3043,9 @@ bool CommandInterpreter::InterruptCommand() { } bool CommandInterpreter::WasInterrupted() const { + if (!m_debugger.IsIOHandlerThreadCurrentThread()) + return false; + bool was_interrupted = (m_command_state == CommandHandlingState::eInterrupted); lldbassert(!was_interrupted || m_iohandler_nesting_level > 0); @@ -3037,7 +3059,8 @@ void CommandInterpreter::PrintCommandOutput(IOHandler &io_handler, lldb::StreamFileSP stream = is_stdout ? io_handler.GetOutputStreamFileSP() : io_handler.GetErrorStreamFileSP(); // Split the output into lines and poll for interrupt requests - while (!str.empty() && !WasInterrupted()) { + bool had_output = !str.empty(); + while (!str.empty()) { llvm::StringRef line; std::tie(line, str) = str.split('\n'); { @@ -3048,7 +3071,8 @@ void CommandInterpreter::PrintCommandOutput(IOHandler &io_handler, } std::lock_guard<std::recursive_mutex> guard(io_handler.GetOutputMutex()); - if (!str.empty()) + if (had_output && INTERRUPT_REQUESTED(GetDebugger(), + "Interrupted dumping command output")) stream->Printf("\n... Interrupted.\n"); stream->Flush(); } @@ -3243,8 +3267,11 @@ bool CommandInterpreter::SaveTranscript( if (GetOpenTranscriptInEditor() && Host::IsInteractiveGraphicSession()) { const FileSpec file_spec; error = file->GetFileSpec(const_cast<FileSpec &>(file_spec)); - if (error.Success()) - Host::OpenFileInExternalEditor(file_spec, 1); + if (error.Success()) { + if (llvm::Error e = Host::OpenFileInExternalEditor( + m_debugger.GetExternalEditor(), file_spec, 1)) + result.AppendError(llvm::toString(std::move(e))); + } } return true; @@ -3361,7 +3388,13 @@ CommandInterpreterRunResult CommandInterpreter::RunCommandInterpreter( if (options.GetSpawnThread()) { m_debugger.StartIOHandlerThread(); } else { + // If the current thread is not managed by a host thread, we won't detect + // that this IS the CommandInterpreter IOHandler thread, so make it so: + HostThread new_io_handler_thread(Host::GetCurrentThread()); + HostThread old_io_handler_thread = + m_debugger.SetIOHandlerThread(new_io_handler_thread); m_debugger.RunIOHandlers(); + m_debugger.SetIOHandlerThread(old_io_handler_thread); if (options.GetAutoHandleEvents()) m_debugger.StopEventHandlerThread(); diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp index 4500378c6229..313d24f0657b 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandObject.cpp @@ -23,11 +23,11 @@ // These are for the Sourcename completers. // FIXME: Make a separate file for the completers. -#include "lldb/Core/FileSpecList.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/FileSpecList.h" #include "lldb/Target/Language.h" @@ -727,10 +727,14 @@ bool CommandObjectParsed::Execute(const char *args_string, } if (!handled) { for (auto entry : llvm::enumerate(cmd_args.entries())) { - if (!entry.value().ref().empty() && entry.value().GetQuoteChar() == '`') { - cmd_args.ReplaceArgumentAtIndex( - entry.index(), - m_interpreter.ProcessEmbeddedScriptCommands(entry.value().c_str())); + const Args::ArgEntry &value = entry.value(); + if (!value.ref().empty() && value.GetQuoteChar() == '`') { + // We have to put the backtick back in place for PreprocessCommand. + std::string opt_string = value.c_str(); + Status error; + error = m_interpreter.PreprocessToken(opt_string); + if (error.Success()) + cmd_args.ReplaceArgumentAtIndex(entry.index(), opt_string); } } diff --git a/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp b/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp index 4433c43ff6d4..0bc58124f394 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/CommandReturnObject.cpp @@ -101,7 +101,10 @@ void CommandReturnObject::AppendError(llvm::StringRef in_string) { SetStatus(eReturnStatusFailed); if (in_string.empty()) return; - error(GetErrorStream()) << in_string.rtrim() << '\n'; + // Workaround to deal with already fully formatted compiler diagnostics. + llvm::StringRef msg(in_string.rtrim()); + msg.consume_front("error: "); + error(GetErrorStream()) << msg << '\n'; } void CommandReturnObject::SetError(const Status &error, diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionArgParser.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionArgParser.cpp index 63ca0f9d3d4d..ba2d3416e183 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionArgParser.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionArgParser.cpp @@ -140,16 +140,40 @@ lldb::ScriptLanguage OptionArgParser::ToScriptLanguage( return fail_value; } +lldb::addr_t OptionArgParser::ToRawAddress(const ExecutionContext *exe_ctx, + llvm::StringRef s, + lldb::addr_t fail_value, + Status *error_ptr) { + std::optional<lldb::addr_t> maybe_addr = DoToAddress(exe_ctx, s, error_ptr); + return maybe_addr ? *maybe_addr : fail_value; +} + lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, lldb::addr_t fail_value, Status *error_ptr) { + std::optional<lldb::addr_t> maybe_addr = DoToAddress(exe_ctx, s, error_ptr); + if (!maybe_addr) + return fail_value; + + lldb::addr_t addr = *maybe_addr; + + if (Process *process = exe_ctx->GetProcessPtr()) + if (ABISP abi_sp = process->GetABI()) + addr = abi_sp->FixCodeAddress(addr); + + return addr; +} + +std::optional<lldb::addr_t> +OptionArgParser::DoToAddress(const ExecutionContext *exe_ctx, llvm::StringRef s, + Status *error_ptr) { bool error_set = false; if (s.empty()) { if (error_ptr) error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", s.str().c_str()); - return fail_value; + return {}; } llvm::StringRef sref = s; @@ -158,10 +182,7 @@ lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx, if (!s.getAsInteger(0, addr)) { if (error_ptr) error_ptr->Clear(); - Process *process = exe_ctx->GetProcessPtr(); - if (process) - if (ABISP abi_sp = process->GetABI()) - addr = abi_sp->FixCodeAddress(addr); + return addr; } @@ -177,7 +198,7 @@ lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx, if (error_ptr) error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", s.str().c_str()); - return fail_value; + return {}; } lldb::ValueObjectSP valobj_sp; @@ -197,7 +218,7 @@ lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx, valobj_sp->GetDynamicValueType(), true); // Get the address to watch. if (valobj_sp) - addr = valobj_sp->GetValueAsUnsigned(fail_value, &success); + addr = valobj_sp->GetValueAsUnsigned(0, &success); if (success) { if (error_ptr) error_ptr->Clear(); @@ -249,5 +270,5 @@ lldb::addr_t OptionArgParser::ToAddress(const ExecutionContext *exe_ctx, error_ptr->SetErrorStringWithFormat("invalid address expression \"%s\"", s.str().c_str()); } - return fail_value; + return {}; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPlatform.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPlatform.cpp index 60107eb28806..9928a5cda03e 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPlatform.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -50,10 +50,10 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( if (!m_os_version.empty()) platform_sp->SetOSVersion(m_os_version); - if (m_sdk_sysroot) + if (!m_sdk_sysroot.empty()) platform_sp->SetSDKRootDirectory(m_sdk_sysroot); - if (m_sdk_build) + if (!m_sdk_build.empty()) platform_sp->SetSDKBuild(m_sdk_build); } @@ -63,8 +63,8 @@ PlatformSP OptionGroupPlatform::CreatePlatformWithOptions( void OptionGroupPlatform::OptionParsingStarting( ExecutionContext *execution_context) { m_platform_name.clear(); - m_sdk_sysroot.Clear(); - m_sdk_build.Clear(); + m_sdk_sysroot.clear(); + m_sdk_build.clear(); m_os_version = llvm::VersionTuple(); } @@ -103,7 +103,7 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx, switch (short_option) { case 'p': - m_platform_name.assign(std::string(option_arg)); + m_platform_name.assign(option_arg.str()); break; case 'v': @@ -113,11 +113,11 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx, break; case 'b': - m_sdk_build.SetString(option_arg); + m_sdk_build.assign(option_arg.str()); break; case 'S': - m_sdk_sysroot.SetString(option_arg); + m_sdk_sysroot.assign(option_arg.str()); break; default: @@ -128,21 +128,21 @@ OptionGroupPlatform::SetOptionValue(uint32_t option_idx, bool OptionGroupPlatform::PlatformMatches( const lldb::PlatformSP &platform_sp) const { - if (platform_sp) { - if (!m_platform_name.empty()) { - if (platform_sp->GetName() != m_platform_name) - return false; - } + if (!platform_sp) + return false; - if (m_sdk_build && m_sdk_build != platform_sp->GetSDKBuild()) - return false; + if (!m_platform_name.empty() && platform_sp->GetName() != m_platform_name) + return false; - if (m_sdk_sysroot && m_sdk_sysroot != platform_sp->GetSDKRootDirectory()) - return false; + if (!m_sdk_build.empty() && platform_sp->GetSDKBuild() != m_sdk_build) + return false; - if (!m_os_version.empty() && m_os_version != platform_sp->GetOSVersion()) - return false; - return true; - } - return false; + if (!m_sdk_sysroot.empty() && + platform_sp->GetSDKRootDirectory() != m_sdk_sysroot) + return false; + + if (!m_os_version.empty() && platform_sp->GetOSVersion() != m_os_version) + return false; + + return true; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp index a01c190266dd..8f507828518b 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupPythonClassWithDict.cpp @@ -102,8 +102,26 @@ Status OptionGroupPythonClassWithDict::SetOptionValue( if (!m_dict_sp) m_dict_sp = std::make_shared<StructuredData::Dictionary>(); if (!m_current_key.empty()) { - m_dict_sp->AddStringItem(m_current_key, option_arg); - m_current_key.clear(); + if (!option_arg.empty()) { + double d = 0; + std::string opt = option_arg.lower(); + + if (llvm::to_integer(option_arg, d)) { + if (opt[0] == '-') + m_dict_sp->AddIntegerItem(m_current_key, static_cast<int64_t>(d)); + else + m_dict_sp->AddIntegerItem(m_current_key, + static_cast<uint64_t>(d)); + } else if (llvm::to_float(option_arg, d)) { + m_dict_sp->AddFloatItem(m_current_key, d); + } else if (opt == "true" || opt == "false") { + m_dict_sp->AddBooleanItem(m_current_key, opt == "true"); + } else { + m_dict_sp->AddStringItem(m_current_key, option_arg); + } + } + + m_current_key.clear(); } else error.SetErrorStringWithFormat("Value: \"%s\" missing matching key.", diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupWatchpoint.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupWatchpoint.cpp index 5559e82d4722..c2f78d8c2dd1 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionGroupWatchpoint.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionGroupWatchpoint.cpp @@ -10,6 +10,7 @@ #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Target/Language.h" #include "lldb/lldb-enumerations.h" using namespace lldb; @@ -62,7 +63,17 @@ static constexpr OptionDefinition g_option_table[] = { "Specify the type of watching to perform."}, {LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument, nullptr, OptionEnumValues(g_watch_size), 0, eArgTypeByteSize, - "Number of bytes to use to watch a region."}}; + "Number of bytes to use to watch a region."}, + {LLDB_OPT_SET_2, + false, + "language", + 'l', + OptionParser::eRequiredArgument, + nullptr, + {}, + 0, + eArgTypeLanguage, + "Language of expression to run"}}; bool OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) { for (const auto& size : g_watch_size) { @@ -81,6 +92,18 @@ OptionGroupWatchpoint::SetOptionValue(uint32_t option_idx, Status error; const int short_option = g_option_table[option_idx].short_option; switch (short_option) { + case 'l': { + language_type = Language::GetLanguageTypeFromString(option_arg); + if (language_type == eLanguageTypeUnknown) { + StreamString sstr; + sstr.Printf("Unknown language type: '%s' for expression. List of " + "supported languages:\n", + option_arg.str().c_str()); + Language::PrintSupportedLanguagesForExpressions(sstr, " ", "\n"); + error.SetErrorString(sstr.GetString()); + } + break; + } case 'w': { WatchType tmp_watch_type; tmp_watch_type = (WatchType)OptionArgParser::ToOptionEnum( @@ -108,6 +131,7 @@ void OptionGroupWatchpoint::OptionParsingStarting( watch_type_specified = false; watch_type = eWatchInvalid; watch_size = 0; + language_type = eLanguageTypeUnknown; } llvm::ArrayRef<OptionDefinition> OptionGroupWatchpoint::GetDefinitions() { diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp index 79bdf74b6fd9..8d429b6bc9cf 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValue.cpp @@ -15,26 +15,6 @@ using namespace lldb; using namespace lldb_private; -// Get this value as a uint64_t value if it is encoded as a boolean, uint64_t -// or int64_t. Other types will cause "fail_value" to be returned -uint64_t OptionValue::GetUInt64Value(uint64_t fail_value, bool *success_ptr) { - if (success_ptr) - *success_ptr = true; - switch (GetType()) { - case OptionValue::eTypeBoolean: - return static_cast<OptionValueBoolean *>(this)->GetCurrentValue(); - case OptionValue::eTypeSInt64: - return static_cast<OptionValueSInt64 *>(this)->GetCurrentValue(); - case OptionValue::eTypeUInt64: - return static_cast<OptionValueUInt64 *>(this)->GetCurrentValue(); - default: - break; - } - if (success_ptr) - *success_ptr = false; - return fail_value; -} - Status OptionValue::SetSubValue(const ExecutionContext *exe_ctx, VarSetOperationType op, llvm::StringRef name, llvm::StringRef value) { @@ -271,104 +251,98 @@ const OptionValueUUID *OptionValue::GetAsUUID() const { return nullptr; } -bool OptionValue::GetBooleanValue(bool fail_value) const { - const OptionValueBoolean *option_value = GetAsBoolean(); - if (option_value) +std::optional<bool> OptionValue::GetBooleanValue() const { + if (const OptionValueBoolean *option_value = GetAsBoolean()) return option_value->GetCurrentValue(); - return fail_value; + return {}; } bool OptionValue::SetBooleanValue(bool new_value) { - OptionValueBoolean *option_value = GetAsBoolean(); - if (option_value) { + if (OptionValueBoolean *option_value = GetAsBoolean()) { option_value->SetCurrentValue(new_value); return true; } return false; } -char OptionValue::GetCharValue(char fail_value) const { - const OptionValueChar *option_value = GetAsChar(); - if (option_value) +std::optional<char> OptionValue::GetCharValue() const { + if (const OptionValueChar *option_value = GetAsChar()) return option_value->GetCurrentValue(); - return fail_value; + return {}; } -char OptionValue::SetCharValue(char new_value) { - OptionValueChar *option_value = GetAsChar(); - if (option_value) { +bool OptionValue::SetCharValue(char new_value) { + if (OptionValueChar *option_value = GetAsChar()) { option_value->SetCurrentValue(new_value); return true; } return false; } -int64_t OptionValue::GetEnumerationValue(int64_t fail_value) const { - const OptionValueEnumeration *option_value = GetAsEnumeration(); - if (option_value) +std::optional<int64_t> OptionValue::GetEnumerationValue() const { + if (const OptionValueEnumeration *option_value = GetAsEnumeration()) return option_value->GetCurrentValue(); - return fail_value; + return {}; } bool OptionValue::SetEnumerationValue(int64_t value) { - OptionValueEnumeration *option_value = GetAsEnumeration(); - if (option_value) { + if (OptionValueEnumeration *option_value = GetAsEnumeration()) { option_value->SetCurrentValue(value); return true; } return false; } -FileSpec OptionValue::GetFileSpecValue() const { - const OptionValueFileSpec *option_value = GetAsFileSpec(); - if (option_value) +std::optional<FileSpec> OptionValue::GetFileSpecValue() const { + if (const OptionValueFileSpec *option_value = GetAsFileSpec()) return option_value->GetCurrentValue(); - return FileSpec(); + return {}; } -bool OptionValue::SetFileSpecValue(const FileSpec &file_spec) { - OptionValueFileSpec *option_value = GetAsFileSpec(); - if (option_value) { +bool OptionValue::SetFileSpecValue(FileSpec file_spec) { + if (OptionValueFileSpec *option_value = GetAsFileSpec()) { option_value->SetCurrentValue(file_spec, false); return true; } return false; } -FileSpecList OptionValue::GetFileSpecListValue() const { - const OptionValueFileSpecList *option_value = GetAsFileSpecList(); - if (option_value) +bool OptionValue::AppendFileSpecValue(FileSpec file_spec) { + if (OptionValueFileSpecList *option_value = GetAsFileSpecList()) { + option_value->AppendCurrentValue(file_spec); + return true; + } + return false; +} + +std::optional<FileSpecList> OptionValue::GetFileSpecListValue() const { + if (const OptionValueFileSpecList *option_value = GetAsFileSpecList()) return option_value->GetCurrentValue(); - return FileSpecList(); + return {}; } -lldb::Format OptionValue::GetFormatValue(lldb::Format fail_value) const { - const OptionValueFormat *option_value = GetAsFormat(); - if (option_value) +std::optional<lldb::Format> OptionValue::GetFormatValue() const { + if (const OptionValueFormat *option_value = GetAsFormat()) return option_value->GetCurrentValue(); - return fail_value; + return {}; } bool OptionValue::SetFormatValue(lldb::Format new_value) { - OptionValueFormat *option_value = GetAsFormat(); - if (option_value) { + if (OptionValueFormat *option_value = GetAsFormat()) { option_value->SetCurrentValue(new_value); return true; } return false; } -lldb::LanguageType -OptionValue::GetLanguageValue(lldb::LanguageType fail_value) const { - const OptionValueLanguage *option_value = GetAsLanguage(); - if (option_value) +std::optional<lldb::LanguageType> OptionValue::GetLanguageValue() const { + if (const OptionValueLanguage *option_value = GetAsLanguage()) return option_value->GetCurrentValue(); - return fail_value; + return {}; } bool OptionValue::SetLanguageValue(lldb::LanguageType new_language) { - OptionValueLanguage *option_value = GetAsLanguage(); - if (option_value) { + if (OptionValueLanguage *option_value = GetAsLanguage()) { option_value->SetCurrentValue(new_language); return true; } @@ -376,83 +350,87 @@ bool OptionValue::SetLanguageValue(lldb::LanguageType new_language) { } const FormatEntity::Entry *OptionValue::GetFormatEntity() const { - const OptionValueFormatEntity *option_value = GetAsFormatEntity(); - if (option_value) + if (const OptionValueFormatEntity *option_value = GetAsFormatEntity()) return &option_value->GetCurrentValue(); return nullptr; } const RegularExpression *OptionValue::GetRegexValue() const { - const OptionValueRegex *option_value = GetAsRegex(); - if (option_value) + if (const OptionValueRegex *option_value = GetAsRegex()) return option_value->GetCurrentValue(); return nullptr; } -int64_t OptionValue::GetSInt64Value(int64_t fail_value) const { - const OptionValueSInt64 *option_value = GetAsSInt64(); - if (option_value) +std::optional<int64_t> OptionValue::GetSInt64Value() const { + if (const OptionValueSInt64 *option_value = GetAsSInt64()) return option_value->GetCurrentValue(); - return fail_value; + return {}; } bool OptionValue::SetSInt64Value(int64_t new_value) { - OptionValueSInt64 *option_value = GetAsSInt64(); - if (option_value) { + if (OptionValueSInt64 *option_value = GetAsSInt64()) { option_value->SetCurrentValue(new_value); return true; } return false; } -llvm::StringRef OptionValue::GetStringValue(llvm::StringRef fail_value) const { - const OptionValueString *option_value = GetAsString(); - if (option_value) +std::optional<llvm::StringRef> OptionValue::GetStringValue() const { + if (const OptionValueString *option_value = GetAsString()) return option_value->GetCurrentValueAsRef(); - return fail_value; + return {}; } bool OptionValue::SetStringValue(llvm::StringRef new_value) { - OptionValueString *option_value = GetAsString(); - if (option_value) { + if (OptionValueString *option_value = GetAsString()) { option_value->SetCurrentValue(new_value); return true; } return false; } -uint64_t OptionValue::GetUInt64Value(uint64_t fail_value) const { - const OptionValueUInt64 *option_value = GetAsUInt64(); - if (option_value) +std::optional<uint64_t> OptionValue::GetUInt64Value() const { + if (const OptionValueUInt64 *option_value = GetAsUInt64()) return option_value->GetCurrentValue(); - return fail_value; + return {}; } bool OptionValue::SetUInt64Value(uint64_t new_value) { - OptionValueUInt64 *option_value = GetAsUInt64(); - if (option_value) { + if (OptionValueUInt64 *option_value = GetAsUInt64()) { option_value->SetCurrentValue(new_value); return true; } return false; } -UUID OptionValue::GetUUIDValue() const { - const OptionValueUUID *option_value = GetAsUUID(); - if (option_value) +std::optional<UUID> OptionValue::GetUUIDValue() const { + if (const OptionValueUUID *option_value = GetAsUUID()) return option_value->GetCurrentValue(); - return UUID(); + return {}; } bool OptionValue::SetUUIDValue(const UUID &uuid) { - OptionValueUUID *option_value = GetAsUUID(); - if (option_value) { + if (OptionValueUUID *option_value = GetAsUUID()) { option_value->SetCurrentValue(uuid); return true; } return false; } +std::optional<ArchSpec> OptionValue::GetArchSpecValue() const { + if (const OptionValueArch *option_value = GetAsArch()) + return option_value->GetCurrentValue(); + return {}; +} + +bool OptionValue::SetArchSpecValue(ArchSpec arch_spec) { + if (OptionValueArch *option_value = GetAsArch()) { + option_value->SetCurrentValue(arch_spec, false); + return true; + } + return false; +} + const char *OptionValue::GetBuiltinTypeAsCString(Type t) { switch (t) { case eTypeInvalid: @@ -556,8 +534,8 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const { if (m_parent_sp->DumpQualifiedName(strm)) dumped_something = true; } - ConstString name(GetName()); - if (name) { + llvm::StringRef name(GetName()); + if (!name.empty()) { if (dumped_something) strm.PutChar('.'); else diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArch.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArch.cpp index 4d1e2c7869f3..71a3627fbe5e 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArch.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArch.cpp @@ -66,7 +66,6 @@ Status OptionValueArch::SetValueFromString(llvm::StringRef value, void OptionValueArch::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { - CommandCompletions::InvokeCommonCompletionCallbacks( - interpreter, CommandCompletions::eArchitectureCompletion, request, - nullptr); + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( + interpreter, lldb::eArchitectureCompletion, request, nullptr); } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArgs.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArgs.cpp index bdb5f486835a..963651640539 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArgs.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArgs.cpp @@ -15,11 +15,7 @@ using namespace lldb_private; size_t OptionValueArgs::GetArgs(Args &args) const { args.Clear(); - for (const auto &value : m_values) { - llvm::StringRef string_value = value->GetStringValue(); - if (!string_value.empty()) - args.AppendArgument(string_value); - } - + for (const auto &value : m_values) + args.AppendArgument(value->GetValueAs<llvm::StringRef>().value_or("")); return args.GetArgumentCount(); } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp index 40357d5f4b06..08b5f86202d3 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueArray.cpp @@ -94,8 +94,7 @@ Status OptionValueArray::SetValueFromString(llvm::StringRef value, lldb::OptionValueSP OptionValueArray::GetSubValue(const ExecutionContext *exe_ctx, - llvm::StringRef name, bool will_modify, - Status &error) const { + llvm::StringRef name, Status &error) const { if (name.empty() || name.front() != '[') { error.SetErrorStringWithFormat( "invalid value path '%s', %s values only support '[<index>]' subvalues " @@ -129,8 +128,7 @@ OptionValueArray::GetSubValue(const ExecutionContext *exe_ctx, if (new_idx < array_count) { if (m_values[new_idx]) { if (!sub_value.empty()) - return m_values[new_idx]->GetSubValue(exe_ctx, sub_value, - will_modify, error); + return m_values[new_idx]->GetSubValue(exe_ctx, sub_value, error); else return m_values[new_idx]; } @@ -155,9 +153,9 @@ size_t OptionValueArray::GetArgs(Args &args) const { args.Clear(); const uint32_t size = m_values.size(); for (uint32_t i = 0; i < size; ++i) { - llvm::StringRef string_value = m_values[i]->GetStringValue(); - if (!string_value.empty()) - args.AppendArgument(string_value); + auto string_value = m_values[i]->GetValueAs<llvm::StringRef>(); + if (string_value) + args.AppendArgument(*string_value); } return args.GetArgumentCount(); diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp index d18510166eeb..c7d501fd4521 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -33,20 +33,24 @@ void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx, if (dump_mask & eDumpOptionType) strm.PutCString(" ="); - collection::iterator pos, end = m_values.end(); - if (!one_line) strm.IndentMore(); - for (pos = m_values.begin(); pos != end; ++pos) { - OptionValue *option_value = pos->second.get(); + // m_values is not guaranteed to be sorted alphabetically, so for + // consistentcy we will sort them here before dumping + std::map<llvm::StringRef, OptionValue *> sorted_values; + for (const auto &value : m_values) { + sorted_values[value.first()] = value.second.get(); + } + for (const auto &value : sorted_values) { + OptionValue *option_value = value.second; if (one_line) strm << ' '; else strm.EOL(); - strm.Indent(pos->first.GetStringRef()); + strm.Indent(value.first); const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; switch (dict_type) { @@ -87,18 +91,17 @@ llvm::json::Value OptionValueDictionary::ToJSON(const ExecutionContext *exe_ctx) { llvm::json::Object dict; for (const auto &value : m_values) { - dict.try_emplace(value.first.GetCString(), value.second->ToJSON(exe_ctx)); + dict.try_emplace(value.first(), value.second->ToJSON(exe_ctx)); } return dict; } size_t OptionValueDictionary::GetArgs(Args &args) const { args.Clear(); - collection::const_iterator pos, end = m_values.end(); - for (pos = m_values.begin(); pos != end; ++pos) { + for (const auto &value : m_values) { StreamString strm; - strm.Printf("%s=", pos->first.GetCString()); - pos->second->DumpValue(nullptr, strm, eDumpOptionValue | eDumpOptionRaw); + strm.Printf("%s=", value.first().data()); + value.second->DumpValue(nullptr, strm, eDumpOptionValue | eDumpOptionRaw); args.AppendArgument(strm.GetString()); } return args.GetArgumentCount(); @@ -178,7 +181,7 @@ Status OptionValueDictionary::SetArgs(const Args &args, if (error.Fail()) return error; m_value_was_set = true; - SetValueForKey(ConstString(key), enum_value, true); + SetValueForKey(key, enum_value, true); } else { lldb::OptionValueSP value_sp(CreateValueFromCStringForTypeMask( value.str().c_str(), m_type_mask, error)); @@ -186,7 +189,7 @@ Status OptionValueDictionary::SetArgs(const Args &args, if (error.Fail()) return error; m_value_was_set = true; - SetValueForKey(ConstString(key), value_sp, true); + SetValueForKey(key, value_sp, true); } else { error.SetErrorString("dictionaries that can contain multiple types " "must subclass OptionValueArray"); @@ -198,11 +201,11 @@ Status OptionValueDictionary::SetArgs(const Args &args, case eVarSetOperationRemove: if (argc > 0) { for (size_t i = 0; i < argc; ++i) { - ConstString key(args.GetArgumentAtIndex(i)); + llvm::StringRef key(args.GetArgumentAtIndex(i)); if (!DeleteValueForKey(key)) { error.SetErrorStringWithFormat( "no value found named '%s', aborting remove operation", - key.GetCString()); + key.data()); break; } } @@ -231,8 +234,7 @@ Status OptionValueDictionary::SetValueFromString(llvm::StringRef value, lldb::OptionValueSP OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx, - llvm::StringRef name, bool will_modify, - Status &error) const { + llvm::StringRef name, Status &error) const { lldb::OptionValueSP value_sp; if (name.empty()) return nullptr; @@ -267,7 +269,7 @@ OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx, return nullptr; } - value_sp = GetValueForKey(ConstString(key)); + value_sp = GetValueForKey(key); if (!value_sp) { error.SetErrorStringWithFormat( "dictionary does not contain a value for the key name '%s'", @@ -277,7 +279,7 @@ OptionValueDictionary::GetSubValue(const ExecutionContext *exe_ctx, if (sub_name.empty()) return value_sp; - return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error); + return value_sp->GetSubValue(exe_ctx, sub_name, error); } Status OptionValueDictionary::SetSubValue(const ExecutionContext *exe_ctx, @@ -285,8 +287,7 @@ Status OptionValueDictionary::SetSubValue(const ExecutionContext *exe_ctx, llvm::StringRef name, llvm::StringRef value) { Status error; - const bool will_modify = true; - lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error)); + lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, error)); if (value_sp) error = value_sp->SetValueFromString(value, op); else { @@ -297,22 +298,22 @@ Status OptionValueDictionary::SetSubValue(const ExecutionContext *exe_ctx, } lldb::OptionValueSP -OptionValueDictionary::GetValueForKey(ConstString key) const { +OptionValueDictionary::GetValueForKey(llvm::StringRef key) const { lldb::OptionValueSP value_sp; - collection::const_iterator pos = m_values.find(key); + auto pos = m_values.find(key); if (pos != m_values.end()) value_sp = pos->second; return value_sp; } -bool OptionValueDictionary::SetValueForKey(ConstString key, +bool OptionValueDictionary::SetValueForKey(llvm::StringRef key, const lldb::OptionValueSP &value_sp, bool can_replace) { // Make sure the value_sp object is allowed to contain values of the type // passed in... if (value_sp && (m_type_mask & value_sp->GetTypeAsMask())) { if (!can_replace) { - collection::const_iterator pos = m_values.find(key); + auto pos = m_values.find(key); if (pos != m_values.end()) return false; } @@ -322,8 +323,8 @@ bool OptionValueDictionary::SetValueForKey(ConstString key, return false; } -bool OptionValueDictionary::DeleteValueForKey(ConstString key) { - collection::iterator pos = m_values.find(key); +bool OptionValueDictionary::DeleteValueForKey(llvm::StringRef key) { + auto pos = m_values.find(key); if (pos != m_values.end()) { m_values.erase(pos); return true; diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp index e500005a815d..a68967b81797 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileColonLine.cpp @@ -132,6 +132,6 @@ Status OptionValueFileColonLine::SetValueFromString(llvm::StringRef value, void OptionValueFileColonLine::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { - CommandCompletions::InvokeCommonCompletionCallbacks( + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( interpreter, m_completion_mask, request, nullptr); } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp index f35a6b886f98..35a1081dba1e 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -84,7 +84,7 @@ Status OptionValueFileSpec::SetValueFromString(llvm::StringRef value, void OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter, CompletionRequest &request) { - CommandCompletions::InvokeCommonCompletionCallbacks( + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( interpreter, m_completion_mask, request, nullptr); } diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueLanguage.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueLanguage.cpp index 1be8a5585bc4..409fcf882bcb 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueLanguage.cpp @@ -43,10 +43,8 @@ Status OptionValueLanguage::SetValueFromString(llvm::StringRef value, case eVarSetOperationReplace: case eVarSetOperationAssign: { - ConstString lang_name(value.trim()); LanguageSet languages_for_types = Language::GetLanguagesSupportingTypeSystems(); - LanguageType new_type = - Language::GetLanguageTypeFromString(lang_name.GetStringRef()); + LanguageType new_type = Language::GetLanguageTypeFromString(value.trim()); if (new_type && languages_for_types[new_type]) { m_value_was_set = true; m_current_value = new_type; diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp index 62590bb18869..8719a2b63656 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueProperties.cpp @@ -20,90 +20,64 @@ using namespace lldb; using namespace lldb_private; -OptionValueProperties::OptionValueProperties(ConstString name) : m_name(name) {} - -size_t OptionValueProperties::GetNumProperties() const { - return m_properties.size(); -} +OptionValueProperties::OptionValueProperties(llvm::StringRef name) + : m_name(name.str()) {} void OptionValueProperties::Initialize(const PropertyDefinitions &defs) { for (const auto &definition : defs) { Property property(definition); assert(property.IsValid()); - m_name_to_index.Append(ConstString(property.GetName()), m_properties.size()); + m_name_to_index.insert({property.GetName(), m_properties.size()}); property.GetValue()->SetParent(shared_from_this()); m_properties.push_back(property); } - m_name_to_index.Sort(); } void OptionValueProperties::SetValueChangedCallback( - uint32_t property_idx, std::function<void()> callback) { + size_t property_idx, std::function<void()> callback) { Property *property = ProtectedGetPropertyAtIndex(property_idx); if (property) property->SetValueChangedCallback(std::move(callback)); } -void OptionValueProperties::AppendProperty(ConstString name, - ConstString desc, - bool is_global, +void OptionValueProperties::AppendProperty(llvm::StringRef name, + llvm::StringRef desc, bool is_global, const OptionValueSP &value_sp) { - Property property(name.GetStringRef(), desc.GetStringRef(), is_global, - value_sp); - m_name_to_index.Append(name, m_properties.size()); + Property property(name, desc, is_global, value_sp); + m_name_to_index.insert({name, m_properties.size()}); m_properties.push_back(property); value_sp->SetParent(shared_from_this()); - m_name_to_index.Sort(); } -// bool -// OptionValueProperties::GetQualifiedName (Stream &strm) -//{ -// bool dumped_something = false; -//// lldb::OptionValuePropertiesSP parent_sp(GetParent ()); -//// if (parent_sp) -//// { -//// parent_sp->GetQualifiedName (strm); -//// strm.PutChar('.'); -//// dumped_something = true; -//// } -// if (m_name) -// { -// strm << m_name; -// dumped_something = true; -// } -// return dumped_something; -//} -// lldb::OptionValueSP OptionValueProperties::GetValueForKey(const ExecutionContext *exe_ctx, - ConstString key, - bool will_modify) const { - lldb::OptionValueSP value_sp; - size_t idx = m_name_to_index.Find(key, SIZE_MAX); - if (idx < m_properties.size()) - value_sp = GetPropertyAtIndex(exe_ctx, will_modify, idx)->GetValue(); - return value_sp; + llvm::StringRef key) const { + auto iter = m_name_to_index.find(key); + if (iter == m_name_to_index.end()) + return OptionValueSP(); + const size_t idx = iter->second; + if (idx >= m_properties.size()) + return OptionValueSP(); + return GetPropertyAtIndex(idx, exe_ctx)->GetValue(); } lldb::OptionValueSP OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx, - llvm::StringRef name, bool will_modify, - Status &error) const { + llvm::StringRef name, Status &error) const { lldb::OptionValueSP value_sp; if (name.empty()) return OptionValueSP(); llvm::StringRef sub_name; - ConstString key; + llvm::StringRef key; size_t key_len = name.find_first_of(".[{"); if (key_len != llvm::StringRef::npos) { - key.SetString(name.take_front(key_len)); + key = name.take_front(key_len); sub_name = name.drop_front(key_len); } else - key.SetString(name); + key = name; - value_sp = GetValueForKey(exe_ctx, key, will_modify); + value_sp = GetValueForKey(exe_ctx, key); if (sub_name.empty() || !value_sp) return value_sp; @@ -111,14 +85,14 @@ OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx, case '.': { lldb::OptionValueSP return_val_sp; return_val_sp = - value_sp->GetSubValue(exe_ctx, sub_name.drop_front(), will_modify, error); + value_sp->GetSubValue(exe_ctx, sub_name.drop_front(), error); if (!return_val_sp) { if (Properties::IsSettingExperimental(sub_name.drop_front())) { - size_t experimental_len = - strlen(Properties::GetExperimentalSettingsName()); + const size_t experimental_len = + Properties::GetExperimentalSettingsName().size(); if (sub_name[experimental_len + 1] == '.') return_val_sp = value_sp->GetSubValue( - exe_ctx, sub_name.drop_front(experimental_len + 2), will_modify, error); + exe_ctx, sub_name.drop_front(experimental_len + 2), error); // It isn't an error if an experimental setting is not present. if (!return_val_sp) error.Clear(); @@ -129,7 +103,7 @@ OptionValueProperties::GetSubValue(const ExecutionContext *exe_ctx, case '[': // Array or dictionary access for subvalues like: "[12]" -- access // 12th array element "['hello']" -- dictionary access of key named hello - return value_sp->GetSubValue(exe_ctx, sub_name, will_modify, error); + return value_sp->GetSubValue(exe_ctx, sub_name, error); default: value_sp.reset(); @@ -143,7 +117,6 @@ Status OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx, llvm::StringRef name, llvm::StringRef value) { Status error; - const bool will_modify = true; llvm::SmallVector<llvm::StringRef, 8> components; name.split(components, '.'); bool name_contains_experimental = false; @@ -151,41 +124,39 @@ Status OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx, if (Properties::IsSettingExperimental(part)) name_contains_experimental = true; - lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, will_modify, error)); + lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, name, error)); if (value_sp) error = value_sp->SetValueFromString(value, op); else { // Don't set an error if the path contained .experimental. - those are // allowed to be missing and should silently fail. if (!name_contains_experimental && error.AsCString() == nullptr) { - error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str()); + error.SetErrorStringWithFormat("invalid value path '%s'", + name.str().c_str()); } } return error; } -uint32_t -OptionValueProperties::GetPropertyIndex(ConstString name) const { - return m_name_to_index.Find(name, SIZE_MAX); +size_t OptionValueProperties::GetPropertyIndex(llvm::StringRef name) const { + auto iter = m_name_to_index.find(name); + if (iter == m_name_to_index.end()) + return SIZE_MAX; + return iter->second; } const Property * -OptionValueProperties::GetProperty(const ExecutionContext *exe_ctx, - bool will_modify, - ConstString name) const { - return GetPropertyAtIndex( - exe_ctx, will_modify, - m_name_to_index.Find(name, SIZE_MAX)); -} - -const Property *OptionValueProperties::GetPropertyAtIndex( - const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { - return ProtectedGetPropertyAtIndex(idx); +OptionValueProperties::GetProperty(llvm::StringRef name, + const ExecutionContext *exe_ctx) const { + auto iter = m_name_to_index.find(name); + if (iter == m_name_to_index.end()) + return nullptr; + return GetPropertyAtIndex(iter->second, exe_ctx); } lldb::OptionValueSP OptionValueProperties::GetPropertyValueAtIndex( - const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { - const Property *setting = GetPropertyAtIndex(exe_ctx, will_modify, idx); + size_t idx, const ExecutionContext *exe_ctx) const { + const Property *setting = GetPropertyAtIndex(idx, exe_ctx); if (setting) return setting->GetValue(); return OptionValueSP(); @@ -193,8 +164,8 @@ lldb::OptionValueSP OptionValueProperties::GetPropertyValueAtIndex( OptionValuePathMappings * OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings( - const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { - OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx)); + size_t idx, const ExecutionContext *exe_ctx) const { + OptionValueSP value_sp(GetPropertyValueAtIndex(idx, exe_ctx)); if (value_sp) return value_sp->GetAsPathMappings(); return nullptr; @@ -202,44 +173,16 @@ OptionValueProperties::GetPropertyAtIndexAsOptionValuePathMappings( OptionValueFileSpecList * OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpecList( - const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { - OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx)); + size_t idx, const ExecutionContext *exe_ctx) const { + OptionValueSP value_sp(GetPropertyValueAtIndex(idx, exe_ctx)); if (value_sp) return value_sp->GetAsFileSpecList(); return nullptr; } -OptionValueArch *OptionValueProperties::GetPropertyAtIndexAsOptionValueArch( - const ExecutionContext *exe_ctx, uint32_t idx) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); - if (property) - return property->GetValue()->GetAsArch(); - return nullptr; -} - -OptionValueLanguage * -OptionValueProperties::GetPropertyAtIndexAsOptionValueLanguage( - const ExecutionContext *exe_ctx, uint32_t idx) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); - if (property) - return property->GetValue()->GetAsLanguage(); - return nullptr; -} - -bool OptionValueProperties::SetPropertyAtIndexAsLanguage( - const ExecutionContext *exe_ctx, uint32_t idx, const LanguageType lang) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetLanguageValue(lang); - } - return false; -} - bool OptionValueProperties::GetPropertyAtIndexAsArgs( - const ExecutionContext *exe_ctx, uint32_t idx, Args &args) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + size_t idx, Args &args, const ExecutionContext *exe_ctx) const { + const Property *property = GetPropertyAtIndex(idx, exe_ctx); if (!property) return false; @@ -269,8 +212,8 @@ bool OptionValueProperties::GetPropertyAtIndexAsArgs( } bool OptionValueProperties::SetPropertyAtIndexFromArgs( - const ExecutionContext *exe_ctx, uint32_t idx, const Args &args) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); + size_t idx, const Args &args, const ExecutionContext *exe_ctx) { + const Property *property = GetPropertyAtIndex(idx, exe_ctx); if (!property) return false; @@ -293,77 +236,19 @@ bool OptionValueProperties::SetPropertyAtIndexFromArgs( return false; } -bool OptionValueProperties::GetPropertyAtIndexAsBoolean( - const ExecutionContext *exe_ctx, uint32_t idx, bool fail_value) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetBooleanValue(fail_value); - } - return fail_value; -} - -bool OptionValueProperties::SetPropertyAtIndexAsBoolean( - const ExecutionContext *exe_ctx, uint32_t idx, bool new_value) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) { - value->SetBooleanValue(new_value); - return true; - } - } - return false; -} - OptionValueDictionary * OptionValueProperties::GetPropertyAtIndexAsOptionValueDictionary( - const ExecutionContext *exe_ctx, uint32_t idx) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + size_t idx, const ExecutionContext *exe_ctx) const { + const Property *property = GetPropertyAtIndex(idx, exe_ctx); if (property) return property->GetValue()->GetAsDictionary(); return nullptr; } -int64_t OptionValueProperties::GetPropertyAtIndexAsEnumeration( - const ExecutionContext *exe_ctx, uint32_t idx, int64_t fail_value) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetEnumerationValue(fail_value); - } - return fail_value; -} - -bool OptionValueProperties::SetPropertyAtIndexAsEnumeration( - const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetEnumerationValue(new_value); - } - return false; -} - -const FormatEntity::Entry * -OptionValueProperties::GetPropertyAtIndexAsFormatEntity( - const ExecutionContext *exe_ctx, uint32_t idx) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetFormatEntity(); - } - return nullptr; -} - OptionValueFileSpec * OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec( - const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + size_t idx, const ExecutionContext *exe_ctx) const { + const Property *property = GetPropertyAtIndex(idx, exe_ctx); if (property) { OptionValue *value = property->GetValue().get(); if (value) @@ -372,44 +257,9 @@ OptionValueProperties::GetPropertyAtIndexAsOptionValueFileSpec( return nullptr; } -FileSpec OptionValueProperties::GetPropertyAtIndexAsFileSpec( - 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->GetFileSpecValue(); - } - return FileSpec(); -} - -bool OptionValueProperties::SetPropertyAtIndexAsFileSpec( - const ExecutionContext *exe_ctx, uint32_t idx, - const FileSpec &new_file_spec) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetFileSpecValue(new_file_spec); - } - return false; -} - -const RegularExpression * -OptionValueProperties::GetPropertyAtIndexAsOptionValueRegex( - 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->GetRegexValue(); - } - return nullptr; -} - OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64( - const ExecutionContext *exe_ctx, uint32_t idx) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + size_t idx, const ExecutionContext *exe_ctx) const { + const Property *property = GetPropertyAtIndex(idx, exe_ctx); if (property) { OptionValue *value = property->GetValue().get(); if (value) @@ -419,8 +269,8 @@ OptionValueSInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueSInt64( } OptionValueUInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueUInt64( - const ExecutionContext *exe_ctx, uint32_t idx) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); + size_t idx, const ExecutionContext *exe_ctx) const { + const Property *property = GetPropertyAtIndex(idx, exe_ctx); if (property) { OptionValue *value = property->GetValue().get(); if (value) @@ -429,81 +279,14 @@ OptionValueUInt64 *OptionValueProperties::GetPropertyAtIndexAsOptionValueUInt64( 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); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetSInt64Value(fail_value); - } - return fail_value; -} - -bool OptionValueProperties::SetPropertyAtIndexAsSInt64( - const ExecutionContext *exe_ctx, uint32_t idx, int64_t new_value) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetSInt64Value(new_value); - } - return false; -} - -llvm::StringRef OptionValueProperties::GetPropertyAtIndexAsString( - const ExecutionContext *exe_ctx, uint32_t idx, - llvm::StringRef fail_value) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetStringValue(fail_value); - } - return fail_value; -} - -bool OptionValueProperties::SetPropertyAtIndexAsString( - const ExecutionContext *exe_ctx, uint32_t idx, llvm::StringRef new_value) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetStringValue(new_value); - } - return false; -} - OptionValueString *OptionValueProperties::GetPropertyAtIndexAsOptionValueString( - const ExecutionContext *exe_ctx, bool will_modify, uint32_t idx) const { - OptionValueSP value_sp(GetPropertyValueAtIndex(exe_ctx, will_modify, idx)); + size_t idx, const ExecutionContext *exe_ctx) const { + OptionValueSP value_sp(GetPropertyValueAtIndex(idx, exe_ctx)); if (value_sp) return value_sp->GetAsString(); return nullptr; } -uint64_t OptionValueProperties::GetPropertyAtIndexAsUInt64( - const ExecutionContext *exe_ctx, uint32_t idx, uint64_t fail_value) const { - const Property *property = GetPropertyAtIndex(exe_ctx, false, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->GetUInt64Value(fail_value); - } - return fail_value; -} - -bool OptionValueProperties::SetPropertyAtIndexAsUInt64( - const ExecutionContext *exe_ctx, uint32_t idx, uint64_t new_value) { - const Property *property = GetPropertyAtIndex(exe_ctx, true, idx); - if (property) { - OptionValue *value = property->GetValue().get(); - if (value) - return value->SetUInt64Value(new_value); - } - return false; -} - void OptionValueProperties::Clear() { const size_t num_properties = m_properties.size(); for (size_t i = 0; i < num_properties; ++i) @@ -539,7 +322,7 @@ void OptionValueProperties::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) { const size_t num_properties = m_properties.size(); for (size_t i = 0; i < num_properties; ++i) { - const Property *property = GetPropertyAtIndex(exe_ctx, false, i); + const Property *property = GetPropertyAtIndex(i, exe_ctx); if (property) { OptionValue *option_value = property->GetValue().get(); assert(option_value); @@ -556,7 +339,7 @@ OptionValueProperties::ToJSON(const ExecutionContext *exe_ctx) { llvm::json::Object json_properties; const size_t num_properties = m_properties.size(); for (size_t i = 0; i < num_properties; ++i) { - const Property *property = GetPropertyAtIndex(exe_ctx, false, i); + const Property *property = GetPropertyAtIndex(i, exe_ctx); if (property) { OptionValue *option_value = property->GetValue().get(); assert(option_value); @@ -570,11 +353,10 @@ OptionValueProperties::ToJSON(const ExecutionContext *exe_ctx) { Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx, Stream &strm, llvm::StringRef property_path, - uint32_t dump_mask, bool is_json) { + uint32_t dump_mask, + bool is_json) { Status error; - const bool will_modify = false; - lldb::OptionValueSP value_sp( - GetSubValue(exe_ctx, property_path, will_modify, error)); + lldb::OptionValueSP value_sp(GetSubValue(exe_ctx, property_path, error)); if (value_sp) { if (!value_sp->ValueIsTransparent()) { if (dump_mask & eDumpOptionName) @@ -583,7 +365,9 @@ Status OptionValueProperties::DumpPropertyValue(const ExecutionContext *exe_ctx, strm.PutChar(' '); } if (is_json) { - strm.Printf("%s", llvm::formatv("{0:2}", value_sp->ToJSON(exe_ctx)).str().c_str()); + strm.Printf( + "%s", + llvm::formatv("{0:2}", value_sp->ToJSON(exe_ctx)).str().c_str()); } else value_sp->DumpValue(exe_ctx, strm, dump_mask); } @@ -618,22 +402,24 @@ OptionValueProperties::DeepCopy(const OptionValueSP &new_parent) const { return copy_sp; } -const Property *OptionValueProperties::GetPropertyAtPath( - const ExecutionContext *exe_ctx, bool will_modify, llvm::StringRef name) const { - const Property *property = nullptr; +const Property * +OptionValueProperties::GetPropertyAtPath(const ExecutionContext *exe_ctx, + llvm::StringRef name) const { if (name.empty()) return nullptr; + + const Property *property = nullptr; llvm::StringRef sub_name; - ConstString key; + llvm::StringRef key; size_t key_len = name.find_first_of(".[{"); if (key_len != llvm::StringRef::npos) { - key.SetString(name.take_front(key_len)); + key = name.take_front(key_len); sub_name = name.drop_front(key_len); } else - key.SetString(name); + key = name; - property = GetProperty(exe_ctx, will_modify, key); + property = GetProperty(key, exe_ctx); if (sub_name.empty() || !property) return property; @@ -641,8 +427,7 @@ const Property *OptionValueProperties::GetPropertyAtPath( OptionValueProperties *sub_properties = property->GetValue()->GetAsProperties(); if (sub_properties) - return sub_properties->GetPropertyAtPath(exe_ctx, will_modify, - sub_name.drop_front()); + return sub_properties->GetPropertyAtPath(exe_ctx, sub_name.drop_front()); } return nullptr; } @@ -695,8 +480,8 @@ void OptionValueProperties::Apropos( lldb::OptionValuePropertiesSP OptionValueProperties::GetSubProperty(const ExecutionContext *exe_ctx, - ConstString name) { - lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name, false)); + llvm::StringRef name) { + lldb::OptionValueSP option_value_sp(GetValueForKey(exe_ctx, name)); if (option_value_sp) { OptionValueProperties *ov_properties = option_value_sp->GetAsProperties(); if (ov_properties) diff --git a/contrib/llvm-project/lldb/source/Interpreter/OptionValueUUID.cpp b/contrib/llvm-project/lldb/source/Interpreter/OptionValueUUID.cpp index 283f9c1b67b3..ff35870a76e8 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/OptionValueUUID.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/OptionValueUUID.cpp @@ -23,7 +23,7 @@ void OptionValueUUID::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) strm.PutCString(" = "); - m_uuid.Dump(&strm); + m_uuid.Dump(strm); } } diff --git a/contrib/llvm-project/lldb/source/Interpreter/Options.cpp b/contrib/llvm-project/lldb/source/Interpreter/Options.cpp index 8cb386f95f43..acbde7660440 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/Options.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/Options.cpp @@ -714,8 +714,8 @@ void Options::HandleOptionArgumentCompletion( } } - if (completion_mask & CommandCompletions::eSourceFileCompletion || - completion_mask & CommandCompletions::eSymbolCompletion) { + if (completion_mask & lldb::eSourceFileCompletion || + completion_mask & lldb::eSymbolCompletion) { for (size_t i = 0; i < opt_element_vector.size(); i++) { int cur_defs_index = opt_element_vector[i].opt_defs_index; @@ -748,7 +748,7 @@ void Options::HandleOptionArgumentCompletion( } } - CommandCompletions::InvokeCommonCompletionCallbacks( + lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( interpreter, completion_mask, request, filter_up.get()); } @@ -781,6 +781,19 @@ void OptionGroupOptions::Append(OptionGroup *group, uint32_t src_mask, } } +void OptionGroupOptions::Append( + OptionGroup *group, llvm::ArrayRef<llvm::StringRef> exclude_long_options) { + auto group_option_defs = group->GetDefinitions(); + for (uint32_t i = 0; i < group_option_defs.size(); ++i) { + const auto &definition = group_option_defs[i]; + if (llvm::is_contained(exclude_long_options, definition.long_option)) + continue; + + m_option_infos.push_back(OptionInfo(group, i)); + m_option_defs.push_back(definition); + } +} + void OptionGroupOptions::Finalize() { m_did_finalize = true; } diff --git a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp index 681596224d31..56e45363be89 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/Property.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/Property.cpp @@ -226,6 +226,7 @@ Property::Property(const PropertyDefinition &definition) } break; } + assert(m_value_sp && "invalid property definition"); } Property::Property(llvm::StringRef name, llvm::StringRef desc, bool is_global, diff --git a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp index 2722666439bf..fb3fa74d0b97 100644 --- a/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp +++ b/contrib/llvm-project/lldb/source/Interpreter/ScriptInterpreter.cpp @@ -29,10 +29,8 @@ using namespace lldb_private; ScriptInterpreter::ScriptInterpreter( Debugger &debugger, lldb::ScriptLanguage script_lang, - lldb::ScriptedProcessInterfaceUP scripted_process_interface_up, lldb::ScriptedPlatformInterfaceUP scripted_platform_interface_up) : m_debugger(debugger), m_script_lang(script_lang), - m_scripted_process_interface_up(std::move(scripted_process_interface_up)), m_scripted_platform_interface_up( std::move(scripted_platform_interface_up)) {} @@ -82,6 +80,22 @@ ScriptInterpreter::GetDataExtractorFromSBData(const lldb::SBData &data) const { return data.m_opaque_sp; } +lldb::BreakpointSP ScriptInterpreter::GetOpaqueTypeFromSBBreakpoint( + const lldb::SBBreakpoint &breakpoint) const { + return breakpoint.m_opaque_wp.lock(); +} + +lldb::ProcessAttachInfoSP ScriptInterpreter::GetOpaqueTypeFromSBAttachInfo( + const lldb::SBAttachInfo &attach_info) const { + return attach_info.m_opaque_sp; +} + +lldb::ProcessLaunchInfoSP ScriptInterpreter::GetOpaqueTypeFromSBLaunchInfo( + const lldb::SBLaunchInfo &launch_info) const { + return std::make_shared<ProcessLaunchInfo>( + *reinterpret_cast<ProcessLaunchInfo *>(launch_info.m_opaque_sp.get())); +} + Status ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const { if (error.m_opaque_up) @@ -114,7 +128,8 @@ Status ScriptInterpreter::SetBreakpointCommandCallback( const char *callback_text) { Status error; for (BreakpointOptions &bp_options : bp_options_vec) { - error = SetBreakpointCommandCallback(bp_options, callback_text); + error = SetBreakpointCommandCallback(bp_options, callback_text, + /*is_callback=*/false); if (!error.Success()) break; } 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 cce7c81bb06c..f4ef9b4fc824 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 @@ -12,7 +12,7 @@ #include <vector> #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -303,26 +303,17 @@ ABIMacOSX_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, if (v0_info) { if (byte_size <= 16) { - if (byte_size <= RegisterValue::GetMaxByteSize()) { - RegisterValue reg_value; - error = reg_value.SetValueFromData(*v0_info, data, 0, true); - if (error.Success()) { - if (!reg_ctx->WriteRegister(v0_info, reg_value)) - error.SetErrorString("failed to write register v0"); - } - } else { - error.SetErrorStringWithFormat( - "returning float values with a byte size of %" PRIu64 - " are not supported", - byte_size); - } + RegisterValue reg_value; + error = reg_value.SetValueFromData(*v0_info, data, 0, true); + if (error.Success()) + if (!reg_ctx->WriteRegister(v0_info, reg_value)) + error.SetErrorString("failed to write register v0"); } else { error.SetErrorString("returning float values longer than 128 " "bits are not supported"); } - } else { + } else error.SetErrorString("v0 register is not available on this target"); - } } } } else if (type_flags & eTypeIsVector) { @@ -814,18 +805,41 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( return return_valobj_sp; } -lldb::addr_t ABIMacOSX_arm64::FixAddress(addr_t pc, addr_t mask) { - lldb::addr_t pac_sign_extension = 0x0080000000000000ULL; - // Darwin systems originally couldn't determine the proper value - // dynamically, so the most common value was hardcoded. This has - // largely been cleaned up, but there are still a handful of - // environments that assume the default value is set to this value - // and there's no dynamic value to correct it. - // When no mask is specified, set it to 39 bits of addressing (0..38). - if (mask == 0) { - // ~((1ULL<<39)-1) - mask = 0xffffff8000000000; +addr_t ABIMacOSX_arm64::FixCodeAddress(addr_t pc) { + addr_t pac_sign_extension = 0x0080000000000000ULL; + addr_t tbi_mask = 0xff80000000000000ULL; + addr_t mask = 0; + + if (ProcessSP process_sp = GetProcessSP()) { + mask = process_sp->GetCodeAddressMask(); + if (pc & pac_sign_extension) { + addr_t highmem_mask = process_sp->GetHighmemCodeAddressMask(); + if (highmem_mask) + mask = highmem_mask; + } + } + if (mask == 0) + mask = tbi_mask; + + return (pc & pac_sign_extension) ? pc | mask : pc & (~mask); +} + +addr_t ABIMacOSX_arm64::FixDataAddress(addr_t pc) { + addr_t pac_sign_extension = 0x0080000000000000ULL; + addr_t tbi_mask = 0xff80000000000000ULL; + addr_t mask = 0; + + if (ProcessSP process_sp = GetProcessSP()) { + mask = process_sp->GetDataAddressMask(); + if (pc & pac_sign_extension) { + addr_t highmem_mask = process_sp->GetHighmemDataAddressMask(); + if (highmem_mask) + mask = highmem_mask; + } } + if (mask == 0) + mask = tbi_mask; + return (pc & pac_sign_extension) ? pc | mask : pc & (~mask); } diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h index 1a5bc7f67573..283306ed0f81 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/AArch64/ABIMacOSX_arm64.h @@ -62,7 +62,8 @@ public: return true; } - lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask) override; + lldb::addr_t FixCodeAddress(lldb::addr_t pc) override; + lldb::addr_t FixDataAddress(lldb::addr_t pc) override; // Static Functions 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 d46545a93583..bf3c5ddd5889 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 @@ -12,7 +12,7 @@ #include <vector> #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -276,26 +276,17 @@ Status ABISysV_arm64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, if (v0_info) { if (byte_size <= 16) { - if (byte_size <= RegisterValue::GetMaxByteSize()) { - RegisterValue reg_value; - error = reg_value.SetValueFromData(*v0_info, data, 0, true); - if (error.Success()) { - if (!reg_ctx->WriteRegister(v0_info, reg_value)) - error.SetErrorString("failed to write register v0"); - } - } else { - error.SetErrorStringWithFormat( - "returning float values with a byte size of %" PRIu64 - " are not supported", - byte_size); - } + RegisterValue reg_value; + error = reg_value.SetValueFromData(*v0_info, data, 0, true); + if (error.Success()) + if (!reg_ctx->WriteRegister(v0_info, reg_value)) + error.SetErrorString("failed to write register v0"); } else { error.SetErrorString("returning float values longer than 128 " "bits are not supported"); } - } else { + } else error.SetErrorString("v0 register is not available on this target"); - } } } } else if (type_flags & eTypeIsVector) { 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 3386acd9080f..1ae3d64797ae 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 @@ -15,9 +15,9 @@ #include <type_traits> // Other libraries and framework includes -#include "llvm/ADT/Triple.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/Support/MathExtras.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -46,7 +46,7 @@ DEFINE_REG_NAME(dwarf_num), DEFINE_REG_NAME_STR(str_name), \ 0, 0, eEncodingInvalid, eFormatDefault, \ { dwarf_num, dwarf_num, generic_num, LLDB_INVALID_REGNUM, dwarf_num }, \ - nullptr, nullptr \ + nullptr, nullptr, nullptr, \ } #define DEFINE_REGISTER_STUB(dwarf_num, str_name) \ diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp index 3b6c0955371e..51067a2a2901 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/ARM/ABIMacOSX_arm.cpp @@ -12,7 +12,7 @@ #include <vector> #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -52,6 +52,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r1", nullptr, @@ -63,6 +64,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r2", nullptr, @@ -74,6 +76,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r3", nullptr, @@ -85,6 +88,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r4", nullptr, @@ -96,6 +100,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r5", nullptr, @@ -107,6 +112,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r6", nullptr, @@ -118,6 +124,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r7", nullptr, @@ -129,6 +136,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r8", nullptr, @@ -140,6 +148,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r9", nullptr, @@ -151,6 +160,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r10", nullptr, @@ -162,6 +172,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r11", nullptr, @@ -173,6 +184,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r12", nullptr, @@ -184,6 +196,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"sp", "r13", @@ -195,6 +208,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"lr", "r14", @@ -206,6 +220,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"pc", "r15", @@ -217,6 +232,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"cpsr", "psr", @@ -228,6 +244,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s0", nullptr, @@ -239,6 +256,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s1", nullptr, @@ -250,6 +268,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s2", nullptr, @@ -261,6 +280,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s3", nullptr, @@ -272,6 +292,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s4", nullptr, @@ -283,6 +304,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s5", nullptr, @@ -294,6 +316,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s6", nullptr, @@ -305,6 +328,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s7", nullptr, @@ -316,6 +340,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s8", nullptr, @@ -327,6 +352,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s9", nullptr, @@ -338,6 +364,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s10", nullptr, @@ -349,6 +376,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s11", nullptr, @@ -360,6 +388,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s12", nullptr, @@ -371,6 +400,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s13", nullptr, @@ -382,6 +412,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s14", nullptr, @@ -393,6 +424,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s15", nullptr, @@ -404,6 +436,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s16", nullptr, @@ -415,6 +448,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s17", nullptr, @@ -426,6 +460,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s18", nullptr, @@ -437,6 +472,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s19", nullptr, @@ -448,6 +484,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s20", nullptr, @@ -459,6 +496,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s21", nullptr, @@ -470,6 +508,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s22", nullptr, @@ -481,6 +520,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s23", nullptr, @@ -492,6 +532,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s24", nullptr, @@ -503,6 +544,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s25", nullptr, @@ -514,6 +556,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s26", nullptr, @@ -525,6 +568,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s27", nullptr, @@ -536,6 +580,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s28", nullptr, @@ -547,6 +592,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s29", nullptr, @@ -558,6 +604,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s30", nullptr, @@ -569,6 +616,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s31", nullptr, @@ -580,6 +628,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"fpscr", nullptr, @@ -591,6 +640,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d0", nullptr, @@ -602,6 +652,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d1", nullptr, @@ -613,6 +664,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d2", nullptr, @@ -624,6 +676,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d3", nullptr, @@ -635,6 +688,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d4", nullptr, @@ -646,6 +700,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d5", nullptr, @@ -657,6 +712,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d6", nullptr, @@ -668,6 +724,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d7", nullptr, @@ -679,6 +736,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d8", nullptr, @@ -690,6 +748,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d9", nullptr, @@ -701,6 +760,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d10", nullptr, @@ -712,6 +772,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d11", nullptr, @@ -723,6 +784,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d12", nullptr, @@ -734,6 +796,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d13", nullptr, @@ -745,6 +808,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d14", nullptr, @@ -756,6 +820,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d15", nullptr, @@ -767,6 +832,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d16", nullptr, @@ -778,6 +844,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d17", nullptr, @@ -789,6 +856,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d18", nullptr, @@ -800,6 +868,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d19", nullptr, @@ -811,6 +880,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d20", nullptr, @@ -822,6 +892,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d21", nullptr, @@ -833,6 +904,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d22", nullptr, @@ -844,6 +916,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d23", nullptr, @@ -855,6 +928,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d24", nullptr, @@ -866,6 +940,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d25", nullptr, @@ -877,6 +952,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d26", nullptr, @@ -888,6 +964,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d27", nullptr, @@ -899,6 +976,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d28", nullptr, @@ -910,6 +988,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d29", nullptr, @@ -921,6 +1000,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d30", nullptr, @@ -932,6 +1012,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d31", nullptr, @@ -943,6 +1024,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r8_usr", nullptr, @@ -954,6 +1036,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r9_usr", nullptr, @@ -965,6 +1048,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r10_usr", nullptr, @@ -976,6 +1060,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r11_usr", nullptr, @@ -987,6 +1072,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r12_usr", nullptr, @@ -998,6 +1084,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_usr", "sp_usr", @@ -1009,6 +1096,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_usr", "lr_usr", @@ -1020,6 +1108,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r8_fiq", nullptr, @@ -1031,6 +1120,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r9_fiq", nullptr, @@ -1042,6 +1132,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r10_fiq", nullptr, @@ -1053,6 +1144,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r11_fiq", nullptr, @@ -1064,6 +1156,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r12_fiq", nullptr, @@ -1075,6 +1168,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_fiq", "sp_fiq", @@ -1086,6 +1180,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_fiq", "lr_fiq", @@ -1097,6 +1192,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_irq", "sp_irq", @@ -1108,6 +1204,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_irq", "lr_irq", @@ -1119,6 +1216,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_abt", "sp_abt", @@ -1130,6 +1228,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_abt", "lr_abt", @@ -1141,6 +1240,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_und", "sp_und", @@ -1152,6 +1252,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_und", "lr_und", @@ -1163,6 +1264,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_svc", "sp_svc", @@ -1174,6 +1276,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_svc", "lr_svc", @@ -1185,6 +1288,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }}; static const uint32_t k_num_register_infos = std::size(g_register_infos); 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 218af1dca2c0..8eca9d6672ad 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 @@ -12,7 +12,7 @@ #include <vector> #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -55,6 +55,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r1", nullptr, @@ -66,6 +67,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r2", nullptr, @@ -77,6 +79,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r3", nullptr, @@ -88,6 +91,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r4", nullptr, @@ -99,6 +103,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r5", nullptr, @@ -110,6 +115,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r6", nullptr, @@ -121,6 +127,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r7", nullptr, @@ -132,6 +139,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r8", nullptr, @@ -143,6 +151,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r9", nullptr, @@ -154,6 +163,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r10", nullptr, @@ -165,6 +175,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r11", nullptr, @@ -176,6 +187,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r12", nullptr, @@ -187,6 +199,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"sp", "r13", @@ -198,6 +211,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"lr", "r14", @@ -209,6 +223,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"pc", "r15", @@ -220,6 +235,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"cpsr", "psr", @@ -231,6 +247,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s0", nullptr, @@ -242,6 +259,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s1", nullptr, @@ -253,6 +271,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s2", nullptr, @@ -264,6 +283,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s3", nullptr, @@ -275,6 +295,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s4", nullptr, @@ -286,6 +307,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s5", nullptr, @@ -297,6 +319,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s6", nullptr, @@ -308,6 +331,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s7", nullptr, @@ -319,6 +343,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s8", nullptr, @@ -330,6 +355,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s9", nullptr, @@ -341,6 +367,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s10", nullptr, @@ -352,6 +379,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s11", nullptr, @@ -363,6 +391,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s12", nullptr, @@ -374,6 +403,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s13", nullptr, @@ -385,6 +415,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s14", nullptr, @@ -396,6 +427,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s15", nullptr, @@ -407,6 +439,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s16", nullptr, @@ -418,6 +451,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s17", nullptr, @@ -429,6 +463,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s18", nullptr, @@ -440,6 +475,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s19", nullptr, @@ -451,6 +487,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s20", nullptr, @@ -462,6 +499,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s21", nullptr, @@ -473,6 +511,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s22", nullptr, @@ -484,6 +523,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s23", nullptr, @@ -495,6 +535,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s24", nullptr, @@ -506,6 +547,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s25", nullptr, @@ -517,6 +559,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s26", nullptr, @@ -528,6 +571,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s27", nullptr, @@ -539,6 +583,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s28", nullptr, @@ -550,6 +595,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s29", nullptr, @@ -561,6 +607,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s30", nullptr, @@ -572,6 +619,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"s31", nullptr, @@ -583,6 +631,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"fpscr", nullptr, @@ -594,6 +643,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d0", nullptr, @@ -605,6 +655,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d1", nullptr, @@ -616,6 +667,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d2", nullptr, @@ -627,6 +679,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d3", nullptr, @@ -638,6 +691,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d4", nullptr, @@ -649,6 +703,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d5", nullptr, @@ -660,6 +715,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d6", nullptr, @@ -671,6 +727,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d7", nullptr, @@ -682,6 +739,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d8", nullptr, @@ -693,6 +751,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d9", nullptr, @@ -704,6 +763,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d10", nullptr, @@ -715,6 +775,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d11", nullptr, @@ -726,6 +787,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d12", nullptr, @@ -737,6 +799,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d13", nullptr, @@ -748,6 +811,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d14", nullptr, @@ -759,6 +823,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d15", nullptr, @@ -770,6 +835,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d16", nullptr, @@ -781,6 +847,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d17", nullptr, @@ -792,6 +859,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d18", nullptr, @@ -803,6 +871,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d19", nullptr, @@ -814,6 +883,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d20", nullptr, @@ -825,6 +895,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d21", nullptr, @@ -836,6 +907,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d22", nullptr, @@ -847,6 +919,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d23", nullptr, @@ -858,6 +931,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d24", nullptr, @@ -869,6 +943,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d25", nullptr, @@ -880,6 +955,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d26", nullptr, @@ -891,6 +967,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d27", nullptr, @@ -902,6 +979,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d28", nullptr, @@ -913,6 +991,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d29", nullptr, @@ -924,6 +1003,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d30", nullptr, @@ -935,6 +1015,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"d31", nullptr, @@ -946,6 +1027,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r8_usr", nullptr, @@ -957,6 +1039,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r9_usr", nullptr, @@ -968,6 +1051,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r10_usr", nullptr, @@ -979,6 +1063,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r11_usr", nullptr, @@ -990,6 +1075,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r12_usr", nullptr, @@ -1001,6 +1087,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_usr", "sp_usr", @@ -1012,6 +1099,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_usr", "lr_usr", @@ -1023,6 +1111,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r8_fiq", nullptr, @@ -1034,6 +1123,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r9_fiq", nullptr, @@ -1045,6 +1135,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r10_fiq", nullptr, @@ -1056,6 +1147,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r11_fiq", nullptr, @@ -1067,6 +1159,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r12_fiq", nullptr, @@ -1078,6 +1171,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_fiq", "sp_fiq", @@ -1089,6 +1183,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_fiq", "lr_fiq", @@ -1100,6 +1195,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_irq", "sp_irq", @@ -1111,6 +1207,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_irq", "lr_irq", @@ -1122,6 +1219,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_abt", "sp_abt", @@ -1133,6 +1231,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_abt", "lr_abt", @@ -1144,6 +1243,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13_und", "sp_und", @@ -1155,6 +1255,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_und", "lr_und", @@ -1166,6 +1267,8 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, + }, {"r13_svc", "sp_svc", @@ -1177,6 +1280,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14_svc", "lr_svc", @@ -1188,6 +1292,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }}; static const uint32_t k_num_register_infos = std::size(g_register_infos); diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp index d47bca48ae09..1fb293bb3d53 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/Hexagon/ABISysV_hexagon.cpp @@ -8,8 +8,8 @@ #include "ABISysV_hexagon.h" -#include "llvm/ADT/Triple.h" #include "llvm/IR/DerivedTypes.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -45,6 +45,7 @@ static const RegisterInfo g_register_infos[] = { {0, 0, LLDB_INVALID_REGNUM, 0, 0}, nullptr, nullptr, + nullptr, }, {"r01", "", @@ -55,6 +56,7 @@ static const RegisterInfo g_register_infos[] = { {1, 1, LLDB_INVALID_REGNUM, 1, 1}, nullptr, nullptr, + nullptr, }, {"r02", "", @@ -65,6 +67,7 @@ static const RegisterInfo g_register_infos[] = { {2, 2, LLDB_INVALID_REGNUM, 2, 2}, nullptr, nullptr, + nullptr, }, {"r03", "", @@ -75,6 +78,7 @@ static const RegisterInfo g_register_infos[] = { {3, 3, LLDB_INVALID_REGNUM, 3, 3}, nullptr, nullptr, + nullptr, }, {"r04", "", @@ -85,6 +89,7 @@ static const RegisterInfo g_register_infos[] = { {4, 4, LLDB_INVALID_REGNUM, 4, 4}, nullptr, nullptr, + nullptr, }, {"r05", "", @@ -95,6 +100,7 @@ static const RegisterInfo g_register_infos[] = { {5, 5, LLDB_INVALID_REGNUM, 5, 5}, nullptr, nullptr, + nullptr, }, {"r06", "", @@ -105,6 +111,7 @@ static const RegisterInfo g_register_infos[] = { {6, 6, LLDB_INVALID_REGNUM, 6, 6}, nullptr, nullptr, + nullptr, }, {"r07", "", @@ -115,6 +122,7 @@ static const RegisterInfo g_register_infos[] = { {7, 7, LLDB_INVALID_REGNUM, 7, 7}, nullptr, nullptr, + nullptr, }, {"r08", "", @@ -125,6 +133,7 @@ static const RegisterInfo g_register_infos[] = { {8, 8, LLDB_INVALID_REGNUM, 8, 8}, nullptr, nullptr, + nullptr, }, {"r09", "", @@ -135,6 +144,7 @@ static const RegisterInfo g_register_infos[] = { {9, 9, LLDB_INVALID_REGNUM, 9, 9}, nullptr, nullptr, + nullptr, }, {"r10", "", @@ -145,6 +155,7 @@ static const RegisterInfo g_register_infos[] = { {10, 10, LLDB_INVALID_REGNUM, 10, 10}, nullptr, nullptr, + nullptr, }, {"r11", "", @@ -155,6 +166,7 @@ static const RegisterInfo g_register_infos[] = { {11, 11, LLDB_INVALID_REGNUM, 11, 11}, nullptr, nullptr, + nullptr, }, {"r12", "", @@ -165,6 +177,7 @@ static const RegisterInfo g_register_infos[] = { {12, 12, LLDB_INVALID_REGNUM, 12, 12}, nullptr, nullptr, + nullptr, }, {"r13", "", @@ -175,6 +188,7 @@ static const RegisterInfo g_register_infos[] = { {13, 13, LLDB_INVALID_REGNUM, 13, 13}, nullptr, nullptr, + nullptr, }, {"r14", "", @@ -185,6 +199,7 @@ static const RegisterInfo g_register_infos[] = { {14, 14, LLDB_INVALID_REGNUM, 14, 14}, nullptr, nullptr, + nullptr, }, {"r15", "", @@ -195,6 +210,7 @@ static const RegisterInfo g_register_infos[] = { {15, 15, LLDB_INVALID_REGNUM, 15, 15}, nullptr, nullptr, + nullptr, }, {"r16", "", @@ -205,6 +221,7 @@ static const RegisterInfo g_register_infos[] = { {16, 16, LLDB_INVALID_REGNUM, 16, 16}, nullptr, nullptr, + nullptr, }, {"r17", "", @@ -215,6 +232,7 @@ static const RegisterInfo g_register_infos[] = { {17, 17, LLDB_INVALID_REGNUM, 17, 17}, nullptr, nullptr, + nullptr, }, {"r18", "", @@ -225,6 +243,7 @@ static const RegisterInfo g_register_infos[] = { {18, 18, LLDB_INVALID_REGNUM, 18, 18}, nullptr, nullptr, + nullptr, }, {"r19", "", @@ -235,6 +254,7 @@ static const RegisterInfo g_register_infos[] = { {19, 19, LLDB_INVALID_REGNUM, 19, 19}, nullptr, nullptr, + nullptr, }, {"r20", "", @@ -245,6 +265,7 @@ static const RegisterInfo g_register_infos[] = { {20, 20, LLDB_INVALID_REGNUM, 20, 20}, nullptr, nullptr, + nullptr, }, {"r21", "", @@ -255,6 +276,7 @@ static const RegisterInfo g_register_infos[] = { {21, 21, LLDB_INVALID_REGNUM, 21, 21}, nullptr, nullptr, + nullptr, }, {"r22", "", @@ -265,6 +287,7 @@ static const RegisterInfo g_register_infos[] = { {22, 22, LLDB_INVALID_REGNUM, 22, 22}, nullptr, nullptr, + nullptr, }, {"r23", "", @@ -275,6 +298,7 @@ static const RegisterInfo g_register_infos[] = { {23, 23, LLDB_INVALID_REGNUM, 23, 23}, nullptr, nullptr, + nullptr, }, {"r24", "", @@ -285,6 +309,7 @@ static const RegisterInfo g_register_infos[] = { {24, 24, LLDB_INVALID_REGNUM, 24, 24}, nullptr, nullptr, + nullptr, }, {"r25", "", @@ -295,6 +320,7 @@ static const RegisterInfo g_register_infos[] = { {25, 25, LLDB_INVALID_REGNUM, 25, 25}, nullptr, nullptr, + nullptr, }, {"r26", "", @@ -305,6 +331,7 @@ static const RegisterInfo g_register_infos[] = { {26, 26, LLDB_INVALID_REGNUM, 26, 26}, nullptr, nullptr, + nullptr, }, {"r27", "", @@ -315,6 +342,7 @@ static const RegisterInfo g_register_infos[] = { {27, 27, LLDB_INVALID_REGNUM, 27, 27}, nullptr, nullptr, + nullptr, }, {"r28", "", @@ -325,6 +353,7 @@ static const RegisterInfo g_register_infos[] = { {28, 28, LLDB_INVALID_REGNUM, 28, 28}, nullptr, nullptr, + nullptr, }, {"sp", "r29", @@ -335,6 +364,7 @@ static const RegisterInfo g_register_infos[] = { {29, 29, LLDB_REGNUM_GENERIC_SP, 29, 29}, nullptr, nullptr, + nullptr, }, {"fp", "r30", @@ -345,6 +375,7 @@ static const RegisterInfo g_register_infos[] = { {30, 30, LLDB_REGNUM_GENERIC_FP, 30, 30}, nullptr, nullptr, + nullptr, }, {"lr", "r31", @@ -355,6 +386,7 @@ static const RegisterInfo g_register_infos[] = { {31, 31, LLDB_REGNUM_GENERIC_RA, 31, 31}, nullptr, nullptr, + nullptr, }, {"sa0", "", @@ -365,6 +397,7 @@ static const RegisterInfo g_register_infos[] = { {32, 32, LLDB_INVALID_REGNUM, 32, 32}, nullptr, nullptr, + nullptr, }, {"lc0", "", @@ -375,6 +408,7 @@ static const RegisterInfo g_register_infos[] = { {33, 33, LLDB_INVALID_REGNUM, 33, 33}, nullptr, nullptr, + nullptr, }, {"sa1", "", @@ -385,6 +419,7 @@ static const RegisterInfo g_register_infos[] = { {34, 34, LLDB_INVALID_REGNUM, 34, 34}, nullptr, nullptr, + nullptr, }, {"lc1", "", @@ -395,6 +430,7 @@ static const RegisterInfo g_register_infos[] = { {35, 35, LLDB_INVALID_REGNUM, 35, 35}, nullptr, nullptr, + nullptr, }, // --> hexagon-v4/5/55/56-sim.xml {"p3_0", @@ -406,6 +442,8 @@ static const RegisterInfo g_register_infos[] = { {36, 36, LLDB_INVALID_REGNUM, 36, 36}, nullptr, nullptr, + nullptr, + }, // PADDING { {"p00", @@ -417,6 +455,7 @@ static const RegisterInfo g_register_infos[] = { {37, 37, LLDB_INVALID_REGNUM, 37, 37}, nullptr, nullptr, + nullptr, }, // } {"m0", @@ -428,6 +467,7 @@ static const RegisterInfo g_register_infos[] = { {38, 38, LLDB_INVALID_REGNUM, 38, 38}, nullptr, nullptr, + nullptr, }, {"m1", "", @@ -438,6 +478,7 @@ static const RegisterInfo g_register_infos[] = { {39, 39, LLDB_INVALID_REGNUM, 39, 39}, nullptr, nullptr, + nullptr, }, {"usr", "", @@ -448,6 +489,7 @@ static const RegisterInfo g_register_infos[] = { {40, 40, LLDB_INVALID_REGNUM, 40, 40}, nullptr, nullptr, + nullptr, }, {"pc", "", @@ -458,6 +500,7 @@ static const RegisterInfo g_register_infos[] = { {41, 41, LLDB_REGNUM_GENERIC_PC, 41, 41}, nullptr, nullptr, + nullptr, }, {"ugp", "", @@ -468,6 +511,7 @@ static const RegisterInfo g_register_infos[] = { {42, 42, LLDB_INVALID_REGNUM, 42, 42}, nullptr, nullptr, + nullptr, }, {"gp", "", @@ -478,6 +522,7 @@ static const RegisterInfo g_register_infos[] = { {43, 43, LLDB_INVALID_REGNUM, 43, 43}, nullptr, nullptr, + nullptr, }, {"cs0", "", @@ -488,6 +533,7 @@ static const RegisterInfo g_register_infos[] = { {44, 44, LLDB_INVALID_REGNUM, 44, 44}, nullptr, nullptr, + nullptr, }, {"cs1", "", @@ -498,6 +544,7 @@ static const RegisterInfo g_register_infos[] = { {45, 45, LLDB_INVALID_REGNUM, 45, 45}, nullptr, nullptr, + nullptr, }, // PADDING { {"p01", @@ -509,6 +556,7 @@ static const RegisterInfo g_register_infos[] = { {46, 46, LLDB_INVALID_REGNUM, 46, 46}, nullptr, nullptr, + nullptr, }, {"p02", "", @@ -519,6 +567,7 @@ static const RegisterInfo g_register_infos[] = { {47, 47, LLDB_INVALID_REGNUM, 47, 47}, nullptr, nullptr, + nullptr, }, {"p03", "", @@ -529,6 +578,7 @@ static const RegisterInfo g_register_infos[] = { {48, 48, LLDB_INVALID_REGNUM, 48, 48}, nullptr, nullptr, + nullptr, }, {"p04", "", @@ -539,6 +589,7 @@ static const RegisterInfo g_register_infos[] = { {49, 49, LLDB_INVALID_REGNUM, 49, 49}, nullptr, nullptr, + nullptr, }, {"p05", "", @@ -549,6 +600,7 @@ static const RegisterInfo g_register_infos[] = { {50, 50, LLDB_INVALID_REGNUM, 50, 50}, nullptr, nullptr, + nullptr, }, {"p06", "", @@ -559,6 +611,7 @@ static const RegisterInfo g_register_infos[] = { {51, 51, LLDB_INVALID_REGNUM, 51, 51}, nullptr, nullptr, + nullptr, }, {"p07", "", @@ -569,6 +622,7 @@ static const RegisterInfo g_register_infos[] = { {52, 52, LLDB_INVALID_REGNUM, 52, 52}, nullptr, nullptr, + nullptr, }, {"p08", "", @@ -579,6 +633,7 @@ static const RegisterInfo g_register_infos[] = { {53, 53, LLDB_INVALID_REGNUM, 53, 53}, nullptr, nullptr, + nullptr, }, {"p09", "", @@ -589,6 +644,7 @@ static const RegisterInfo g_register_infos[] = { {54, 54, LLDB_INVALID_REGNUM, 54, 54}, nullptr, nullptr, + nullptr, }, {"p10", "", @@ -599,6 +655,7 @@ static const RegisterInfo g_register_infos[] = { {55, 55, LLDB_INVALID_REGNUM, 55, 55}, nullptr, nullptr, + nullptr, }, {"p11", "", @@ -609,6 +666,7 @@ static const RegisterInfo g_register_infos[] = { {56, 56, LLDB_INVALID_REGNUM, 56, 56}, nullptr, nullptr, + nullptr, }, {"p12", "", @@ -619,6 +677,7 @@ static const RegisterInfo g_register_infos[] = { {57, 57, LLDB_INVALID_REGNUM, 57, 57}, nullptr, nullptr, + nullptr, }, {"p13", "", @@ -629,6 +688,7 @@ static const RegisterInfo g_register_infos[] = { {58, 58, LLDB_INVALID_REGNUM, 58, 58}, nullptr, nullptr, + nullptr, }, {"p14", "", @@ -639,6 +699,7 @@ static const RegisterInfo g_register_infos[] = { {59, 59, LLDB_INVALID_REGNUM, 59, 59}, nullptr, nullptr, + nullptr, }, {"p15", "", @@ -649,6 +710,7 @@ static const RegisterInfo g_register_infos[] = { {60, 60, LLDB_INVALID_REGNUM, 60, 60}, nullptr, nullptr, + nullptr, }, {"p16", "", @@ -659,6 +721,7 @@ static const RegisterInfo g_register_infos[] = { {61, 61, LLDB_INVALID_REGNUM, 61, 61}, nullptr, nullptr, + nullptr, }, {"p17", "", @@ -669,6 +732,7 @@ static const RegisterInfo g_register_infos[] = { {62, 62, LLDB_INVALID_REGNUM, 62, 62}, nullptr, nullptr, + nullptr, }, {"p18", "", @@ -679,6 +743,7 @@ static const RegisterInfo g_register_infos[] = { {63, 63, LLDB_INVALID_REGNUM, 63, 63}, nullptr, nullptr, + nullptr, }, // } {"sgp0", @@ -690,6 +755,7 @@ static const RegisterInfo g_register_infos[] = { {64, 64, LLDB_INVALID_REGNUM, 64, 64}, nullptr, nullptr, + nullptr, }, // PADDING { {"p19", @@ -701,6 +767,7 @@ static const RegisterInfo g_register_infos[] = { {65, 65, LLDB_INVALID_REGNUM, 65, 65}, nullptr, nullptr, + nullptr, }, // } {"stid", @@ -712,6 +779,7 @@ static const RegisterInfo g_register_infos[] = { {66, 66, LLDB_INVALID_REGNUM, 66, 66}, nullptr, nullptr, + nullptr, }, {"elr", "", @@ -722,6 +790,7 @@ static const RegisterInfo g_register_infos[] = { {67, 67, LLDB_INVALID_REGNUM, 67, 67}, nullptr, nullptr, + nullptr, }, {"badva0", "", @@ -732,6 +801,7 @@ static const RegisterInfo g_register_infos[] = { {68, 68, LLDB_INVALID_REGNUM, 68, 68}, nullptr, nullptr, + nullptr, }, {"badva1", "", @@ -742,6 +812,7 @@ static const RegisterInfo g_register_infos[] = { {69, 69, LLDB_INVALID_REGNUM, 69, 69}, nullptr, nullptr, + nullptr, }, {"ssr", "", @@ -752,6 +823,7 @@ static const RegisterInfo g_register_infos[] = { {70, 70, LLDB_INVALID_REGNUM, 70, 70}, nullptr, nullptr, + nullptr, }, {"ccr", "", @@ -762,6 +834,7 @@ static const RegisterInfo g_register_infos[] = { {71, 71, LLDB_INVALID_REGNUM, 71, 71}, nullptr, nullptr, + nullptr, }, {"htid", "", @@ -772,6 +845,7 @@ static const RegisterInfo g_register_infos[] = { {72, 72, LLDB_INVALID_REGNUM, 72, 72}, nullptr, nullptr, + nullptr, }, // PADDING { {"p20", @@ -783,6 +857,7 @@ static const RegisterInfo g_register_infos[] = { {73, 73, LLDB_INVALID_REGNUM, 73, 73}, nullptr, nullptr, + nullptr, }, // } {"imask", @@ -794,6 +869,7 @@ static const RegisterInfo g_register_infos[] = { {74, 74, LLDB_INVALID_REGNUM, 74, 74}, nullptr, nullptr, + nullptr, }, // PADDING { {"p21", @@ -805,6 +881,7 @@ static const RegisterInfo g_register_infos[] = { {75, 75, LLDB_INVALID_REGNUM, 75, 75}, nullptr, nullptr, + nullptr, }, {"p22", "", @@ -815,6 +892,7 @@ static const RegisterInfo g_register_infos[] = { {76, 76, LLDB_INVALID_REGNUM, 76, 76}, nullptr, nullptr, + nullptr, }, {"p23", "", @@ -825,6 +903,7 @@ static const RegisterInfo g_register_infos[] = { {77, 77, LLDB_INVALID_REGNUM, 77, 77}, nullptr, nullptr, + nullptr, }, {"p24", "", @@ -835,6 +914,7 @@ static const RegisterInfo g_register_infos[] = { {78, 78, LLDB_INVALID_REGNUM, 78, 78}, nullptr, nullptr, + nullptr, }, {"p25", "", @@ -845,6 +925,7 @@ static const RegisterInfo g_register_infos[] = { {79, 79, LLDB_INVALID_REGNUM, 79, 79}, nullptr, nullptr, + nullptr, }, // } {"g0", @@ -856,6 +937,7 @@ static const RegisterInfo g_register_infos[] = { {80, 80, LLDB_INVALID_REGNUM, 80, 80}, nullptr, nullptr, + nullptr, }, {"g1", "", @@ -866,6 +948,7 @@ static const RegisterInfo g_register_infos[] = { {81, 81, LLDB_INVALID_REGNUM, 81, 81}, nullptr, nullptr, + nullptr, }, {"g2", "", @@ -876,6 +959,7 @@ static const RegisterInfo g_register_infos[] = { {82, 82, LLDB_INVALID_REGNUM, 82, 82}, nullptr, nullptr, + nullptr, }, {"g3", "", @@ -886,6 +970,7 @@ static const RegisterInfo g_register_infos[] = { {83, 83, LLDB_INVALID_REGNUM, 83, 83}, nullptr, nullptr, + nullptr, }}; static const uint32_t k_num_register_infos = diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp new file mode 100644 index 000000000000..7fb651aa6c18 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.cpp @@ -0,0 +1,365 @@ +//===-- ABISysV_msp430.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ABISysV_msp430.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/Core/ValueObjectMemory.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/Target.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" + +#include "llvm/IR/DerivedTypes.h" +#include "llvm/TargetParser/Triple.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE_ADV(ABISysV_msp430, ABIMSP430) + +enum dwarf_regnums { + dwarf_pc = 0, + dwarf_sp, + dwarf_r2, + dwarf_r3, + dwarf_fp, + dwarf_r5, + dwarf_r6, + dwarf_r7, + dwarf_r8, + dwarf_r9, + dwarf_r10, + dwarf_r11, + dwarf_r12, + dwarf_r13, + dwarf_r14, + dwarf_r15, +}; + +static const RegisterInfo g_register_infos[] = { + {"r0", + "pc", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r1", + "sp", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r2", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r3", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r4", + "fp", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_fp, dwarf_fp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r5", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r6", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r7", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r7, dwarf_r7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r8", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r9", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r10", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r11", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r12", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r13", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r13, dwarf_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r14", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r14, dwarf_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }, + {"r15", + "", + 2, + 0, + eEncodingUint, + eFormatHex, + {dwarf_r15, dwarf_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr, + }}; + +static const uint32_t k_num_register_infos = + sizeof(g_register_infos) / sizeof(RegisterInfo); + +const lldb_private::RegisterInfo * +ABISysV_msp430::GetRegisterInfoArray(uint32_t &count) { + // Make the C-string names and alt_names for the register infos into const + // C-string values by having the ConstString unique the names in the global + // constant C-string pool. + count = k_num_register_infos; + return g_register_infos; +} + +size_t ABISysV_msp430::GetRedZoneSize() const { return 0; } + +//------------------------------------------------------------------ +// Static Functions +//------------------------------------------------------------------ + +ABISP +ABISysV_msp430::CreateInstance(lldb::ProcessSP process_sp, + const ArchSpec &arch) { + if (arch.GetTriple().getArch() == llvm::Triple::msp430) { + return ABISP( + new ABISysV_msp430(std::move(process_sp), MakeMCRegisterInfo(arch))); + } + return ABISP(); +} + +bool ABISysV_msp430::PrepareTrivialCall(Thread &thread, lldb::addr_t sp, + lldb::addr_t pc, lldb::addr_t ra, + llvm::ArrayRef<addr_t> args) const { + // we don't use the traditional trivial call specialized for jit + return false; +} + +bool ABISysV_msp430::GetArgumentValues(Thread &thread, + ValueList &values) const { + return false; +} + +Status ABISysV_msp430::SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value_sp) { + return Status(); +} + +ValueObjectSP ABISysV_msp430::GetReturnValueObjectSimple( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + return return_valobj_sp; +} + +ValueObjectSP ABISysV_msp430::GetReturnValueObjectImpl( + Thread &thread, CompilerType &return_compiler_type) const { + ValueObjectSP return_valobj_sp; + return return_valobj_sp; +} + +// called when we are on the first instruction of a new function +bool ABISysV_msp430::CreateFunctionEntryUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t sp_reg_num = dwarf_sp; + uint32_t pc_reg_num = dwarf_pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 2); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -2, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("msp430 at-func-entry default"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + return true; +} + +bool ABISysV_msp430::CreateDefaultUnwindPlan(UnwindPlan &unwind_plan) { + unwind_plan.Clear(); + unwind_plan.SetRegisterKind(eRegisterKindDWARF); + + uint32_t fp_reg_num = dwarf_fp; + uint32_t sp_reg_num = dwarf_sp; + uint32_t pc_reg_num = dwarf_pc; + + UnwindPlan::RowSP row(new UnwindPlan::Row); + row->GetCFAValue().SetIsRegisterPlusOffset(sp_reg_num, 2); + row->SetRegisterLocationToAtCFAPlusOffset(pc_reg_num, -2, true); + row->SetRegisterLocationToIsCFAPlusOffset(sp_reg_num, 0, true); + row->SetRegisterLocationToUnspecified(fp_reg_num, true); + + unwind_plan.AppendRow(row); + unwind_plan.SetSourceName("msp430 default unwind plan"); + unwind_plan.SetSourcedFromCompiler(eLazyBoolNo); + unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolNo); + return true; +} + +bool ABISysV_msp430::RegisterIsVolatile(const RegisterInfo *reg_info) { + return !RegisterIsCalleeSaved(reg_info); +} + +bool ABISysV_msp430::RegisterIsCalleeSaved(const RegisterInfo *reg_info) { + int reg = ((reg_info->byte_offset) / 2); + + bool save = (reg >= 4) && (reg <= 10); + return save; +} + +void ABISysV_msp430::Initialize(void) { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "System V ABI for msp430 targets", CreateInstance); +} + +void ABISysV_msp430::Terminate(void) { + PluginManager::UnregisterPlugin(CreateInstance); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h b/contrib/llvm-project/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h new file mode 100644 index 000000000000..8ef39e7aa1bb --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/MSP430/ABISysV_msp430.h @@ -0,0 +1,90 @@ +//===-- ABISysV_msp430.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_ABI_MSP430_ABISYSV_MSP430_H +#define LLDB_SOURCE_PLUGINS_ABI_MSP430_ABISYSV_MSP430_H + +#include "lldb/Target/ABI.h" +#include "lldb/lldb-private.h" + +class ABISysV_msp430 : public lldb_private::RegInfoBasedABI { +public: + ~ABISysV_msp430() override = default; + + size_t GetRedZoneSize() const override; + + bool PrepareTrivialCall(lldb_private::Thread &thread, lldb::addr_t sp, + lldb::addr_t functionAddress, + lldb::addr_t returnAddress, + llvm::ArrayRef<lldb::addr_t> args) const override; + + bool GetArgumentValues(lldb_private::Thread &thread, + lldb_private::ValueList &values) const override; + + lldb_private::Status + SetReturnValueObject(lldb::StackFrameSP &frame_sp, + lldb::ValueObjectSP &new_value) override; + + lldb::ValueObjectSP + GetReturnValueObjectImpl(lldb_private::Thread &thread, + lldb_private::CompilerType &type) const override; + + bool + CreateFunctionEntryUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool CreateDefaultUnwindPlan(lldb_private::UnwindPlan &unwind_plan) override; + + bool RegisterIsVolatile(const lldb_private::RegisterInfo *reg_info) override; + + bool CallFrameAddressIsValid(lldb::addr_t cfa) override { + // Make sure the stack call frame addresses are 2 byte aligned + // and not zero + if (cfa & 0x01 || cfa == 0) + return false; + return true; + } + + bool CodeAddressIsValid(lldb::addr_t pc) override { return true; } + + const lldb_private::RegisterInfo * + GetRegisterInfoArray(uint32_t &count) override; + + uint64_t GetStackFrameSize() override { return 512; } + + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + + static void Initialize(); + + static void Terminate(); + + static lldb::ABISP CreateInstance(lldb::ProcessSP process_sp, + const lldb_private::ArchSpec &arch); + + static llvm::StringRef GetPluginNameStatic() { return "sysv-msp430"; } + + // PluginInterface protocol + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + +protected: + void CreateRegisterMapIfNeeded(); + + lldb::ValueObjectSP + GetReturnValueObjectSimple(lldb_private::Thread &thread, + lldb_private::CompilerType &ast_type) const; + + bool RegisterIsCalleeSaved(const lldb_private::RegisterInfo *reg_info); + +private: + using lldb_private::RegInfoBasedABI::RegInfoBasedABI; +}; + +#endif // LLDB_SOURCE_PLUGINS_ABI_MSP430_ABISYSV_MSP430_H 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 a94be159cbbd..0f99afa35a71 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 @@ -9,7 +9,7 @@ #include "ABISysV_mips.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -94,6 +94,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r1", "AT", @@ -105,6 +106,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r2", "v0", @@ -116,6 +118,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r3", "v1", @@ -127,6 +130,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r4", nullptr, @@ -138,6 +142,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r5", nullptr, @@ -149,6 +154,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r6", nullptr, @@ -160,6 +166,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r7", nullptr, @@ -171,6 +178,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r8", "arg5", @@ -182,6 +190,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r9", "arg6", @@ -193,6 +202,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r10", "arg7", @@ -204,6 +214,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r11", "arg8", @@ -215,6 +226,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r12", nullptr, @@ -226,6 +238,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13", nullptr, @@ -237,6 +250,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14", nullptr, @@ -248,6 +262,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r15", nullptr, @@ -259,6 +274,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r16", nullptr, @@ -270,6 +286,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r17", nullptr, @@ -281,6 +298,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r18", nullptr, @@ -292,6 +310,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r19", nullptr, @@ -303,6 +322,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r20", nullptr, @@ -314,6 +334,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r21", nullptr, @@ -325,6 +346,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r22", nullptr, @@ -336,6 +358,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r23", nullptr, @@ -347,6 +370,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r24", nullptr, @@ -358,6 +382,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r25", nullptr, @@ -369,6 +394,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r26", nullptr, @@ -380,6 +406,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r27", nullptr, @@ -391,6 +418,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r28", "gp", @@ -402,6 +430,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r29", nullptr, @@ -413,6 +442,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r30", nullptr, @@ -424,6 +454,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r31", nullptr, @@ -435,6 +466,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"sr", nullptr, @@ -446,6 +478,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"lo", nullptr, @@ -457,6 +490,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"hi", nullptr, @@ -468,6 +502,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"bad", nullptr, @@ -479,6 +514,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"cause", nullptr, @@ -490,6 +526,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"pc", nullptr, @@ -501,6 +538,7 @@ static const RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, }; 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 97b8e61a9b92..82529a3165c8 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 @@ -9,7 +9,7 @@ #include "ABISysV_mips64.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -94,6 +94,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r1", "AT", @@ -105,6 +106,8 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, + }, {"r2", "v0", @@ -116,6 +119,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r3", "v1", @@ -127,6 +131,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r4", nullptr, @@ -138,6 +143,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r5", nullptr, @@ -149,6 +155,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r6", nullptr, @@ -160,6 +167,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r7", nullptr, @@ -171,6 +179,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r8", nullptr, @@ -182,6 +191,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r9", nullptr, @@ -193,6 +203,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r10", nullptr, @@ -204,6 +215,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r11", nullptr, @@ -215,6 +227,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r12", nullptr, @@ -226,6 +239,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r13", nullptr, @@ -237,6 +251,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r14", nullptr, @@ -248,6 +263,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r15", nullptr, @@ -259,6 +275,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r16", nullptr, @@ -270,6 +287,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r17", nullptr, @@ -281,6 +299,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r18", nullptr, @@ -292,6 +311,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r19", nullptr, @@ -303,6 +323,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r20", nullptr, @@ -314,6 +335,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r21", nullptr, @@ -325,6 +347,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r22", nullptr, @@ -336,6 +359,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r23", nullptr, @@ -347,6 +371,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r24", nullptr, @@ -358,6 +383,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r25", nullptr, @@ -369,6 +395,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r26", nullptr, @@ -380,6 +407,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r27", nullptr, @@ -391,6 +419,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r28", "gp", @@ -402,6 +431,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r29", nullptr, @@ -413,6 +443,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r30", nullptr, @@ -424,6 +455,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"r31", nullptr, @@ -435,6 +467,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"sr", nullptr, @@ -446,6 +479,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"lo", nullptr, @@ -457,6 +491,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"hi", nullptr, @@ -468,6 +503,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"bad", nullptr, @@ -479,6 +515,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"cause", nullptr, @@ -490,6 +527,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, {"pc", nullptr, @@ -501,6 +539,7 @@ static const RegisterInfo g_register_infos_mips64[] = { LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }, }; 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 8879b57bed0c..a07d7179e5f8 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 @@ -9,7 +9,7 @@ #include "ABISysV_ppc.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -114,7 +114,7 @@ enum dwarf_regnums { #define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ { \ #reg, alt, 8, 0, eEncodingUint, eFormatHex, {kind1, kind2, kind3, kind4 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } static const RegisterInfo g_register_infos[] = { @@ -203,6 +203,7 @@ static const RegisterInfo g_register_infos[] = { {dwarf_cfa, dwarf_cfa, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, nullptr, nullptr, + nullptr, }}; static const uint32_t k_num_register_infos = std::size(g_register_infos); 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 bb4b4e037774..656f07437095 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 @@ -9,7 +9,7 @@ #include "ABISysV_ppc64.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "Utility/PPC64LE_DWARF_Registers.h" 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 4436bcd37503..2230797e0f5a 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 @@ -9,7 +9,7 @@ #include "ABISysV_s390x.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -117,7 +117,7 @@ enum dwarf_regnums { #name, alt, size, 0, eEncodingUint, eFormatHex, \ {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } static const RegisterInfo g_register_infos[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp index 4d2e16da4cda..10775f656b95 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABIMacOSX_i386.cpp @@ -12,7 +12,7 @@ #include <vector> #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp index 2bc6e3b891e6..cc48ceb5c1e0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ABI/X86/ABISysV_i386.cpp @@ -8,7 +8,7 @@ #include "ABISysV_i386.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" 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 9d5ed1fa2666..caa4efbd4c10 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 @@ -10,7 +10,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" 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 6d9b3ae3c636..9b1556b06f0a 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 @@ -10,7 +10,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h index e1b8558e1cda..da0b867fb1e9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Architecture/AArch64/ArchitectureAArch64.h @@ -22,7 +22,7 @@ public: llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } - void OverrideStopInfo(Thread &thread) const override{}; + void OverrideStopInfo(Thread &thread) const override {} const MemoryTagManager *GetMemoryTagManager() const override { return &m_memory_tag_manager; 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 ed3b3e6da02b..09115cc670da 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.cpp @@ -23,10 +23,10 @@ #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" +#include "llvm/TargetParser/AArch64TargetParser.h" #include "lldb/Core/Address.h" #include "lldb/Core/Module.h" @@ -1572,16 +1572,14 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, DisassemblerLLVMC::~DisassemblerLLVMC() = default; -Disassembler *DisassemblerLLVMC::CreateInstance(const ArchSpec &arch, - const char *flavor) { +lldb::DisassemblerSP DisassemblerLLVMC::CreateInstance(const ArchSpec &arch, + const char *flavor) { if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch) { - std::unique_ptr<DisassemblerLLVMC> disasm_up( - new DisassemblerLLVMC(arch, flavor)); - - if (disasm_up.get() && disasm_up->IsValid()) - return disasm_up.release(); + auto disasm_sp = std::make_shared<DisassemblerLLVMC>(arch, flavor); + if (disasm_sp && disasm_sp->IsValid()) + return disasm_sp; } - return nullptr; + return lldb::DisassemblerSP(); } size_t DisassemblerLLVMC::DecodeInstructions(const Address &base_addr, diff --git a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h index 68ae3a32e18f..30c69de81dfc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h +++ b/contrib/llvm-project/lldb/source/Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h @@ -34,8 +34,8 @@ public: static llvm::StringRef GetPluginNameStatic() { return "llvm-mc"; } - static lldb_private::Disassembler * - CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor); + static lldb::DisassemblerSP CreateInstance(const lldb_private::ArchSpec &arch, + const char *flavor); size_t DecodeInstructions(const lldb_private::Address &base_addr, const lldb_private::DataExtractor &data, 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 1834402bb2b1..96c94535c623 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 @@ -420,21 +420,17 @@ DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread, const ModuleList &images = target.GetImages(); images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols); - size_t num_targets = target_symbols.GetSize(); - if (!num_targets) + if (target_symbols.GetSize() == 0) return thread_plan_sp; typedef std::vector<lldb::addr_t> AddressVector; AddressVector addrs; - for (size_t i = 0; i < num_targets; ++i) { - SymbolContext context; + for (const SymbolContext &context : target_symbols) { AddressRange range; - if (target_symbols.GetContextAtIndex(i, context)) { - context.GetAddressRange(eSymbolContextEverything, 0, false, range); - lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target); - if (addr != LLDB_INVALID_ADDRESS) - addrs.push_back(addr); - } + context.GetAddressRange(eSymbolContextEverything, 0, false, range); + lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target); + if (addr != LLDB_INVALID_ADDRESS) + addrs.push_back(addr); } if (addrs.size() > 0) { 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 13a6ffa78a6e..b4b38a88e1b9 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 @@ -511,21 +511,17 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, const ModuleList &images = target.GetImages(); images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols); - size_t num_targets = target_symbols.GetSize(); - if (!num_targets) + if (!target_symbols.GetSize()) return thread_plan_sp; typedef std::vector<lldb::addr_t> AddressVector; AddressVector addrs; - for (size_t i = 0; i < num_targets; ++i) { - SymbolContext context; + for (const SymbolContext &context : target_symbols) { AddressRange range; - if (target_symbols.GetContextAtIndex(i, context)) { - context.GetAddressRange(eSymbolContextEverything, 0, false, range); - lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target); - if (addr != LLDB_INVALID_ADDRESS) - addrs.push_back(addr); - } + context.GetAddressRange(eSymbolContextEverything, 0, false, range); + lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target); + if (addr != LLDB_INVALID_ADDRESS) + addrs.push_back(addr); } if (addrs.size() > 0) { 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 fa6356963fca..f044aa786806 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 @@ -19,7 +19,7 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" using namespace lldb; using namespace lldb_private; 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 07cb4c9f027c..3e2c208bd201 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -429,15 +429,10 @@ void ASTResultSynthesizer::MaybeRecordPersistentType(TypeDecl *D) { return; StringRef name = D->getName(); - - if (name.size() == 0 || name[0] != '$') + if (name.empty() || name.front() != '$') return; - Log *log = GetLog(LLDBLog::Expressions); - - ConstString name_cs(name.str().c_str()); - - LLDB_LOGF(log, "Recording persistent type %s\n", name_cs.GetCString()); + LLDB_LOG(GetLog(LLDBLog::Expressions), "Recording persistent type {0}", name); m_decls.push_back(D); } @@ -449,15 +444,10 @@ void ASTResultSynthesizer::RecordPersistentDecl(NamedDecl *D) { return; StringRef name = D->getName(); - - if (name.size() == 0) + if (name.empty()) return; - Log *log = GetLog(LLDBLog::Expressions); - - ConstString name_cs(name.str().c_str()); - - LLDB_LOGF(log, "Recording persistent decl %s\n", name_cs.GetCString()); + LLDB_LOG(GetLog(LLDBLog::Expressions), "Recording persistent decl {0}", name); m_decls.push_back(D); } @@ -475,7 +465,6 @@ void ASTResultSynthesizer::CommitPersistentDecls() { for (clang::NamedDecl *decl : m_decls) { StringRef name = decl->getName(); - ConstString name_cs(name.str().c_str()); Decl *D_scratch = persistent_vars->GetClangASTImporter()->DeportDecl( &scratch_ts_sp->getASTContext(), decl); @@ -496,8 +485,8 @@ void ASTResultSynthesizer::CommitPersistentDecls() { } if (NamedDecl *NamedDecl_scratch = dyn_cast<NamedDecl>(D_scratch)) - persistent_vars->RegisterPersistentDecl(name_cs, NamedDecl_scratch, - scratch_ts_sp); + persistent_vars->RegisterPersistentDecl(ConstString(name), + NamedDecl_scratch, scratch_ts_sp); } } 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 c084c3fbefc5..2826b102625f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp @@ -113,7 +113,7 @@ private: llvm::DenseMap<clang::Decl *, Backup> m_backups; void OverrideOne(clang::Decl *decl) { - if (m_backups.find(decl) != m_backups.end()) { + if (m_backups.contains(decl)) { return; } 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 108566b066d7..5d7e1252038d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -700,7 +700,18 @@ void ClangASTSource::FillNamespaceMap( if (!symbol_file) continue; - found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl); + // If namespace_decl is not valid, 'FindNamespace' would look for + // any namespace called 'name' (ignoring parent contexts) and return + // the first one it finds. Thus if we're doing a qualified lookup only + // consider root namespaces. E.g., in an expression ::A::B::Foo, the + // lookup of ::A will result in a qualified lookup. Note, namespace + // disambiguation for function calls are handled separately in + // SearchFunctionsInSymbolContexts. + const bool find_root_namespaces = + context.m_decl_context && + context.m_decl_context->shouldUseQualifiedLookup(); + found_namespace_decl = symbol_file->FindNamespace( + name, namespace_decl, /* only root namespaces */ find_root_namespaces); if (found_namespace_decl) { context.m_namespace_map->push_back( @@ -1025,12 +1036,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { lldb::eFunctionNameTypeSelector, function_options, candidate_sc_list); - for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) { - SymbolContext candidate_sc; - - if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc)) - continue; - + for (const SymbolContext &candidate_sc : candidate_sc_list) { if (!candidate_sc.function) continue; @@ -1063,12 +1069,7 @@ void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) { if (sc_list.GetSize()) { // We found a good function symbol. Use that. - for (uint32_t i = 0, e = sc_list.GetSize(); i != e; ++i) { - SymbolContext sc; - - if (!sc_list.GetContextAtIndex(i, sc)) - continue; - + for (const SymbolContext &sc : sc_list) { if (!sc.function) continue; 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 c573b8b8154a..6fbc0bb22f82 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -76,8 +76,7 @@ lldb::ValueObjectSP GetCapturedThisValueObject(StackFrame *frame) { assert(frame); if (auto thisValSP = frame->FindVariable(ConstString("this"))) - if (auto thisThisValSP = - thisValSP->GetChildMemberWithName(ConstString("this"), true)) + if (auto thisThisValSP = thisValSP->GetChildMemberWithName("this")) return thisThisValSP; return nullptr; @@ -531,15 +530,11 @@ addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target, else target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list); - const uint32_t num_matches = sc_list.GetSize(); addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; - for (uint32_t i = 0; - i < num_matches && - (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS); - i++) { - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(i, sym_ctx); + for (const SymbolContext &sym_ctx : sc_list) { + if (symbol_load_addr != 0 && symbol_load_addr != LLDB_INVALID_ADDRESS) + break; const Address sym_address = sym_ctx.symbol->GetAddress(); @@ -1111,7 +1106,7 @@ bool ClangExpressionDeclMap::LookupLocalVariable( auto find_capture = [](ConstString varname, StackFrame *frame) -> ValueObjectSP { if (auto lambda = ClangExpressionUtil::GetLambdaValueObject(frame)) { - if (auto capture = lambda->GetChildMemberWithName(varname, true)) { + if (auto capture = lambda->GetChildMemberWithName(varname)) { return capture; } } @@ -1147,19 +1142,16 @@ SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts( // remove unwanted functions and separate out the functions we want to // compare and prune into a separate list. Cache the info needed about // the function declarations in a vector for efficiency. - uint32_t num_indices = sc_list.GetSize(); SymbolContextList sc_sym_list; std::vector<FuncDeclInfo> decl_infos; - decl_infos.reserve(num_indices); + decl_infos.reserve(sc_list.GetSize()); clang::DeclContext *frame_decl_ctx = (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext(); TypeSystemClang *ast = llvm::dyn_cast_or_null<TypeSystemClang>( frame_decl_context.GetTypeSystem()); - for (uint32_t index = 0; index < num_indices; ++index) { + for (const SymbolContext &sym_ctx : sc_list) { FuncDeclInfo fdi; - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(index, sym_ctx); // We don't know enough about symbols to compare them, but we should // keep them in the list. @@ -1172,8 +1164,7 @@ SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts( // class/instance methods, since they'll be skipped in the code that // follows anyway. CompilerDeclContext func_decl_context = function->GetDeclContext(); - if (!func_decl_context || - func_decl_context.IsClassMethod(nullptr, nullptr, nullptr)) + if (!func_decl_context || func_decl_context.IsClassMethod()) continue; // We can only prune functions for which we can copy the type. CompilerType func_clang_type = function->GetType()->GetFullCompilerType(); @@ -1295,11 +1286,7 @@ void ClangExpressionDeclMap::LookupFunction( Symbol *extern_symbol = nullptr; Symbol *non_extern_symbol = nullptr; - for (uint32_t index = 0, num_indices = sc_list.GetSize(); - index < num_indices; ++index) { - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(index, sym_ctx); - + for (const SymbolContext &sym_ctx : sc_list) { if (sym_ctx.function) { CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext(); @@ -1307,23 +1294,24 @@ void ClangExpressionDeclMap::LookupFunction( continue; // Filter out class/instance methods. - if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr)) + if (decl_ctx.IsClassMethod()) continue; AddOneFunction(context, sym_ctx.function, nullptr); context.m_found_function_with_type_info = true; context.m_found_function = true; } else if (sym_ctx.symbol) { - if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) { - sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target); - if (sym_ctx.symbol == nullptr) + Symbol *symbol = sym_ctx.symbol; + if (target && symbol->GetType() == eSymbolTypeReExported) { + symbol = symbol->ResolveReExportedSymbol(*target); + if (symbol == nullptr) continue; } - if (sym_ctx.symbol->IsExternal()) - extern_symbol = sym_ctx.symbol; + if (symbol->IsExternal()) + extern_symbol = symbol; else - non_extern_symbol = sym_ctx.symbol; + non_extern_symbol = symbol; } } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.cpp new file mode 100644 index 000000000000..97f9d17958fa --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.cpp @@ -0,0 +1,13 @@ +//===-- ClangExpressionHelper.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 "ClangExpressionHelper.h" + +using namespace lldb_private; + +char ClangExpressionHelper::ID; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h index 37bcaf000cfc..e66d46c21ddf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h @@ -24,21 +24,14 @@ class ASTConsumer; namespace lldb_private { class ClangExpressionDeclMap; -class RecordingMemoryManager; // ClangExpressionHelper -class ClangExpressionHelper : public ExpressionTypeSystemHelper { +class ClangExpressionHelper + : public llvm::RTTIExtends<ClangExpressionHelper, + ExpressionTypeSystemHelper> { public: - static bool classof(const ExpressionTypeSystemHelper *ts) { - return ts->getKind() == eKindClangHelper; - } - - ClangExpressionHelper() - : ExpressionTypeSystemHelper( - ExpressionTypeSystemHelper::LLVMCastKind::eKindClangHelper) {} - - /// Destructor - virtual ~ClangExpressionHelper() = default; + // LLVM RTTI support + static char ID; /// Return the object that the parser should use when resolving external /// values. May be NULL if everything should be self-contained. @@ -54,8 +47,6 @@ public: ASTTransformer(clang::ASTConsumer *passthrough) = 0; virtual void CommitPersistentDecls() {} - -protected: }; } // namespace lldb_private 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 58e81fb1cd74..f3d6ea26b30d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -46,9 +46,9 @@ #include "llvm/IR/Module.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Signals.h" +#include "llvm/TargetParser/Host.h" #include "ClangDiagnostic.h" #include "ClangExpressionParser.h" @@ -91,7 +91,6 @@ #include "lldb/Utility/StringList.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" -#include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h" #include <cctype> #include <memory> @@ -396,8 +395,6 @@ ClangExpressionParser::ClangExpressionParser( lldb::LanguageType frame_lang = expr.Language(); // defaults to lldb::eLanguageTypeUnknown - bool overridden_target_opts = false; - lldb_private::LanguageRuntime *lang_rt = nullptr; std::string abi; ArchSpec target_arch; @@ -417,7 +414,6 @@ ClangExpressionParser::ClangExpressionParser( frame_lang = frame_sp->GetLanguage(); if (process_sp && frame_lang != lldb::eLanguageTypeUnknown) { - lang_rt = process_sp->GetLanguageRuntime(frame_lang); LLDB_LOGF(log, "Frame has language of type %s", Language::GetNameForLanguageType(frame_lang)); } @@ -464,34 +460,7 @@ ClangExpressionParser::ClangExpressionParser( if (!abi.empty()) m_compiler->getTargetOpts().ABI = abi; - // 3. Now allow the runtime to provide custom configuration options for the - // target. In this case, a specialized language runtime is available and we - // can query it for extra options. For 99% of use cases, this will not be - // needed and should be provided when basic platform detection is not enough. - // FIXME: Generalize this. Only RenderScriptRuntime currently supports this - // currently. Hardcoding this isn't ideal but it's better than LanguageRuntime - // having knowledge of clang::TargetOpts. - if (auto *renderscript_rt = - llvm::dyn_cast_or_null<RenderScriptRuntime>(lang_rt)) - overridden_target_opts = - renderscript_rt->GetOverrideExprOptions(m_compiler->getTargetOpts()); - - if (overridden_target_opts) - if (log && log->GetVerbose()) { - LLDB_LOGV( - log, "Using overridden target options for the expression evaluation"); - - auto opts = m_compiler->getTargetOpts(); - LLDB_LOGV(log, "Triple: '{0}'", opts.Triple); - LLDB_LOGV(log, "CPU: '{0}'", opts.CPU); - LLDB_LOGV(log, "FPMath: '{0}'", opts.FPMath); - LLDB_LOGV(log, "ABI: '{0}'", opts.ABI); - LLDB_LOGV(log, "LinkerVersion: '{0}'", opts.LinkerVersion); - StringList::LogDump(log, opts.FeaturesAsWritten, "FeaturesAsWritten"); - StringList::LogDump(log, opts.Features, "Features"); - } - - // 4. Create and install the target on the compiler. + // 3. Create and install the target on the compiler. m_compiler->createDiagnostics(); // Limit the number of error diagnostics we emit. // A value of 0 means no limit for both LLDB and Clang. @@ -500,8 +469,6 @@ ClangExpressionParser::ClangExpressionParser( auto target_info = TargetInfo::CreateTargetInfo( m_compiler->getDiagnostics(), m_compiler->getInvocation().TargetOpts); if (log) { - LLDB_LOGF(log, "Using SIMD alignment: %d", - target_info->getSimdDefaultAlign()); LLDB_LOGF(log, "Target datalayout string: '%s'", target_info->getDataLayoutString()); LLDB_LOGF(log, "Target ABI: '%s'", target_info->getABI().str().c_str()); @@ -512,7 +479,7 @@ ClangExpressionParser::ClangExpressionParser( assert(m_compiler->hasTarget()); - // 5. Set language options. + // 4. Set language options. lldb::LanguageType language = expr.Language(); LangOptions &lang_opts = m_compiler->getLangOpts(); @@ -542,6 +509,16 @@ ClangExpressionParser::ClangExpressionParser( // be re-evaluated in the future. lang_opts.CPlusPlus11 = true; break; + case lldb::eLanguageTypeC_plus_plus_20: + lang_opts.CPlusPlus20 = true; + [[fallthrough]]; + case lldb::eLanguageTypeC_plus_plus_17: + // FIXME: add a separate case for CPlusPlus14. Currently folded into C++17 + // because C++14 is the default standard for Clang but enabling CPlusPlus14 + // expression evaluatino doesn't pass the test-suite cleanly. + lang_opts.CPlusPlus14 = true; + lang_opts.CPlusPlus17 = true; + [[fallthrough]]; case lldb::eLanguageTypeC_plus_plus: case lldb::eLanguageTypeC_plus_plus_11: case lldb::eLanguageTypeC_plus_plus_14: @@ -598,7 +575,6 @@ ClangExpressionParser::ClangExpressionParser( // FIXME: We should ask the driver for the appropriate default flags. lang_opts.GNUMode = true; lang_opts.GNUKeywords = true; - lang_opts.DoubleSquareBracketAttributes = true; lang_opts.CPlusPlus11 = true; // The Darwin libc expects this macro to be set. @@ -610,12 +586,19 @@ ClangExpressionParser::ClangExpressionParser( if (process_sp && lang_opts.ObjC) { if (auto *runtime = ObjCLanguageRuntime::Get(*process_sp)) { - if (runtime->GetRuntimeVersion() == - ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2) + switch (runtime->GetRuntimeVersion()) { + case ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2: lang_opts.ObjCRuntime.set(ObjCRuntime::MacOSX, VersionTuple(10, 7)); - else + break; + case ObjCLanguageRuntime::ObjCRuntimeVersions::eObjC_VersionUnknown: + case ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V1: lang_opts.ObjCRuntime.set(ObjCRuntime::FragileMacOSX, VersionTuple(10, 7)); + break; + case ObjCLanguageRuntime::ObjCRuntimeVersions::eGNUstep_libobjc2: + lang_opts.ObjCRuntime.set(ObjCRuntime::GNUstep, VersionTuple(2, 0)); + break; + } if (runtime->HasNewLiteralsAndIndexing()) lang_opts.DebuggerObjCLiteral = true; @@ -650,13 +633,13 @@ ClangExpressionParser::ClangExpressionParser( m_compiler->getTarget().adjust(m_compiler->getDiagnostics(), m_compiler->getLangOpts()); - // 6. Set up the diagnostic buffer for reporting errors + // 5. Set up the diagnostic buffer for reporting errors auto diag_mgr = new ClangDiagnosticManagerAdapter( m_compiler->getDiagnostics().getDiagnosticOptions()); m_compiler->getDiagnostics().setClient(diag_mgr); - // 7. Set up the source management objects inside the compiler + // 6. Set up the source management objects inside the compiler m_compiler->createFileManager(); if (!m_compiler->hasSourceManager()) m_compiler->createSourceManager(m_compiler->getFileManager()); @@ -691,7 +674,7 @@ ClangExpressionParser::ClangExpressionParser( } } - // 8. Most of this we get from the CompilerInstance, but we also want to give + // 7. Most of this we get from the CompilerInstance, but we also want to give // the context an ExternalASTSource. auto &PP = m_compiler->getPreprocessor(); @@ -1436,14 +1419,12 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( ClangDynamicCheckerFunctions *dynamic_checkers = new ClangDynamicCheckerFunctions(); - DiagnosticManager install_diagnostics; - - if (!dynamic_checkers->Install(install_diagnostics, exe_ctx)) { - if (install_diagnostics.Diagnostics().size()) - err.SetErrorString(install_diagnostics.GetString().c_str()); - else - err.SetErrorString("couldn't install checkers, unknown error"); - + DiagnosticManager install_diags; + if (Error Err = dynamic_checkers->Install(install_diags, exe_ctx)) { + std::string ErrMsg = "couldn't install checkers: " + toString(std::move(Err)); + if (install_diags.Diagnostics().size()) + ErrMsg = ErrMsg + "\n" + install_diags.GetString().c_str(); + err.SetErrorString(ErrMsg); return 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 56c00b35ba11..b48bbbecc0cd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionSourceCode.cpp @@ -14,6 +14,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" +#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/StringRef.h" #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" @@ -141,6 +142,17 @@ static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit, if (dm == nullptr) return; + // The macros directives below can potentially redefine builtin macros of the + // Clang instance which parses the user expression. The Clang diagnostics + // caused by this are not useful for the user as the source code here is + // generated by LLDB. + stream << "#pragma clang diagnostic push\n"; + stream << "#pragma clang diagnostic ignored \"-Wmacro-redefined\"\n"; + stream << "#pragma clang diagnostic ignored \"-Wbuiltin-macro-redefined\"\n"; + auto pop_warning = llvm::make_scope_exit([&stream](){ + stream << "#pragma clang diagnostic pop\n"; + }); + for (size_t i = 0; i < dm->GetNumMacroEntries(); i++) { const DebugMacroEntry &entry = dm->GetMacroEntryAtIndex(i); uint32_t line; @@ -200,7 +212,7 @@ public: /// Returns true iff the given expression body contained a token with the /// given content. bool hasToken(llvm::StringRef token) const { - return m_tokens.find(token) != m_tokens.end(); + return m_tokens.contains(token); } }; @@ -219,7 +231,7 @@ void AddLambdaCaptureDecls(StreamString &stream, StackFrame *frame, if (auto thisValSP = ClangExpressionUtil::GetLambdaValueObject(frame)) { uint32_t numChildren = thisValSP->GetNumChildren(); for (uint32_t i = 0; i < numChildren; ++i) { - auto childVal = thisValSP->GetChildAtIndex(i, true); + auto childVal = thisValSP->GetChildAtIndex(i); ConstString childName(childVal ? childVal->GetName() : ConstString("")); if (!childName.IsEmpty() && verifier.hasToken(childName.GetStringRef()) && @@ -262,7 +274,7 @@ TokenVerifier::TokenVerifier(std::string body) { LangOptions Opts; Opts.ObjC = true; Opts.DollarIdents = true; - Opts.CPlusPlus17 = true; + Opts.CPlusPlus20 = true; Opts.LineComment = true; Lexer lex(FID, buf->getMemBufferRef(), SM, Opts); diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionUtil.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionUtil.cpp index 9b490e1c036e..723a3d7e5984 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionUtil.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionUtil.cpp @@ -18,7 +18,7 @@ lldb::ValueObjectSP GetLambdaValueObject(StackFrame *frame) { assert(frame); if (auto this_val_sp = frame->FindVariable(ConstString("this"))) - if (this_val_sp->GetChildMemberWithName(ConstString("this"), true)) + if (this_val_sp->GetChildMemberWithName("this")) return this_val_sp; return nullptr; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp index 9af92e194da9..ac3cb0b1bdf3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.cpp @@ -20,11 +20,12 @@ using namespace lldb_private; using namespace clang; +char ClangExpressionVariable::ID; + ClangExpressionVariable::ClangExpressionVariable( ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size) - : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(), - m_jit_vars() { + : m_parser_vars(), m_jit_vars() { m_flags = EVNone; m_frozen_sp = ValueObjectConstResult::Create(exe_scope, byte_order, addr_byte_size); @@ -33,16 +34,14 @@ ClangExpressionVariable::ClangExpressionVariable( ClangExpressionVariable::ClangExpressionVariable( ExecutionContextScope *exe_scope, Value &value, ConstString name, uint16_t flags) - : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(), - m_jit_vars() { + : m_parser_vars(), m_jit_vars() { m_flags = flags; m_frozen_sp = ValueObjectConstResult::Create(exe_scope, value, name); } ClangExpressionVariable::ClangExpressionVariable( const lldb::ValueObjectSP &valobj_sp) - : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(), - m_jit_vars() { + : m_parser_vars(), m_jit_vars() { m_flags = EVNone; m_frozen_sp = valobj_sp; } @@ -51,8 +50,7 @@ ClangExpressionVariable::ClangExpressionVariable( ExecutionContextScope *exe_scope, ConstString name, const TypeFromUser &user_type, lldb::ByteOrder byte_order, uint32_t addr_byte_size) - : ExpressionVariable(LLVMCastKind::eKindClang), m_parser_vars(), - m_jit_vars() { + : m_parser_vars(), m_jit_vars() { m_flags = EVNone; m_frozen_sp = ValueObjectConstResult::Create(exe_scope, byte_order, addr_byte_size); diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h index c7d9e05269fa..193ada018fa4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h @@ -57,8 +57,12 @@ class ValueObjectConstResult; /// /// This class supports all of these use cases using simple type polymorphism, /// and provides necessary support methods. Its interface is RTTI-neutral. -class ClangExpressionVariable : public ExpressionVariable { +class ClangExpressionVariable + : public llvm::RTTIExtends<ClangExpressionVariable, ExpressionVariable> { public: + // LLVM RTTI support + static char ID; + ClangExpressionVariable(ExecutionContextScope *exe_scope, lldb::ByteOrder byte_order, uint32_t addr_byte_size); @@ -197,11 +201,6 @@ public: TypeFromUser GetTypeFromUser(); - // llvm casting support - static bool classof(const ExpressionVariable *ev) { - return ev->getKind() == ExpressionVariable::eKindClang; - } - /// Members ClangExpressionVariable(const ClangExpressionVariable &) = delete; const ClangExpressionVariable & 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 f1449c02c9dc..5235cd2a1461 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp @@ -17,9 +17,9 @@ #include "clang/CodeGen/ModuleBuilder.h" #include "clang/Frontend/CompilerInstance.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/IR/Module.h" +#include "llvm/TargetParser/Triple.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Core/Module.h" @@ -207,6 +207,8 @@ ClangFunctionCaller::CompileFunction(lldb::ThreadSP thread_to_use_sp, return num_errors; } +char ClangFunctionCaller::ClangFunctionCallerHelper::ID; + clang::ASTConsumer * ClangFunctionCaller::ClangFunctionCallerHelper::ASTTransformer( clang::ASTConsumer *passthrough) { diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h index 151935b0ce68..2a5c863b51a2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h @@ -57,11 +57,14 @@ class ASTStructExtractor; class ClangFunctionCaller : public FunctionCaller { friend class ASTStructExtractor; - class ClangFunctionCallerHelper : public ClangExpressionHelper { + class ClangFunctionCallerHelper + : public llvm::RTTIExtends<ClangFunctionCallerHelper, + ClangExpressionHelper> { public: - ClangFunctionCallerHelper(ClangFunctionCaller &owner) : m_owner(owner) {} + // LLVM RTTI support + static char ID; - ~ClangFunctionCallerHelper() override = default; + ClangFunctionCallerHelper(ClangFunctionCaller &owner) : m_owner(owner) {} /// Return the object that the parser should use when resolving external /// values. May be NULL if everything should be self-contained. diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp index ae4dcc05256e..6064c02c7fd6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp @@ -10,6 +10,7 @@ #include "clang/Basic/Version.h" #include "clang/Config/config.h" +#include "clang/Driver/Driver.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" @@ -51,11 +52,14 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec, Log *log = GetLog(LLDBLog::Host); std::string raw_path = lldb_shlib_spec.GetPath(); llvm::StringRef parent_dir = llvm::sys::path::parent_path(raw_path); + static const std::string clang_resource_path = + clang::driver::Driver::GetResourcesPath("bin/lldb", CLANG_RESOURCE_DIR); static const llvm::StringRef kResourceDirSuffixes[] = { // LLVM.org's build of LLDB uses the clang resource directory placed - // in $install_dir/lib{,64}/clang/$clang_version. - CLANG_INSTALL_LIBDIR_BASENAME "/clang/" CLANG_VERSION_MAJOR_STRING, + // in $install_dir/lib{,64}/clang/$clang_version or + // $install_dir/bin/$CLANG_RESOURCE_DIR + clang_resource_path, // swift-lldb uses the clang resource directory copied from swift, which // by default is placed in $install_dir/lib{,64}/lldb/clang. LLDB places // it there, so we use LLDB_INSTALL_LIBDIR_BASENAME. @@ -82,7 +86,8 @@ static bool DefaultComputeClangResourceDirectory(FileSpec &lldb_shlib_spec, } bool lldb_private::ComputeClangResourceDirectory(FileSpec &lldb_shlib_spec, - FileSpec &file_spec, bool verify) { + FileSpec &file_spec, + bool verify) { #if !defined(__APPLE__) return DefaultComputeClangResourceDirectory(lldb_shlib_spec, file_spec, verify); 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 2b98fc83097a..5ce0d3537823 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -68,7 +68,7 @@ public: private: bool HandleModuleRemark(const clang::Diagnostic &info); - void SetCurrentModuleProgress(llvm::StringRef module_name); + void SetCurrentModuleProgress(std::string module_name); typedef std::pair<clang::DiagnosticsEngine::Level, std::string> IDAndDiagnostic; @@ -208,8 +208,9 @@ bool StoringDiagnosticConsumer::HandleModuleRemark( if (m_module_build_stack.empty()) { m_current_progress_up = nullptr; } else { - // Update the progress to re-show the module that was currently being - // built from the time the now completed module was originally began. + // When the just completed module began building, a module that depends on + // it ("module A") was effectively paused. Update the progress to re-show + // "module A" as continuing to be built. const auto &resumed_module_name = m_module_build_stack.back(); SetCurrentModuleProgress(resumed_module_name); } @@ -224,13 +225,12 @@ bool StoringDiagnosticConsumer::HandleModuleRemark( } void StoringDiagnosticConsumer::SetCurrentModuleProgress( - llvm::StringRef module_name) { - // Ensure the ordering of: - // 1. Completing the existing progress event. - // 2. Beginining a new progress event. - m_current_progress_up = nullptr; - m_current_progress_up = std::make_unique<Progress>( - llvm::formatv("Currently building module {0}", module_name)); + std::string module_name) { + if (!m_current_progress_up) + m_current_progress_up = + std::make_unique<Progress>("Building Clang modules"); + + m_current_progress_up->Increment(1, std::move(module_name)); } ClangModulesDeclVendor::ClangModulesDeclVendor() @@ -329,14 +329,14 @@ bool ClangModulesDeclVendorImpl::AddModule(const SourceModule &module, bool is_system = true; bool is_framework = false; - auto dir = - HS.getFileMgr().getDirectory(module.search_path.GetStringRef()); + auto dir = HS.getFileMgr().getOptionalDirectoryRef( + module.search_path.GetStringRef()); if (!dir) return error(); - auto *file = HS.lookupModuleMapFile(*dir, is_framework); + auto file = HS.lookupModuleMapFile(*dir, is_framework); if (!file) return error(); - if (!HS.loadModuleMapFile(file, is_system)) + if (!HS.loadModuleMapFile(*file, is_system)) return error(); } } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp index a7b20a5b6853..aa0e6e37d63e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp @@ -26,10 +26,11 @@ using namespace lldb; using namespace lldb_private; +char ClangPersistentVariables::ID; + ClangPersistentVariables::ClangPersistentVariables( std::shared_ptr<Target> target_sp) - : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang), - m_target_sp(target_sp) {} + : m_target_sp(target_sp) {} ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable( const lldb::ValueObjectSP &valobj_sp) { diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h index 1ea4125077fa..abeb431ccc08 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h @@ -31,17 +31,17 @@ class TypeSystemClang; /// A list of variables that can be accessed and updated by any expression. See /// ClangPersistentVariable for more discussion. Also provides an increasing, /// 0-based counter for naming result variables. -class ClangPersistentVariables : public PersistentExpressionState { +class ClangPersistentVariables + : public llvm::RTTIExtends<ClangPersistentVariables, + PersistentExpressionState> { public: + // LLVM RTTI support + static char ID; + ClangPersistentVariables(std::shared_ptr<Target> target_sp); ~ClangPersistentVariables() override = default; - // llvm casting support - static bool classof(const PersistentExpressionState *pv) { - return pv->getKind() == PersistentExpressionState::eKindClang; - } - std::shared_ptr<ClangASTImporter> GetClangASTImporter(); std::shared_ptr<ClangModulesDeclVendor> GetClangModulesDeclVendor(); 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 3399f423f8fc..74c1212791be 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -880,8 +880,7 @@ lldb::addr_t ClangUserExpression::GetCppObjectPointer( // We're inside a C++ class method. This could potentially be an unnamed // lambda structure. If the lambda captured a "this", that should be // the object pointer. - if (auto thisChildSP = - valobj_sp->GetChildMemberWithName(ConstString("this"), true)) { + if (auto thisChildSP = valobj_sp->GetChildMemberWithName("this")) { valobj_sp = thisChildSP; } @@ -981,6 +980,8 @@ lldb::ExpressionVariableSP ClangUserExpression::GetResultAfterDematerialization( return m_result_delegate.GetVariable(); } +char ClangUserExpression::ClangUserExpressionHelper::ID; + void ClangUserExpression::ClangUserExpressionHelper::ResetDeclMap( ExecutionContext &exe_ctx, Materializer::PersistentVariableDelegate &delegate, diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h index f05624c6119b..0fbeff7f6143 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h @@ -51,13 +51,16 @@ public: enum { kDefaultTimeout = 500000u }; - class ClangUserExpressionHelper : public ClangExpressionHelper { + class ClangUserExpressionHelper + : public llvm::RTTIExtends<ClangUserExpressionHelper, + ClangExpressionHelper> { public: + // LLVM RTTI support + static char ID; + ClangUserExpressionHelper(Target &target, bool top_level) : m_target(target), m_top_level(top_level) {} - ~ClangUserExpressionHelper() override = default; - /// Return the object that the parser should use when resolving external /// values. May be NULL if everything should be self-contained. ClangExpressionDeclMap *DeclMap() override { diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 66493aa3e592..371605d427ad 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -176,6 +176,8 @@ bool ClangUtilityFunction::Install(DiagnosticManager &diagnostic_manager, } } +char ClangUtilityFunction::ClangUtilityFunctionHelper::ID; + void ClangUtilityFunction::ClangUtilityFunctionHelper::ResetDeclMap( ExecutionContext &exe_ctx, bool keep_result_in_memory) { std::shared_ptr<ClangASTImporter> ast_importer; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h index b8a154b3baed..72ff84f3ceaf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h @@ -72,11 +72,12 @@ public: ExecutionContext &exe_ctx) override; private: - class ClangUtilityFunctionHelper : public ClangExpressionHelper { + class ClangUtilityFunctionHelper + : public llvm::RTTIExtends<ClangUtilityFunctionHelper, + ClangExpressionHelper> { public: - ClangUtilityFunctionHelper() = default; - - ~ClangUtilityFunctionHelper() override = default; + // LLVM RTTI support + static char ID; /// Return the object that the parser should use when resolving external /// values. May be NULL if everything should be self-contained. diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp index 055ad0711f90..847dab6592b8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.cpp @@ -10,7 +10,7 @@ #include "ClangHost.h" #include "lldb/Host/FileSystem.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include <optional> using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h index 3a87570bf804..7be0ce6c7ae5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CppModuleConfiguration.h @@ -9,7 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CPPMODULECONFIGURATION_H #define LLDB_SOURCE_PLUGINS_EXPRESSIONPARSER_CLANG_CPPMODULECONFIGURATION_H -#include <lldb/Core/FileSpecList.h> +#include <lldb/Utility/FileSpecList.h> #include <llvm/Support/Regex.h> namespace lldb_private { 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 3eda04dc022a..c201153fd7ce 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp @@ -239,7 +239,8 @@ std::optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) { LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}"); return std::nullopt; } - imported_args.push_back(TemplateArgument(*type)); + imported_args.push_back( + TemplateArgument(*type, /*isNullPtr*/ false, arg.getIsDefaulted())); break; } case TemplateArgument::Integral: { @@ -250,8 +251,8 @@ std::optional<Decl *> CxxModuleHandler::tryInstantiateStdTemplate(Decl *d) { LLDB_LOG_ERROR(log, type.takeError(), "Couldn't import type: {0}"); return std::nullopt; } - imported_args.push_back( - TemplateArgument(d->getASTContext(), integral, *type)); + imported_args.push_back(TemplateArgument(d->getASTContext(), integral, + *type, arg.getIsDefaulted())); break; } default: 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 0a4af196857c..cd7d1ff6148b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.cpp @@ -47,33 +47,30 @@ ClangDynamicCheckerFunctions::ClangDynamicCheckerFunctions() ClangDynamicCheckerFunctions::~ClangDynamicCheckerFunctions() = default; -bool ClangDynamicCheckerFunctions::Install( +llvm::Error ClangDynamicCheckerFunctions::Install( DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) { - auto utility_fn_or_error = exe_ctx.GetTargetRef().CreateUtilityFunction( - g_valid_pointer_check_text, VALID_POINTER_CHECK_NAME, - lldb::eLanguageTypeC, exe_ctx); - if (!utility_fn_or_error) { - llvm::consumeError(utility_fn_or_error.takeError()); - return false; - } - m_valid_pointer_check = std::move(*utility_fn_or_error); + Expected<std::unique_ptr<UtilityFunction>> utility_fn = + exe_ctx.GetTargetRef().CreateUtilityFunction( + g_valid_pointer_check_text, VALID_POINTER_CHECK_NAME, + lldb::eLanguageTypeC, exe_ctx); + if (!utility_fn) + return utility_fn.takeError(); + m_valid_pointer_check = std::move(*utility_fn); if (Process *process = exe_ctx.GetProcessPtr()) { ObjCLanguageRuntime *objc_language_runtime = ObjCLanguageRuntime::Get(*process); if (objc_language_runtime) { - auto utility_fn_or_error = objc_language_runtime->CreateObjectChecker( - VALID_OBJC_OBJECT_CHECK_NAME, exe_ctx); - if (!utility_fn_or_error) { - llvm::consumeError(utility_fn_or_error.takeError()); - return false; - } - m_objc_object_check = std::move(*utility_fn_or_error); + Expected<std::unique_ptr<UtilityFunction>> checker_fn = + objc_language_runtime->CreateObjectChecker(VALID_OBJC_OBJECT_CHECK_NAME, exe_ctx); + if (!checker_fn) + return checker_fn.takeError(); + m_objc_object_check = std::move(*checker_fn); } } - return true; + return Error::success(); } bool ClangDynamicCheckerFunctions::DoCheckersExplainStop(lldb::addr_t addr, @@ -334,20 +331,8 @@ protected: else return false; - // Insert an instruction to cast the loaded value to int8_t* - - BitCastInst *bit_cast = - new BitCastInst(dereferenced_ptr, GetI8PtrTy(), "", inst); - // Insert an instruction to call the helper with the result - - llvm::Value *arg_array[1]; - - arg_array[0] = bit_cast; - - llvm::ArrayRef<llvm::Value *> args(arg_array, 1); - - CallInst::Create(m_valid_pointer_check_func, args, "", inst); + CallInst::Create(m_valid_pointer_check_func, dereferenced_ptr, "", inst); return true; } @@ -425,16 +410,11 @@ protected: assert(target_object); assert(selector); - // Insert an instruction to cast the receiver id to int8_t* - - BitCastInst *bit_cast = - new BitCastInst(target_object, GetI8PtrTy(), "", inst); - // Insert an instruction to call the helper with the result llvm::Value *arg_array[2]; - arg_array[0] = bit_cast; + arg_array[0] = target_object; arg_array[1] = selector; ArrayRef<llvm::Value *> args(arg_array, 2); 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 4abd16c5c326..ff20c1f08be0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRDynamicChecks.h @@ -46,10 +46,10 @@ public: /// The execution context to install the functions into. /// /// \return - /// True on success; false on failure, or if the functions have - /// already been installed. - bool Install(DiagnosticManager &diagnostic_manager, - ExecutionContext &exe_ctx) override; + /// Either llvm::ErrorSuccess or Error with llvm::ErrorInfo + /// + llvm::Error Install(DiagnosticManager &diagnostic_manager, + ExecutionContext &exe_ctx) override; bool DoCheckersExplainStop(lldb::addr_t addr, Stream &message) override; 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 ec0243d92099..1b7e86bb187f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -476,8 +476,7 @@ bool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str, string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer()); Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty); - Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) - : Constant::getNullValue(i8_ptr_ty); + Constant *bytes_arg = cstr ? cstr : Constant::getNullValue(i8_ptr_ty); Constant *numBytes_arg = ConstantInt::get( m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false); int encoding_flags = 0; @@ -743,8 +742,8 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { // 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. + // @"\01L_OBJC_METH_VAR_NAME_". + // @"\01L_OBJC_METH_VAR_NAME_" contains the string. // Find the pointer's initializer and get the string from its target. @@ -821,17 +820,9 @@ bool IRForTarget::RewriteObjCSelector(Instruction *selector_load) { ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)}; } - Value *argument_array[1]; - - Constant *omvn_pointer = ConstantExpr::getBitCast( - _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext())); - - argument_array[0] = omvn_pointer; - - ArrayRef<Value *> srN_arguments(argument_array, 1); - - CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments, - "sel_registerName", selector_load); + CallInst *srN_call = + CallInst::Create(m_sel_registerName, _objc_meth_var_name_, + "sel_registerName", selector_load); // Replace the load with the call in all users @@ -868,156 +859,6 @@ bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) { return true; } -static bool IsObjCClassReference(Value *value) { - GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value); - - return !(!global_variable || !global_variable->hasName() || - !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_")); -} - -// This function does not report errors; its callers are responsible. -bool IRForTarget::RewriteObjCClassReference(Instruction *class_load) { - lldb_private::Log *log(GetLog(LLDBLog::Expressions)); - - LoadInst *load = dyn_cast<LoadInst>(class_load); - - if (!load) - return false; - - // Unpack the class name from the reference. In LLVM IR, a reference to an - // Objective-C class gets represented as - // - // %tmp = load %struct._objc_class*, - // %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4 - // - // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called - // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string. - - // Find the pointer's initializer (a ConstantExpr with opcode BitCast) and - // get the string from its target - - GlobalVariable *_objc_class_references_ = - dyn_cast<GlobalVariable>(load->getPointerOperand()); - - if (!_objc_class_references_ || - !_objc_class_references_->hasInitializer()) - return false; - - Constant *ocr_initializer = _objc_class_references_->getInitializer(); - - ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer); - - if (!ocr_initializer_expr || - ocr_initializer_expr->getOpcode() != Instruction::BitCast) - return false; - - Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0); - - if (!ocr_initializer_base) - return false; - - // Find the string's initializer (a ConstantArray) and get the string from it - - GlobalVariable *_objc_class_name_ = - dyn_cast<GlobalVariable>(ocr_initializer_base); - - if (!_objc_class_name_ || !_objc_class_name_->hasInitializer()) - return false; - - Constant *ocn_initializer = _objc_class_name_->getInitializer(); - - ConstantDataArray *ocn_initializer_array = - dyn_cast<ConstantDataArray>(ocn_initializer); - - if (!ocn_initializer_array->isString()) - return false; - - std::string ocn_initializer_string = - std::string(ocn_initializer_array->getAsString()); - - LLDB_LOG(log, "Found Objective-C class reference \"{0}\"", - ocn_initializer_string); - - // Construct a call to objc_getClass - - if (!m_objc_getClass) { - lldb::addr_t objc_getClass_addr; - - bool missing_weak = false; - static lldb_private::ConstString g_objc_getClass_str("objc_getClass"); - objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str, - missing_weak); - if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak) - return false; - - LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr); - - // Build the function type: %struct._objc_class *objc_getClass(i8*) - - Type *class_type = load->getType(); - Type *type_array[1]; - type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext()); - - ArrayRef<Type *> ogC_arg_types(type_array, 1); - - llvm::FunctionType *ogC_type = - FunctionType::get(class_type, ogC_arg_types, false); - - // Build the constant containing the pointer to the function - PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type); - Constant *ogC_addr_int = - ConstantInt::get(m_intptr_ty, objc_getClass_addr, false); - m_objc_getClass = {ogC_type, - ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)}; - } - - Value *argument_array[1]; - - Constant *ocn_pointer = ConstantExpr::getBitCast( - _objc_class_name_, Type::getInt8PtrTy(m_module->getContext())); - - argument_array[0] = ocn_pointer; - - ArrayRef<Value *> ogC_arguments(argument_array, 1); - - CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments, - "objc_getClass", class_load); - - // Replace the load with the call in all users - - class_load->replaceAllUsesWith(ogC_call); - - class_load->eraseFromParent(); - - return true; -} - -bool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) { - lldb_private::Log *log(GetLog(LLDBLog::Expressions)); - - InstrList class_loads; - - for (Instruction &inst : basic_block) { - if (LoadInst *load = dyn_cast<LoadInst>(&inst)) - if (IsObjCClassReference(load->getPointerOperand())) - class_loads.push_back(&inst); - } - - for (Instruction *inst : class_loads) { - if (!RewriteObjCClassReference(inst)) { - m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a " - "static reference to an Objective-C class to a " - "dynamic reference\n"); - - LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class"); - - return false; - } - } - - return true; -} - // This function does not report errors; its callers are responsible. bool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) { lldb_private::Log *log(GetLog(LLDBLog::Expressions)); @@ -1419,19 +1260,7 @@ bool IRForTarget::ResolveExternals(Function &llvm_function) { } static bool isGuardVariableRef(Value *V) { - Constant *Old = dyn_cast<Constant>(V); - - if (!Old) - return false; - - if (auto CE = dyn_cast<ConstantExpr>(V)) { - if (CE->getOpcode() != Instruction::BitCast) - return false; - - Old = CE->getOperand(0); - } - - GlobalVariable *GV = dyn_cast<GlobalVariable>(Old); + GlobalVariable *GV = dyn_cast<GlobalVariable>(V); if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName())) return false; @@ -1732,19 +1561,12 @@ bool IRForTarget::ReplaceVariables(Function &llvm_function) { 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(value->getType(), bit_cast, "", - entry_instruction); + LoadInst *load = new LoadInst(value->getType(), get_element_ptr, + "", entry_instruction); return load; } else { - BitCastInst *bit_cast = new BitCastInst( - get_element_ptr, value->getType(), "", entry_instruction); - - return bit_cast; + return get_element_ptr; } }); @@ -1903,14 +1725,6 @@ bool IRForTarget::runOnModule(Module &llvm_module) { return false; } - - if (!RewriteObjCClassReferences(bb)) { - LLDB_LOG(log, "RewriteObjCClassReferences() failed"); - - // RewriteObjCClasses() reports its own errors, so we don't do so here - - return false; - } } } diff --git a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h index 5f212fa8f918..eb93952e2b3c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h +++ b/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.h @@ -252,28 +252,6 @@ private: /// True on success; false otherwise bool RewriteObjCSelectors(llvm::BasicBlock &basic_block); - /// A basic block-level pass to find all Objective-C class references that - /// use the old-style Objective-C runtime and rewrite them to use - /// class_getClass instead of statically allocated class references. - - /// Replace a single old-style class reference - /// - /// \param[in] class_load - /// The load of the statically-allocated selector. - /// - /// \return - /// True on success; false otherwise - bool RewriteObjCClassReference(llvm::Instruction *class_load); - - /// The top-level pass implementation - /// - /// \param[in] basic_block - /// The basic block currently being processed. - /// - /// \return - /// True on success; false otherwise - bool RewriteObjCClassReferences(llvm::BasicBlock &basic_block); - /// A basic block-level pass to find all newly-declared persistent /// variables and register them with the ClangExprDeclMap. This allows them /// to be materialized and dematerialized like normal external variables. @@ -425,9 +403,6 @@ private: /// The address of the function sel_registerName, cast to the appropriate /// function pointer type. llvm::FunctionCallee m_sel_registerName; - /// The address of the function objc_getClass, cast to the appropriate - /// function pointer type. - llvm::FunctionCallee m_objc_getClass; /// The type of an integer large enough to hold a pointer. llvm::IntegerType *m_intptr_ty = nullptr; /// The stream on which errors should be printed. 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 5ab256a62e07..ff5c79aa2455 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -18,7 +18,6 @@ #include "lldb/Interpreter/OptionValueDictionary.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Stream.h" #include "Plugins/Process/Utility/ARMDefines.h" @@ -605,7 +604,7 @@ static std::optional<RegisterInfo> GetARMDWARFRegisterInfo(unsigned reg_num) { // Valid return values are {1, 2, 3, 4}, with 0 signifying an error condition. static uint32_t CountITSize(uint32_t ITMask) { // First count the trailing zeros of the IT mask. - uint32_t TZ = llvm::countTrailingZeros(ITMask); + uint32_t TZ = llvm::countr_zero(ITMask); if (TZ > 3) { return 0; } @@ -13750,13 +13749,13 @@ bool EmulateInstructionARM::SetArchitecture(const ArchSpec &arch) { m_arm_isa = ARMvAll; else if (arch_cstr.equals_insensitive("thumb")) m_arm_isa = ARMvAll; - else if (arch_cstr.startswith_insensitive("armv4")) + else if (arch_cstr.starts_with_insensitive("armv4")) m_arm_isa = ARMv4; - else if (arch_cstr.startswith_insensitive("armv6")) + else if (arch_cstr.starts_with_insensitive("armv6")) m_arm_isa = ARMv6; - else if (arch_cstr.startswith_insensitive("armv7")) + else if (arch_cstr.starts_with_insensitive("armv7")) m_arm_isa = ARMv7; - else if (arch_cstr.startswith_insensitive("armv8")) + else if (arch_cstr.starts_with_insensitive("armv8")) m_arm_isa = ARMv8; return m_arm_isa != 0; } @@ -14346,26 +14345,26 @@ EmulateInstructionARM::GetInstructionCondition() { return cond; } -bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, +bool EmulateInstructionARM::TestEmulation(Stream &out_stream, ArchSpec &arch, OptionValueDictionary *test_data) { if (!test_data) { - out_stream->Printf("TestEmulation: Missing test data.\n"); + out_stream.Printf("TestEmulation: Missing test data.\n"); return false; } - static ConstString opcode_key("opcode"); - static ConstString before_key("before_state"); - static ConstString after_key("after_state"); + static constexpr llvm::StringLiteral opcode_key("opcode"); + static constexpr llvm::StringLiteral before_key("before_state"); + static constexpr llvm::StringLiteral after_key("after_state"); OptionValueSP value_sp = test_data->GetValueForKey(opcode_key); uint32_t test_opcode; if ((value_sp.get() == nullptr) || (value_sp->GetType() != OptionValue::eTypeUInt64)) { - out_stream->Printf("TestEmulation: Error reading opcode from test file.\n"); + out_stream.Printf("TestEmulation: Error reading opcode from test file.\n"); return false; } - test_opcode = value_sp->GetUInt64Value(); + test_opcode = value_sp->GetValueAs<uint64_t>().value_or(0); if (arch.GetTriple().getArch() == llvm::Triple::thumb || arch.IsAlwaysThumbInstructions()) { @@ -14378,7 +14377,7 @@ bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, m_opcode_mode = eModeARM; m_opcode.SetOpcode32(test_opcode, endian::InlHostByteOrder()); } else { - out_stream->Printf("TestEmulation: Invalid arch.\n"); + out_stream.Printf("TestEmulation: Invalid arch.\n"); return false; } @@ -14388,26 +14387,26 @@ bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, value_sp = test_data->GetValueForKey(before_key); if ((value_sp.get() == nullptr) || (value_sp->GetType() != OptionValue::eTypeDictionary)) { - out_stream->Printf("TestEmulation: Failed to find 'before' state.\n"); + out_stream.Printf("TestEmulation: Failed to find 'before' state.\n"); return false; } OptionValueDictionary *state_dictionary = value_sp->GetAsDictionary(); if (!before_state.LoadStateFromDictionary(state_dictionary)) { - out_stream->Printf("TestEmulation: Failed loading 'before' state.\n"); + out_stream.Printf("TestEmulation: Failed loading 'before' state.\n"); return false; } value_sp = test_data->GetValueForKey(after_key); if ((value_sp.get() == nullptr) || (value_sp->GetType() != OptionValue::eTypeDictionary)) { - out_stream->Printf("TestEmulation: Failed to find 'after' state.\n"); + out_stream.Printf("TestEmulation: Failed to find 'after' state.\n"); return false; } state_dictionary = value_sp->GetAsDictionary(); if (!after_state.LoadStateFromDictionary(state_dictionary)) { - out_stream->Printf("TestEmulation: Failed loading 'after' state.\n"); + out_stream.Printf("TestEmulation: Failed loading 'after' state.\n"); return false; } @@ -14419,14 +14418,14 @@ bool EmulateInstructionARM::TestEmulation(Stream *out_stream, ArchSpec &arch, bool success = EvaluateInstruction(eEmulateInstructionOptionAutoAdvancePC); if (!success) { - out_stream->Printf("TestEmulation: EvaluateInstruction() failed.\n"); + out_stream.Printf("TestEmulation: EvaluateInstruction() failed.\n"); return false; } success = before_state.CompareState(after_state, out_stream); if (!success) - out_stream->Printf( - "TestEmulation: State after emulation does not match 'after' state.\n"); + out_stream.Printf("TestEmulation: State after emulation does not match " + "'after' state.\n"); return success; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h index 7b8849ede9c7..9eca0288607c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.h @@ -11,7 +11,6 @@ #include "Plugins/Process/Utility/ARMDefines.h" #include "lldb/Core/EmulateInstruction.h" -#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" #include <optional> @@ -133,7 +132,7 @@ public: InstructionCondition GetInstructionCondition() override; - bool TestEmulation(Stream *out_stream, ArchSpec &arch, + bool TestEmulation(Stream &out_stream, ArchSpec &arch, OptionValueDictionary *test_data) override; std::optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind, diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp index 1bb96fc8a2f7..75dcb6ee6dcf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp @@ -118,7 +118,7 @@ size_t EmulationStateARM::ReadPseudoMemory( return 0; if (endian::InlHostByteOrder() == lldb::eByteOrderBig) - value = llvm::ByteSwap_32(value); + value = llvm::byteswap<uint32_t>(value); *((uint32_t *)dst) = value; } else if (length == 8) { uint32_t value1 = pseudo_state->ReadFromPseudoAddress(addr, success); @@ -130,8 +130,8 @@ size_t EmulationStateARM::ReadPseudoMemory( return 0; if (endian::InlHostByteOrder() == lldb::eByteOrderBig) { - value1 = llvm::ByteSwap_32(value1); - value2 = llvm::ByteSwap_32(value2); + value1 = llvm::byteswap<uint32_t>(value1); + value2 = llvm::byteswap<uint32_t>(value2); } ((uint32_t *)dst)[0] = value1; ((uint32_t *)dst)[1] = value2; @@ -157,7 +157,7 @@ size_t EmulationStateARM::WritePseudoMemory( uint32_t value; memcpy (&value, dst, sizeof (uint32_t)); if (endian::InlHostByteOrder() == lldb::eByteOrderBig) - value = llvm::ByteSwap_32(value); + value = llvm::byteswap<uint32_t>(value); pseudo_state->StoreToPseudoAddress(addr, value); return length; @@ -168,8 +168,8 @@ size_t EmulationStateARM::WritePseudoMemory( memcpy(&value2, static_cast<const uint8_t *>(dst) + sizeof(uint32_t), sizeof(uint32_t)); if (endian::InlHostByteOrder() == lldb::eByteOrderBig) { - value1 = llvm::ByteSwap_32(value1); - value2 = llvm::ByteSwap_32(value2); + value1 = llvm::byteswap<uint32_t>(value1); + value2 = llvm::byteswap<uint32_t>(value2); } pseudo_state->StoreToPseudoAddress(addr, value1); @@ -215,44 +215,43 @@ bool EmulationStateARM::WritePseudoRegister( } bool EmulationStateARM::CompareState(EmulationStateARM &other_state, - Stream *out_stream) { + Stream &out_stream) { bool match = true; for (int i = 0; match && i < 17; ++i) { if (m_gpr[i] != other_state.m_gpr[i]) { match = false; - out_stream->Printf("r%d: 0x%x != 0x%x\n", i, m_gpr[i], - other_state.m_gpr[i]); + out_stream.Printf("r%d: 0x%x != 0x%x\n", i, m_gpr[i], + other_state.m_gpr[i]); } } for (int i = 0; match && i < 32; ++i) { if (m_vfp_regs.s_regs[i] != other_state.m_vfp_regs.s_regs[i]) { match = false; - out_stream->Printf("s%d: 0x%x != 0x%x\n", i, m_vfp_regs.s_regs[i], - other_state.m_vfp_regs.s_regs[i]); + out_stream.Printf("s%d: 0x%x != 0x%x\n", i, m_vfp_regs.s_regs[i], + other_state.m_vfp_regs.s_regs[i]); } } for (int i = 0; match && i < 16; ++i) { if (m_vfp_regs.d_regs[i] != other_state.m_vfp_regs.d_regs[i]) { match = false; - out_stream->Printf("d%d: 0x%" PRIx64 " != 0x%" PRIx64 "\n", i + 16, - m_vfp_regs.d_regs[i], - other_state.m_vfp_regs.d_regs[i]); + out_stream.Printf("d%d: 0x%" PRIx64 " != 0x%" PRIx64 "\n", i + 16, + m_vfp_regs.d_regs[i], other_state.m_vfp_regs.d_regs[i]); } } // other_state is the expected state. If it has memory, check it. if (!other_state.m_memory.empty() && m_memory != other_state.m_memory) { match = false; - out_stream->Printf("memory does not match\n"); - out_stream->Printf("got memory:\n"); + out_stream.Printf("memory does not match\n"); + out_stream.Printf("got memory:\n"); for (auto p : m_memory) - out_stream->Printf("0x%08" PRIx64 ": 0x%08x\n", p.first, p.second); - out_stream->Printf("expected memory:\n"); + out_stream.Printf("0x%08" PRIx64 ": 0x%08x\n", p.first, p.second); + out_stream.Printf("expected memory:\n"); for (auto p : other_state.m_memory) - out_stream->Printf("0x%08" PRIx64 ": 0x%08x\n", p.first, p.second); + out_stream.Printf("0x%08" PRIx64 ": 0x%08x\n", p.first, p.second); } return match; @@ -264,11 +263,10 @@ bool EmulationStateARM::LoadRegistersStateFromDictionary( for (int i = 0; i < num; ++i) { sstr.Clear(); sstr.Printf("%c%d", kind, i); - OptionValueSP value_sp = - reg_dict->GetValueForKey(ConstString(sstr.GetString())); + OptionValueSP value_sp = reg_dict->GetValueForKey(sstr.GetString()); if (value_sp.get() == nullptr) return false; - uint64_t reg_value = value_sp->GetUInt64Value(); + uint64_t reg_value = value_sp->GetValueAs<uint64_t>().value_or(0); StorePseudoRegisterValue(first_reg + i, reg_value); } @@ -277,8 +275,8 @@ bool EmulationStateARM::LoadRegistersStateFromDictionary( bool EmulationStateARM::LoadStateFromDictionary( OptionValueDictionary *test_data) { - static ConstString memory_key("memory"); - static ConstString registers_key("registers"); + static constexpr llvm::StringLiteral memory_key("memory"); + static constexpr llvm::StringLiteral registers_key("registers"); if (!test_data) return false; @@ -288,8 +286,8 @@ bool EmulationStateARM::LoadStateFromDictionary( // Load memory, if present. if (value_sp.get() != nullptr) { - static ConstString address_key("address"); - static ConstString data_key("data"); + static constexpr llvm::StringLiteral address_key("address"); + static constexpr llvm::StringLiteral data_key("data"); uint64_t start_address = 0; OptionValueDictionary *mem_dict = value_sp->GetAsDictionary(); @@ -297,7 +295,7 @@ bool EmulationStateARM::LoadStateFromDictionary( if (value_sp.get() == nullptr) return false; else - start_address = value_sp->GetUInt64Value(); + start_address = value_sp->GetValueAs<uint64_t>().value_or(0); value_sp = mem_dict->GetValueForKey(data_key); OptionValueArray *mem_array = value_sp->GetAsArray(); @@ -311,7 +309,7 @@ bool EmulationStateARM::LoadStateFromDictionary( value_sp = mem_array->GetValueAtIndex(i); if (value_sp.get() == nullptr) return false; - uint64_t value = value_sp->GetUInt64Value(); + uint64_t value = value_sp->GetValueAs<uint64_t>().value_or(0); StoreToPseudoAddress(address, value); address = address + 4; } @@ -327,11 +325,12 @@ bool EmulationStateARM::LoadStateFromDictionary( if (!LoadRegistersStateFromDictionary(reg_dict, 'r', dwarf_r0, 16)) return false; - static ConstString cpsr_name("cpsr"); + static constexpr llvm::StringLiteral cpsr_name("cpsr"); value_sp = reg_dict->GetValueForKey(cpsr_name); if (value_sp.get() == nullptr) return false; - StorePseudoRegisterValue(dwarf_cpsr, value_sp->GetUInt64Value()); + StorePseudoRegisterValue(dwarf_cpsr, + value_sp->GetValueAs<uint64_t>().value_or(0)); // Load s/d Registers // To prevent you giving both types in a state and overwriting diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h index bf322f5b1a91..6cf842aec18d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.h @@ -35,7 +35,7 @@ public: bool LoadStateFromDictionary(lldb_private::OptionValueDictionary *test_data); bool CompareState(EmulationStateARM &other_state, - lldb_private::Stream *out_stream); + lldb_private::Stream &out_stream); static size_t ReadPseudoMemory(lldb_private::EmulateInstruction *instruction, void *baton, diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp index 0861d24dcc79..6ca4fb052457 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp @@ -12,7 +12,6 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/ConstString.h" #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Stream.h" @@ -22,6 +21,7 @@ #include "Plugins/Process/Utility/ARMUtils.h" #include "Plugins/Process/Utility/lldb-arm64-register-enums.h" +#include <algorithm> #include <cstdlib> #include <optional> @@ -36,7 +36,7 @@ "na", nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, \ - nullptr, nullptr + nullptr, nullptr, nullptr #define DECLARE_REGISTER_INFOS_ARM64_STRUCT @@ -804,7 +804,7 @@ bool EmulateInstructionARM64::EmulateLDPSTP(const uint32_t opcode) { Context context_t; Context context_t2; - uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer buffer; Status error; switch (memop) { @@ -827,23 +827,27 @@ bool EmulateInstructionARM64::EmulateLDPSTP(const uint32_t opcode) { if (!data_Rt) return false; - if (data_Rt->GetAsMemoryData(*reg_info_Rt, buffer, reg_info_Rt->byte_size, - eByteOrderLittle, error) == 0) + buffer.resize(reg_info_Rt->byte_size); + if (data_Rt->GetAsMemoryData(*reg_info_Rt, buffer.data(), + reg_info_Rt->byte_size, eByteOrderLittle, + error) == 0) return false; - if (!WriteMemory(context_t, address + 0, buffer, reg_info_Rt->byte_size)) + if (!WriteMemory(context_t, address + 0, buffer.data(), + reg_info_Rt->byte_size)) return false; std::optional<RegisterValue> data_Rt2 = ReadRegister(*reg_info_Rt2); if (!data_Rt2) return false; - if (data_Rt2->GetAsMemoryData(*reg_info_Rt2, buffer, + buffer.resize(reg_info_Rt2->byte_size); + if (data_Rt2->GetAsMemoryData(*reg_info_Rt2, buffer.data(), reg_info_Rt2->byte_size, eByteOrderLittle, error) == 0) return false; - if (!WriteMemory(context_t2, address + size, buffer, + if (!WriteMemory(context_t2, address + size, buffer.data(), reg_info_Rt2->byte_size)) return false; } break; @@ -862,16 +866,19 @@ bool EmulateInstructionARM64::EmulateLDPSTP(const uint32_t opcode) { context_t.SetAddress(address); context_t2.SetAddress(address + size); + buffer.resize(reg_info_Rt->byte_size); if (rt_unknown) - memset(buffer, 'U', reg_info_Rt->byte_size); + std::fill(buffer.begin(), buffer.end(), 'U'); else { - if (!ReadMemory(context_t, address, buffer, reg_info_Rt->byte_size)) + if (!ReadMemory(context_t, address, buffer.data(), + reg_info_Rt->byte_size)) return false; } RegisterValue data_Rt; - if (data_Rt.SetFromMemoryData(*reg_info_Rt, buffer, reg_info_Rt->byte_size, - eByteOrderLittle, error) == 0) + if (data_Rt.SetFromMemoryData(*reg_info_Rt, buffer.data(), + reg_info_Rt->byte_size, eByteOrderLittle, + error) == 0) return false; if (!vector && is_signed && !data_Rt.SignExtend(datasize)) @@ -880,14 +887,14 @@ bool EmulateInstructionARM64::EmulateLDPSTP(const uint32_t opcode) { if (!WriteRegister(context_t, *reg_info_Rt, data_Rt)) return false; - if (!rt_unknown) { - if (!ReadMemory(context_t2, address + size, buffer, + buffer.resize(reg_info_Rt2->byte_size); + if (!rt_unknown) + if (!ReadMemory(context_t2, address + size, buffer.data(), reg_info_Rt2->byte_size)) return false; - } RegisterValue data_Rt2; - if (data_Rt2.SetFromMemoryData(*reg_info_Rt2, buffer, + if (data_Rt2.SetFromMemoryData(*reg_info_Rt2, buffer.data(), reg_info_Rt2->byte_size, eByteOrderLittle, error) == 0) return false; @@ -959,7 +966,7 @@ bool EmulateInstructionARM64::EmulateLDRSTRImm(const uint32_t opcode) { Status error; bool success = false; uint64_t address; - uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer buffer; if (n == 31) address = @@ -1000,11 +1007,13 @@ bool EmulateInstructionARM64::EmulateLDRSTRImm(const uint32_t opcode) { if (!data_Rt) return false; - if (data_Rt->GetAsMemoryData(*reg_info_Rt, buffer, reg_info_Rt->byte_size, - eByteOrderLittle, error) == 0) + buffer.resize(reg_info_Rt->byte_size); + if (data_Rt->GetAsMemoryData(*reg_info_Rt, buffer.data(), + reg_info_Rt->byte_size, eByteOrderLittle, + error) == 0) return false; - if (!WriteMemory(context, address, buffer, reg_info_Rt->byte_size)) + if (!WriteMemory(context, address, buffer.data(), reg_info_Rt->byte_size)) return false; } break; @@ -1017,12 +1026,14 @@ bool EmulateInstructionARM64::EmulateLDRSTRImm(const uint32_t opcode) { context.type = eContextRegisterLoad; context.SetAddress(address); - if (!ReadMemory(context, address, buffer, reg_info_Rt->byte_size)) + buffer.resize(reg_info_Rt->byte_size); + if (!ReadMemory(context, address, buffer.data(), reg_info_Rt->byte_size)) return false; RegisterValue data_Rt; - if (data_Rt.SetFromMemoryData(*reg_info_Rt, buffer, reg_info_Rt->byte_size, - eByteOrderLittle, error) == 0) + if (data_Rt.SetFromMemoryData(*reg_info_Rt, buffer.data(), + reg_info_Rt->byte_size, eByteOrderLittle, + error) == 0) return false; if (!WriteRegister(context, *reg_info_Rt, data_Rt)) diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h index b4b107fc267b..749fc633ea8d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h @@ -60,7 +60,7 @@ public: bool EvaluateInstruction(uint32_t evaluate_options) override; - bool TestEmulation(lldb_private::Stream *out_stream, + bool TestEmulation(lldb_private::Stream &out_stream, lldb_private::ArchSpec &arch, lldb_private::OptionValueDictionary *test_data) override { return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp index adfd57dff07c..37f08592d62b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp @@ -187,7 +187,7 @@ bool EmulateInstructionLoongArch::SetTargetTriple(const ArchSpec &arch) { } bool EmulateInstructionLoongArch::TestEmulation( - Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) { + Stream &out_stream, ArchSpec &arch, OptionValueDictionary *test_data) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h index e03356244b47..47fe454fcd88 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h @@ -52,7 +52,7 @@ public: bool SetTargetTriple(const ArchSpec &arch) override; bool ReadInstruction() override; bool EvaluateInstruction(uint32_t options) override; - bool TestEmulation(Stream *out_stream, ArchSpec &arch, + bool TestEmulation(Stream &out_stream, ArchSpec &arch, OptionValueDictionary *test_data) override; std::optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind, 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 1be41e4a316b..76d7a8272f3f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -1263,19 +1263,19 @@ bool EmulateInstructionMIPS::Emulate_SW(llvm::MCInst &insn) { context.type = eContextPushRegisterOnStack; context.SetRegisterToRegisterPlusOffset(*reg_info_src, *reg_info_base, 0); - uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer buffer(reg_info_src->byte_size); Status error; std::optional<RegisterValue> data_src = ReadRegister(*reg_info_base); if (!data_src) return false; - if (data_src->GetAsMemoryData(*reg_info_src, buffer, + if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(), reg_info_src->byte_size, eByteOrderLittle, error) == 0) return false; - if (!WriteMemory(context, address, buffer, reg_info_src->byte_size)) + if (!WriteMemory(context, address, buffer.data(), reg_info_src->byte_size)) return false; return true; @@ -1523,18 +1523,19 @@ bool EmulateInstructionMIPS::Emulate_SWSP(llvm::MCInst &insn) { context.type = eContextPushRegisterOnStack; context.SetRegisterToRegisterPlusOffset(reg_info_src, *reg_info_base, 0); - uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer buffer(reg_info_src.byte_size); Status error; std::optional<RegisterValue> data_src = ReadRegister(*reg_info_base); if (!data_src) return false; - if (data_src->GetAsMemoryData(reg_info_src, buffer, reg_info_src.byte_size, - eByteOrderLittle, error) == 0) + if (data_src->GetAsMemoryData(reg_info_src, buffer.data(), + reg_info_src.byte_size, eByteOrderLittle, + error) == 0) return false; - if (!WriteMemory(context, address, buffer, reg_info_src.byte_size)) + if (!WriteMemory(context, address, buffer.data(), reg_info_src.byte_size)) return false; return true; @@ -1605,19 +1606,20 @@ bool EmulateInstructionMIPS::Emulate_SWM16_32(llvm::MCInst &insn) { context.type = eContextPushRegisterOnStack; context.SetRegisterToRegisterPlusOffset(*reg_info_src, *reg_info_base, 0); - uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer buffer(reg_info_src->byte_size); Status error; std::optional<RegisterValue> data_src = ReadRegister(*reg_info_base); if (!data_src) return false; - if (data_src->GetAsMemoryData(*reg_info_src, buffer, + if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(), reg_info_src->byte_size, eByteOrderLittle, error) == 0) return false; - if (!WriteMemory(context, base_address, buffer, reg_info_src->byte_size)) + if (!WriteMemory(context, base_address, buffer.data(), + reg_info_src->byte_size)) return false; // Stack address for next register 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 ab30be6a8f0d..01692c65ae30 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.h @@ -75,7 +75,7 @@ public: const lldb_private::Address &inst_addr, lldb_private::Target *target) override; - bool TestEmulation(lldb_private::Stream *out_stream, + bool TestEmulation(lldb_private::Stream &out_stream, lldb_private::ArchSpec &arch, lldb_private::OptionValueDictionary *test_data) override { return false; 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 c472f90ea3ba..e33ca95b523b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -1157,19 +1157,18 @@ bool EmulateInstructionMIPS64::Emulate_SD(llvm::MCInst &insn) { context.type = eContextPushRegisterOnStack; context.SetRegisterToRegisterPlusOffset(*reg_info_src, *reg_info_base, 0); - uint8_t buffer[RegisterValue::kMaxRegisterByteSize]; - Status error; - std::optional<RegisterValue> data_src = ReadRegister(*reg_info_base); if (!data_src) return false; - if (data_src->GetAsMemoryData(*reg_info_src, buffer, + Status error; + RegisterValue::BytesContainer buffer(reg_info_src->byte_size); + if (data_src->GetAsMemoryData(*reg_info_src, buffer.data(), reg_info_src->byte_size, eByteOrderLittle, error) == 0) return false; - if (!WriteMemory(context, address, buffer, reg_info_src->byte_size)) + if (!WriteMemory(context, address, buffer.data(), reg_info_src->byte_size)) return false; } 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 e94269e52f83..6becdf5e3c44 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h @@ -67,7 +67,7 @@ public: bool EvaluateInstruction(uint32_t evaluate_options) override; - bool TestEmulation(lldb_private::Stream *out_stream, + bool TestEmulation(lldb_private::Stream &out_stream, lldb_private::ArchSpec &arch, lldb_private::OptionValueDictionary *test_data) override { return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h index 7b63819e5131..a9424f16b0ad 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h @@ -57,7 +57,7 @@ public: bool EvaluateInstruction(uint32_t evaluate_options) override; - bool TestEmulation(Stream *out_stream, ArchSpec &arch, + bool TestEmulation(Stream &out_stream, ArchSpec &arch, OptionValueDictionary *test_data) override { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp b/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp index 06772aaa6e17..6c46618b337c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.cpp @@ -636,7 +636,7 @@ std::optional<DecodeResult> EmulateInstructionRISCV::Decode(uint32_t inst) { if ((inst & pat.type_mask) == pat.eigen && (inst_type & pat.inst_type) != 0) { LLDB_LOGF( - log, "EmulateInstructionRISCV::%s: inst(%x at %lx) was decoded to %s", + log, "EmulateInstructionRISCV::%s: inst(%x at %" PRIx64 ") was decoded to %s", __FUNCTION__, inst, m_addr, pat.name); auto decoded = is_rvc ? pat.decode(try_rvc) : pat.decode(inst); return DecodeResult{decoded, inst, is_rvc, pat}; @@ -1748,7 +1748,7 @@ bool EmulateInstructionRISCV::SetTargetTriple(const ArchSpec &arch) { return SupportsThisArch(arch); } -bool EmulateInstructionRISCV::TestEmulation(Stream *out_stream, ArchSpec &arch, +bool EmulateInstructionRISCV::TestEmulation(Stream &out_stream, ArchSpec &arch, OptionValueDictionary *test_data) { return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.h b/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.h index c3997b89466b..8bca73a7f589 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.h +++ b/contrib/llvm-project/lldb/source/Plugins/Instruction/RISCV/EmulateInstructionRISCV.h @@ -61,7 +61,7 @@ public: bool SetTargetTriple(const ArchSpec &arch) override; bool ReadInstruction() override; bool EvaluateInstruction(uint32_t options) override; - bool TestEmulation(Stream *out_stream, ArchSpec &arch, + bool TestEmulation(Stream &out_stream, ArchSpec &arch, OptionValueDictionary *test_data) override; std::optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) override; 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 72dfbd586622..44070b422220 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/ASan/InstrumentationRuntimeASan.cpp @@ -113,7 +113,8 @@ StructuredData::ObjectSP InstrumentationRuntimeASan::RetrieveReportData() { ThreadSP thread_sp = process_sp->GetThreadList().GetExpressionExecutionThread(); - StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + StackFrameSP frame_sp = + thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); if (!frame_sp) return StructuredData::ObjectSP(); diff --git a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp index e22cc86116ce..b7cd2b1ac6bf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/MainThreadChecker/InstrumentationRuntimeMainThreadChecker.cpp @@ -81,7 +81,8 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData( return StructuredData::ObjectSP(); ThreadSP thread_sp = exe_ctx_ref.GetThreadSP(); - StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + StackFrameSP frame_sp = + thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); ModuleSP runtime_module_sp = GetRuntimeModuleSP(); Target &target = process_sp->GetTarget(); @@ -131,7 +132,7 @@ InstrumentationRuntimeMainThreadChecker::RetrieveReportData( responsible_frame = frame; lldb::addr_t PC = addr.GetLoadAddress(&target); - trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC))); + trace->AddIntegerItem(PC); } auto *d = new StructuredData::Dictionary(); @@ -251,7 +252,7 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo( std::vector<lldb::addr_t> PCs; auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray(); trace->ForEach([&PCs](StructuredData::Object *PC) -> bool { - PCs.push_back(PC->GetAsInteger()->GetValue()); + PCs.push_back(PC->GetUnsignedIntegerValue()); return true; }); @@ -260,7 +261,7 @@ InstrumentationRuntimeMainThreadChecker::GetBacktracesFromExtendedStopInfo( StructuredData::ObjectSP thread_id_obj = info->GetObjectForDotSeparatedPath("tid"); - tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0; + tid_t tid = thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0; // We gather symbolication addresses above, so no need for HistoryThread to // try to infer the call addresses. 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 425b0baa453f..8a5db3335266 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/TSan/InstrumentationRuntimeTSan.cpp @@ -87,11 +87,14 @@ extern "C" void *dlsym(void* handle, const char* symbol); int (*ptr__tsan_get_report_loc_object_type)(void *report, unsigned long idx, const char **object_type); } +)"; + +const char *thread_sanitizer_retrieve_report_data_command = R"( const int REPORT_TRACE_SIZE = 128; const int REPORT_ARRAY_SIZE = 4; -struct data { +struct { void *report; const char *description; int report_count; @@ -154,11 +157,7 @@ struct data { int idx; int tid; } unique_tids[REPORT_ARRAY_SIZE]; -}; -)"; - -const char *thread_sanitizer_retrieve_report_data_command = R"( -data t = {0}; +} t = {0}; ptr__tsan_get_report_loc_object_type = (typeof(ptr__tsan_get_report_loc_object_type))(void *)dlsym((void*)-2 /*RTLD_DEFAULT*/, "__tsan_get_report_loc_object_type"); @@ -215,10 +214,10 @@ CreateStackTrace(ValueObjectSP o, size_t count = trace_value_object->GetNumChildren(); for (size_t j = 0; j < count; j++) { addr_t trace_addr = - trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0); + trace_value_object->GetChildAtIndex(j)->GetValueAsUnsigned(0); if (trace_addr == 0) break; - trace_sp->AddItem(std::make_shared<StructuredData::Integer>(trace_addr)); + trace_sp->AddIntegerItem(trace_addr); } return trace_sp; } @@ -236,7 +235,7 @@ static StructuredData::ArraySP ConvertToStructuredArray( ValueObjectSP objects = return_value_sp->GetValueForExpressionPath(items_name.c_str()); for (unsigned int i = 0; i < count; i++) { - ValueObjectSP o = objects->GetChildAtIndex(i, true); + ValueObjectSP o = objects->GetChildAtIndex(i); auto dict_sp = std::make_shared<StructuredData::Dictionary>(); callback(o, dict_sp); @@ -304,7 +303,8 @@ StructuredData::ObjectSP InstrumentationRuntimeTSan::RetrieveReportData( return StructuredData::ObjectSP(); ThreadSP thread_sp = exe_ctx_ref.GetThreadSP(); - StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + StackFrameSP frame_sp = + thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); if (!frame_sp) return StructuredData::ObjectSP(); @@ -668,13 +668,11 @@ InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) { } addr_t addr = loc->GetAsDictionary() ->GetValueForKey("address") - ->GetAsInteger() - ->GetValue(); + ->GetUnsignedIntegerValue(); if (addr == 0) addr = loc->GetAsDictionary() ->GetValueForKey("start") - ->GetAsInteger() - ->GetValue(); + ->GetUnsignedIntegerValue(); if (addr != 0) { std::string global_name = GetSymbolNameFromAddress(process_sp, addr); @@ -686,8 +684,7 @@ InstrumentationRuntimeTSan::GenerateSummary(StructuredData::ObjectSP report) { } else { int fd = loc->GetAsDictionary() ->GetValueForKey("file_descriptor") - ->GetAsInteger() - ->GetValue(); + ->GetSignedIntegerValue(); if (fd != 0) { summary = summary + " on file descriptor " + Sprintf("%d", fd); } @@ -703,8 +700,8 @@ addr_t InstrumentationRuntimeTSan::GetMainRacyAddress( report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach( [&result](StructuredData::Object *o) -> bool { - addr_t addr = - o->GetObjectForDotSeparatedPath("address")->GetIntegerValue(); + addr_t addr = o->GetObjectForDotSeparatedPath("address") + ->GetUnsignedIntegerValue(); if (addr < result) result = addr; return true; @@ -733,8 +730,8 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription( if (type == "global") { global_addr = loc->GetAsDictionary() ->GetValueForKey("address") - ->GetAsInteger() - ->GetValue(); + ->GetUnsignedIntegerValue(); + global_name = GetSymbolNameFromAddress(process_sp, global_addr); if (!global_name.empty()) { result = Sprintf("'%s' is a global variable (0x%llx)", @@ -752,12 +749,12 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription( } else if (type == "heap") { addr_t addr = loc->GetAsDictionary() ->GetValueForKey("start") - ->GetAsInteger() - ->GetValue(); - long size = loc->GetAsDictionary() - ->GetValueForKey("size") - ->GetAsInteger() - ->GetValue(); + ->GetUnsignedIntegerValue(); + + size_t size = loc->GetAsDictionary() + ->GetValueForKey("size") + ->GetUnsignedIntegerValue(); + std::string object_type = std::string(loc->GetAsDictionary() ->GetValueForKey("object_type") ->GetAsString() @@ -770,22 +767,22 @@ std::string InstrumentationRuntimeTSan::GetLocationDescription( Sprintf("Location is a %ld-byte heap object at 0x%llx", size, addr); } } else if (type == "stack") { - int tid = loc->GetAsDictionary() - ->GetValueForKey("thread_id") - ->GetAsInteger() - ->GetValue(); + tid_t tid = loc->GetAsDictionary() + ->GetValueForKey("thread_id") + ->GetUnsignedIntegerValue(); + result = Sprintf("Location is stack of thread %d", tid); } else if (type == "tls") { - int tid = loc->GetAsDictionary() - ->GetValueForKey("thread_id") - ->GetAsInteger() - ->GetValue(); + tid_t tid = loc->GetAsDictionary() + ->GetValueForKey("thread_id") + ->GetUnsignedIntegerValue(); + result = Sprintf("Location is TLS of thread %d", tid); } else if (type == "fd") { int fd = loc->GetAsDictionary() ->GetValueForKey("file_descriptor") - ->GetAsInteger() - ->GetValue(); + ->GetSignedIntegerValue(); + result = Sprintf("Location is file descriptor %d", fd); } } @@ -848,8 +845,8 @@ bool InstrumentationRuntimeTSan::NotifyBreakpointHit( report->GetObjectForDotSeparatedPath("mops")->GetAsArray()->ForEach( [&all_addresses_are_same, main_address](StructuredData::Object *o) -> bool { - addr_t addr = - o->GetObjectForDotSeparatedPath("address")->GetIntegerValue(); + addr_t addr = o->GetObjectForDotSeparatedPath("address") + ->GetUnsignedIntegerValue(); if (main_address != addr) all_addresses_are_same = false; return true; @@ -946,14 +943,16 @@ static std::string GenerateThreadName(const std::string &path, std::string result = "additional information"; if (path == "mops") { - int size = o->GetObjectForDotSeparatedPath("size")->GetIntegerValue(); - int thread_id = - o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue(); + size_t size = + o->GetObjectForDotSeparatedPath("size")->GetUnsignedIntegerValue(); + tid_t thread_id = + o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue(); bool is_write = o->GetObjectForDotSeparatedPath("is_write")->GetBooleanValue(); bool is_atomic = o->GetObjectForDotSeparatedPath("is_atomic")->GetBooleanValue(); - addr_t addr = o->GetObjectForDotSeparatedPath("address")->GetIntegerValue(); + addr_t addr = + o->GetObjectForDotSeparatedPath("address")->GetUnsignedIntegerValue(); std::string addr_string = Sprintf(" at 0x%llx", addr); @@ -970,44 +969,44 @@ static std::string GenerateThreadName(const std::string &path, ->GetStringValue() == "swift-access-race") { result = Sprintf("modifying access by thread %d", thread_id); } else { - result = Sprintf("%s%s of size %d%s by thread %d", + result = Sprintf("%s%s of size %zu%s by thread %" PRIu64, is_atomic ? "atomic " : "", is_write ? "write" : "read", size, addr_string.c_str(), thread_id); } } if (path == "threads") { - int thread_id = - o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue(); - result = Sprintf("Thread %d created", thread_id); + tid_t thread_id = + o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue(); + result = Sprintf("Thread %zu created", thread_id); } if (path == "locs") { std::string type = std::string( o->GetAsDictionary()->GetValueForKey("type")->GetStringValue()); - int thread_id = - o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue(); - int fd = - o->GetObjectForDotSeparatedPath("file_descriptor")->GetIntegerValue(); + tid_t thread_id = + o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue(); + int fd = o->GetObjectForDotSeparatedPath("file_descriptor") + ->GetSignedIntegerValue(); if (type == "heap") { - result = Sprintf("Heap block allocated by thread %d", thread_id); + result = Sprintf("Heap block allocated by thread %" PRIu64, thread_id); } else if (type == "fd") { - result = - Sprintf("File descriptor %d created by thread %t", fd, thread_id); + result = Sprintf("File descriptor %d created by thread %" PRIu64, fd, + thread_id); } } if (path == "mutexes") { int mutex_id = - o->GetObjectForDotSeparatedPath("mutex_id")->GetIntegerValue(); + o->GetObjectForDotSeparatedPath("mutex_id")->GetSignedIntegerValue(); result = Sprintf("Mutex M%d created", mutex_id); } if (path == "stacks") { - int thread_id = - o->GetObjectForDotSeparatedPath("thread_id")->GetIntegerValue(); - result = Sprintf("Thread %d", thread_id); + tid_t thread_id = + o->GetObjectForDotSeparatedPath("thread_id")->GetUnsignedIntegerValue(); + result = Sprintf("Thread %" PRIu64, thread_id); } result[0] = toupper(result[0]); @@ -1023,7 +1022,7 @@ static void AddThreadsForPath(const std::string &path, std::vector<lldb::addr_t> pcs; o->GetObjectForDotSeparatedPath("trace")->GetAsArray()->ForEach( [&pcs](StructuredData::Object *pc) -> bool { - pcs.push_back(pc->GetAsInteger()->GetValue()); + pcs.push_back(pc->GetUnsignedIntegerValue()); return true; }); @@ -1032,7 +1031,8 @@ static void AddThreadsForPath(const std::string &path, StructuredData::ObjectSP thread_id_obj = o->GetObjectForDotSeparatedPath("thread_os_id"); - tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0; + tid_t tid = + thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0; ThreadSP new_thread_sp = std::make_shared<HistoryThread>(*process_sp, tid, pcs); 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 7ea8b4697d20..2e3c053b97bc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/InstrumentationRuntime/UBSan/InstrumentationRuntimeUBSan.cpp @@ -67,19 +67,18 @@ __ubsan_get_current_report_data(const char **OutIssueKind, const char **OutMessage, const char **OutFilename, unsigned *OutLine, unsigned *OutCol, char **OutMemoryAddr); } +)"; -struct data { +static const char *ub_sanitizer_retrieve_report_data_command = R"( +struct { const char *issue_kind; const char *message; const char *filename; unsigned line; unsigned col; char *memory_addr; -}; -)"; +} t; -static const char *ub_sanitizer_retrieve_report_data_command = R"( -data t; __ubsan_get_current_report_data(&t.issue_kind, &t.message, &t.filename, &t.line, &t.col, &t.memory_addr); t; @@ -109,7 +108,8 @@ StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData( return StructuredData::ObjectSP(); ThreadSP thread_sp = exe_ctx_ref.GetThreadSP(); - StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + StackFrameSP frame_sp = + thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); ModuleSP runtime_module_sp = GetRuntimeModuleSP(); Target &target = process_sp->GetTarget(); @@ -154,7 +154,7 @@ StructuredData::ObjectSP InstrumentationRuntimeUBSan::RetrieveReportData( continue; lldb::addr_t PC = FCA.GetLoadAddress(&target); - trace->AddItem(StructuredData::ObjectSP(new StructuredData::Integer(PC))); + trace->AddIntegerItem(PC); } std::string IssueKind = RetrieveString(main_value, process_sp, ".issue_kind"); @@ -312,7 +312,7 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo( std::vector<lldb::addr_t> PCs; auto trace = info->GetObjectForDotSeparatedPath("trace")->GetAsArray(); trace->ForEach([&PCs](StructuredData::Object *PC) -> bool { - PCs.push_back(PC->GetAsInteger()->GetValue()); + PCs.push_back(PC->GetUnsignedIntegerValue()); return true; }); @@ -321,7 +321,7 @@ InstrumentationRuntimeUBSan::GetBacktracesFromExtendedStopInfo( StructuredData::ObjectSP thread_id_obj = info->GetObjectForDotSeparatedPath("tid"); - tid_t tid = thread_id_obj ? thread_id_obj->GetIntegerValue() : 0; + tid_t tid = thread_id_obj ? thread_id_obj->GetUnsignedIntegerValue() : 0; // We gather symbolication addresses above, so no need for HistoryThread to // try to infer the call addresses. 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 c78804f98b09..97d401028d45 100644 --- a/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -101,9 +101,10 @@ public: } EnableJITLoaderGDB GetEnable() const { - return (EnableJITLoaderGDB)m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, ePropertyEnable, - g_jitloadergdb_properties[ePropertyEnable].default_uint_value); + return GetPropertyAtIndexAs<EnableJITLoaderGDB>( + ePropertyEnable, + static_cast<EnableJITLoaderGDB>( + g_jitloadergdb_properties[ePropertyEnable].default_uint_value)); } }; } // namespace @@ -160,8 +161,7 @@ void JITLoaderGDB::DebuggerInitialize(Debugger &debugger) { const bool is_global_setting = true; PluginManager::CreateSettingForJITLoaderPlugin( debugger, GetGlobalPluginProperties().GetValueProperties(), - ConstString("Properties for the JIT LoaderGDB plug-in."), - is_global_setting); + "Properties for the JIT LoaderGDB plug-in.", is_global_setting); } } 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 40ffe9673792..e780cd8285c4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -45,7 +45,7 @@ public: lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), std::move(err), - "Failed to get scratch TypeSystemClang"); + "Failed to get scratch TypeSystemClang: {0}"); return; } @@ -78,10 +78,10 @@ public: const char *const FuncPtr_name("__FuncPtr"); m_block_struct_type = clang_ast_context->CreateStructForIdentifier( - ConstString(), {{isa_name, isa_type}, - {flags_name, flags_type}, - {reserved_name, reserved_type}, - {FuncPtr_name, function_pointer_type}}); + llvm::StringRef(), {{isa_name, isa_type}, + {flags_name, flags_type}, + {reserved_name, reserved_type}, + {FuncPtr_name, function_pointer_type}}); } ~BlockPointerSyntheticFrontEnd() override = default; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 1b152c16eac2..3d709e3d6759 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -648,95 +648,91 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringSummaryProviderASCII, - "std::string summary provider", - ConstString("^std::__[[:alnum:]]+::string$"), stl_summary_flags, - true); + "std::string summary provider", "^std::__[[:alnum:]]+::string$", + stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringSummaryProviderASCII, "std::string summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string<char, " - "std::__[[:alnum:]]+::char_traits<char>, " - "std::__[[:alnum:]]+::allocator<char> >$"), + "^std::__[[:alnum:]]+::basic_string<char, " + "std::__[[:alnum:]]+::char_traits<char>, " + "std::__[[:alnum:]]+::allocator<char> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringSummaryProviderASCII, "std::string summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string<unsigned char, " - "std::__[[:alnum:]]+::char_traits<unsigned char>, " - "std::__[[:alnum:]]+::allocator<unsigned char> >$"), + "^std::__[[:alnum:]]+::basic_string<unsigned char, " + "std::__[[:alnum:]]+::char_traits<unsigned char>, " + "std::__[[:alnum:]]+::allocator<unsigned char> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringSummaryProviderUTF16, "std::u16string summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string<char16_t, " - "std::__[[:alnum:]]+::char_traits<char16_t>, " - "std::__[[:alnum:]]+::allocator<char16_t> >$"), + "^std::__[[:alnum:]]+::basic_string<char16_t, " + "std::__[[:alnum:]]+::char_traits<char16_t>, " + "std::__[[:alnum:]]+::allocator<char16_t> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringSummaryProviderUTF32, "std::u32string summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string<char32_t, " - "std::__[[:alnum:]]+::char_traits<char32_t>, " - "std::__[[:alnum:]]+::allocator<char32_t> >$"), + "^std::__[[:alnum:]]+::basic_string<char32_t, " + "std::__[[:alnum:]]+::char_traits<char32_t>, " + "std::__[[:alnum:]]+::allocator<char32_t> >$", stl_summary_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::LibcxxWStringSummaryProvider, - "std::wstring summary provider", - ConstString("^std::__[[:alnum:]]+::wstring$"), stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string<wchar_t, " - "std::__[[:alnum:]]+::char_traits<wchar_t>, " - "std::__[[:alnum:]]+::allocator<wchar_t> >$"), + "^std::__[[:alnum:]]+::wstring$", stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxWStringSummaryProvider, + "std::wstring summary provider", + "^std::__[[:alnum:]]+::basic_string<wchar_t, " + "std::__[[:alnum:]]+::char_traits<wchar_t>, " + "std::__[[:alnum:]]+::allocator<wchar_t> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, "std::string_view summary provider", - ConstString("^std::__[[:alnum:]]+::string_view$"), + "^std::__[[:alnum:]]+::string_view$", stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, + "std::string_view summary provider", + "^std::__[[:alnum:]]+::basic_string_view<char, " + "std::__[[:alnum:]]+::char_traits<char> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, "std::string_view summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string_view<char, " - "std::__[[:alnum:]]+::char_traits<char> >$"), + "^std::__[[:alnum:]]+::basic_string_view<unsigned char, " + "std::__[[:alnum:]]+::char_traits<unsigned char> >$", stl_summary_flags, true); - AddCXXSummary( - cpp_category_sp, - lldb_private::formatters::LibcxxStringViewSummaryProviderASCII, - "std::string_view summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string_view<unsigned char, " - "std::__[[:alnum:]]+::char_traits<unsigned char> >$"), - stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringViewSummaryProviderUTF16, "std::u16string_view summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string_view<char16_t, " - "std::__[[:alnum:]]+::char_traits<char16_t> >$"), + "^std::__[[:alnum:]]+::basic_string_view<char16_t, " + "std::__[[:alnum:]]+::char_traits<char16_t> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxStringViewSummaryProviderUTF32, "std::u32string_view summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string_view<char32_t, " - "std::__[[:alnum:]]+::char_traits<char32_t> >$"), + "^std::__[[:alnum:]]+::basic_string_view<char32_t, " + "std::__[[:alnum:]]+::char_traits<char32_t> >$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxWStringViewSummaryProvider, "std::wstring_view summary provider", - ConstString("^std::__[[:alnum:]]+::wstring_view$"), - stl_summary_flags, true); + "^std::__[[:alnum:]]+::wstring_view$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxWStringViewSummaryProvider, "std::wstring_view summary provider", - ConstString("^std::__[[:alnum:]]+::basic_string_view<wchar_t, " - "std::__[[:alnum:]]+::char_traits<wchar_t> >$"), + "^std::__[[:alnum:]]+::basic_string_view<wchar_t, " + "std::__[[:alnum:]]+::char_traits<wchar_t> >$", stl_summary_flags, true); SyntheticChildren::Flags stl_synth_flags; @@ -749,98 +745,89 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator, "libc++ std::bitset synthetic children", - ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"), stl_deref_flags, - true); + "^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$", stl_deref_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator, "libc++ std::vector synthetic children", - ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"), stl_deref_flags, - true); + "^std::__[[:alnum:]]+::vector<.+>(( )?&)?$", stl_deref_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdForwardListSyntheticFrontEndCreator, "libc++ std::forward_list synthetic children", - ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"), - stl_synth_flags, true); + "^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$", stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdListSyntheticFrontEndCreator, "libc++ std::list synthetic children", // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$" // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$" - ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|" - "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"), + "^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|" + "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$", stl_deref_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::map synthetic children", - ConstString("^std::__[[:alnum:]]+::map<.+> >(( )?&)?$"), stl_synth_flags, - true); + "^std::__[[:alnum:]]+::map<.+> >(( )?&)?$", stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::set synthetic children", - ConstString("^std::__[[:alnum:]]+::set<.+> >(( )?&)?$"), stl_deref_flags, - true); + "^std::__[[:alnum:]]+::set<.+> >(( )?&)?$", stl_deref_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multiset synthetic children", - ConstString("^std::__[[:alnum:]]+::multiset<.+> >(( )?&)?$"), - stl_deref_flags, true); + "^std::__[[:alnum:]]+::multiset<.+> >(( )?&)?$", stl_deref_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator, "libc++ std::multimap synthetic children", - ConstString("^std::__[[:alnum:]]+::multimap<.+> >(( )?&)?$"), - stl_synth_flags, true); + "^std::__[[:alnum:]]+::multimap<.+> >(( )?&)?$", stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEndCreator, "libc++ std::unordered containers synthetic children", - ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"), + "^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$", stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxInitializerListSyntheticFrontEndCreator, "libc++ std::initializer_list synthetic children", - ConstString("^std::initializer_list<.+>(( )?&)?$"), stl_synth_flags, - true); + "^std::initializer_list<.+>(( )?&)?$", stl_synth_flags, true); AddCXXSynthetic(cpp_category_sp, LibcxxQueueFrontEndCreator, "libc++ std::queue synthetic children", - ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"), - stl_synth_flags, true); + "^std::__[[:alnum:]]+::queue<.+>(( )?&)?$", stl_synth_flags, + true); AddCXXSynthetic(cpp_category_sp, LibcxxTupleFrontEndCreator, "libc++ std::tuple synthetic children", - ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"), - stl_synth_flags, true); + "^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$", stl_synth_flags, + true); AddCXXSynthetic(cpp_category_sp, LibcxxOptionalSyntheticFrontEndCreator, "libc++ std::optional synthetic children", - ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"), + "^std::__[[:alnum:]]+::optional<.+>(( )?&)?$", stl_synth_flags, true); AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator, "libc++ std::variant synthetic children", - ConstString("^std::__[[:alnum:]]+::variant<.+>(( )?&)?$"), - stl_synth_flags, true); + "^std::__[[:alnum:]]+::variant<.+>(( )?&)?$", stl_synth_flags, + true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, "libc++ std::atomic synthetic children", - ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), stl_synth_flags, true); + "^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); + "^std::__[[:alnum:]]+::span<.+>(( )?&)?$", stl_deref_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxStdRangesRefViewSyntheticFrontEndCreator, "libc++ std::ranges::ref_view synthetic children", - ConstString("^std::__[[:alnum:]]+::ranges::ref_view<.+>(( )?&)?$"), - stl_deref_flags, true); + "^std::__[[:alnum:]]+::ranges::ref_view<.+>(( )?&)?$", stl_deref_flags, + true); cpp_category_sp->AddTypeSynthetic( "^(std::__[[:alnum:]]+::)deque<.+>(( )?&)?$", eFormatterMatchRegex, @@ -852,11 +839,10 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "shared_ptr synthetic children", - ConstString("^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$"), - stl_synth_flags, true); + "^(std::__[[:alnum:]]+::)shared_ptr<.+>(( )?&)?$", stl_synth_flags, true); - ConstString libcxx_std_unique_ptr_regex( - "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$"); + static constexpr const char *const libcxx_std_unique_ptr_regex = + "^std::__[[:alnum:]]+::unique_ptr<.+>(( )?&)?$"; AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator, @@ -867,16 +853,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEndCreator, "weak_ptr synthetic children", - ConstString("^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$"), - stl_synth_flags, true); + "^(std::__[[:alnum:]]+::)weak_ptr<.+>(( )?&)?$", stl_synth_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxFunctionSummaryProvider, "libc++ std::function summary provider", - ConstString("^std::__[[:alnum:]]+::function<.+>$"), - stl_summary_flags, true); + "^std::__[[:alnum:]]+::function<.+>$", stl_summary_flags, true); - ConstString libcxx_std_coroutine_handle_regex( - "^std::__[[:alnum:]]+::coroutine_handle<.+>(( )?&)?$"); + static constexpr const char *const libcxx_std_coroutine_handle_regex = + "^std::__[[:alnum:]]+::coroutine_handle<.+>(( )?&)?$"; AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator, @@ -885,100 +869,88 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { stl_summary_flags.SetDontShowChildren(false); stl_summary_flags.SetSkipPointers(false); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::bitset summary provider", - ConstString("^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$"), - stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::vector summary provider", - ConstString("^std::__[[:alnum:]]+::vector<.+>(( )?&)?$"), - stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::bitset summary provider", + "^std::__[[:alnum:]]+::bitset<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::vector summary provider", + "^std::__[[:alnum:]]+::vector<.+>(( )?&)?$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::list summary provider", - ConstString("^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$"), + "^std::__[[:alnum:]]+::forward_list<.+>(( )?&)?$", stl_summary_flags, true); AddCXXSummary( cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, "libc++ std::list summary provider", // A POSIX variant of: "^std::__(?!cxx11:)[[:alnum:]]+::list<.+>(( )?&)?$" // so that it does not clash with: "^std::(__cxx11::)?list<.+>(( )?&)?$" - ConstString("^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|" - "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$"), + "^std::__([A-Zabd-z0-9]|cx?[A-Za-wyz0-9]|cxx1?[A-Za-z02-9]|" + "cxx11[[:alnum:]])[[:alnum:]]*::list<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::map summary provider", + "^std::__[[:alnum:]]+::map<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::deque summary provider", + "^std::__[[:alnum:]]+::deque<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::queue summary provider", + "^std::__[[:alnum:]]+::queue<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::set summary provider", + "^std::__[[:alnum:]]+::set<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::multiset summary provider", + "^std::__[[:alnum:]]+::multiset<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::multimap summary provider", + "^std::__[[:alnum:]]+::multimap<.+>(( )?&)?$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::map summary provider", - ConstString("^std::__[[:alnum:]]+::map<.+>(( )?&)?$"), - stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::deque summary provider", - ConstString("^std::__[[:alnum:]]+::deque<.+>(( )?&)?$"), - stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::queue summary provider", - ConstString("^std::__[[:alnum:]]+::queue<.+>(( )?&)?$"), - stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::set summary provider", - ConstString("^std::__[[:alnum:]]+::set<.+>(( )?&)?$"), - stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::multiset summary provider", - ConstString("^std::__[[:alnum:]]+::multiset<.+>(( )?&)?$"), - stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::multimap summary provider", - ConstString("^std::__[[:alnum:]]+::multimap<.+>(( )?&)?$"), + "libc++ std::unordered containers summary provider", + "^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$", stl_summary_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, - "libc++ std::unordered containers summary provider", - ConstString("^(std::__[[:alnum:]]+::)unordered_(multi)?(map|set)<.+> >$"), - stl_summary_flags, true); AddCXXSummary(cpp_category_sp, LibcxxContainerSummaryProvider, "libc++ std::tuple summary provider", - ConstString("^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$"), - stl_summary_flags, true); + "^std::__[[:alnum:]]+::tuple<.*>(( )?&)?$", stl_summary_flags, + true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, "libc++ std::atomic summary provider", - ConstString("^std::__[[:alnum:]]+::atomic<.+>$"), - stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::GenericOptionalSummaryProvider, - "libc++ std::optional summary provider", - ConstString("^std::__[[:alnum:]]+::optional<.+>(( )?&)?$"), - stl_summary_flags, true); - AddCXXSummary(cpp_category_sp, - lldb_private::formatters::LibcxxVariantSummaryProvider, - "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); + "^std::__[[:alnum:]]+::atomic<.+>$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::GenericOptionalSummaryProvider, + "libc++ std::optional summary provider", + "^std::__[[:alnum:]]+::optional<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxVariantSummaryProvider, + "libc++ std::variant summary provider", + "^std::__[[:alnum:]]+::variant<.+>(( )?&)?$", stl_summary_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxContainerSummaryProvider, + "libc++ std::span summary provider", + "^std::__[[:alnum:]]+::span<.+>(( )?&)?$", stl_summary_flags, true); stl_summary_flags.SetSkipPointers(true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::shared_ptr summary provider", - ConstString("^std::__[[:alnum:]]+::shared_ptr<.+>(( )?&)?$"), + "^std::__[[:alnum:]]+::shared_ptr<.+>(( )?&)?$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxSmartPointerSummaryProvider, "libc++ std::weak_ptr summary provider", - ConstString("^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$"), + "^std::__[[:alnum:]]+::weak_ptr<.+>(( )?&)?$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibcxxUniquePointerSummaryProvider, @@ -994,23 +966,21 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", - ConstString("^std::__[[:alnum:]]+::__wrap_iter<.+>$"), stl_synth_flags, - true); + "^std::__[[:alnum:]]+::__wrap_iter<.+>$", stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEndCreator, "std::map iterator synthetic children", - ConstString("^std::__[[:alnum:]]+::__map_(const_)?iterator<.+>$"), stl_synth_flags, + "^std::__[[:alnum:]]+::__map_(const_)?iterator<.+>$", stl_synth_flags, true); - AddCXXSynthetic( - cpp_category_sp, - lldb_private::formatters:: - LibCxxUnorderedMapIteratorSyntheticFrontEndCreator, - "std::unordered_map iterator synthetic children", - ConstString("^std::__[[:alnum:]]+::__hash_map_(const_)?iterator<.+>$"), - stl_synth_flags, true); + AddCXXSynthetic(cpp_category_sp, + lldb_private::formatters:: + LibCxxUnorderedMapIteratorSyntheticFrontEndCreator, + "std::unordered_map iterator synthetic children", + "^std::__[[:alnum:]]+::__hash_map_(const_)?iterator<.+>$", + stl_synth_flags, true); } static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { @@ -1183,37 +1153,37 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibStdcppVectorIteratorSyntheticFrontEndCreator, "std::vector iterator synthetic children", - ConstString("^__gnu_cxx::__normal_iterator<.+>$"), stl_synth_flags, true); + "^__gnu_cxx::__normal_iterator<.+>$", stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibstdcppMapIteratorSyntheticFrontEndCreator, - "std::map iterator synthetic children", - ConstString("^std::_Rb_tree_iterator<.+>$"), stl_synth_flags, true); + "std::map iterator synthetic children", "^std::_Rb_tree_iterator<.+>$", + stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibStdcppUniquePtrSyntheticFrontEndCreator, - "std::unique_ptr synthetic children", - ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_synth_flags, true); + "std::unique_ptr synthetic children", "^std::unique_ptr<.+>(( )?&)?$", + stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, - "std::shared_ptr synthetic children", - ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_synth_flags, true); + "std::shared_ptr synthetic children", "^std::shared_ptr<.+>(( )?&)?$", + stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibStdcppSharedPtrSyntheticFrontEndCreator, - "std::weak_ptr synthetic children", - ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true); + "std::weak_ptr synthetic children", "^std::weak_ptr<.+>(( )?&)?$", + stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibStdcppTupleSyntheticFrontEndCreator, - "std::tuple synthetic children", ConstString("^std::tuple<.+>(( )?&)?$"), + "std::tuple synthetic children", "^std::tuple<.+>(( )?&)?$", stl_synth_flags, true); - ConstString libstdcpp_std_coroutine_handle_regex( - "^std::coroutine_handle<.+>(( )?&)?$"); + static constexpr const char *const libstdcpp_std_coroutine_handle_regex = + "^std::coroutine_handle<.+>(( )?&)?$"; AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEndCreator, @@ -1223,38 +1193,35 @@ static void LoadLibStdcppFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibStdcppBitsetSyntheticFrontEndCreator, - "std::bitset synthetic child", ConstString("^std::bitset<.+>(( )?&)?$"), + "std::bitset synthetic child", "^std::bitset<.+>(( )?&)?$", stl_deref_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibStdcppOptionalSyntheticFrontEndCreator, - "std::optional synthetic child", - ConstString("^std::optional<.+>(( )?&)?$"), stl_deref_flags, true); + "std::optional synthetic child", "^std::optional<.+>(( )?&)?$", + stl_deref_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppUniquePointerSummaryProvider, "libstdc++ std::unique_ptr summary provider", - ConstString("^std::unique_ptr<.+>(( )?&)?$"), stl_summary_flags, - true); + "^std::unique_ptr<.+>(( )?&)?$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, "libstdc++ std::shared_ptr summary provider", - ConstString("^std::shared_ptr<.+>(( )?&)?$"), stl_summary_flags, - true); + "^std::shared_ptr<.+>(( )?&)?$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::LibStdcppSmartPointerSummaryProvider, "libstdc++ std::weak_ptr summary provider", - ConstString("^std::weak_ptr<.+>(( )?&)?$"), stl_summary_flags, - true); + "^std::weak_ptr<.+>(( )?&)?$", stl_summary_flags, true); AddCXXSummary(cpp_category_sp, lldb_private::formatters::StdlibCoroutineHandleSummaryProvider, "libstdc++ std::coroutine_handle summary provider", libstdcpp_std_coroutine_handle_regex, stl_summary_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::GenericOptionalSummaryProvider, - "libstd++ std::optional summary provider", - ConstString("^std::optional<.+>(( )?&)?$"), stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::GenericOptionalSummaryProvider, + "libstd++ std::optional summary provider", + "^std::optional<.+>(( )?&)?$", stl_summary_flags, true); } static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { @@ -1279,41 +1246,41 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { .SetShowMembersOneLiner(false) .SetHideItemNames(false); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider, - "char8_t * summary provider", ConstString("char8_t *"), string_flags); AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8StringSummaryProvider, - "char8_t [] summary provider", - ConstString("char8_t ?\\[[0-9]+\\]"), string_array_flags, true); + "char8_t * summary provider", "char8_t *", string_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char8StringSummaryProvider, + "char8_t [] summary provider", "char8_t ?\\[[0-9]+\\]", + string_array_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, - "char16_t * summary provider", ConstString("char16_t *"), string_flags); AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, - "char16_t [] summary provider", - ConstString("char16_t ?\\[[0-9]+\\]"), string_array_flags, true); + "char16_t * summary provider", "char16_t *", string_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char16StringSummaryProvider, + "char16_t [] summary provider", "char16_t ?\\[[0-9]+\\]", + string_array_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, - "char32_t * summary provider", ConstString("char32_t *"), string_flags); AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char32StringSummaryProvider, - "char32_t [] summary provider", - ConstString("char32_t ?\\[[0-9]+\\]"), string_array_flags, true); + "char32_t * summary provider", "char32_t *", string_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char32StringSummaryProvider, + "char32_t [] summary provider", "char32_t ?\\[[0-9]+\\]", + string_array_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, - "wchar_t * summary provider", ConstString("wchar_t *"), string_flags); AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharStringSummaryProvider, - "wchar_t * summary provider", - ConstString("wchar_t ?\\[[0-9]+\\]"), string_array_flags, true); + "wchar_t * summary provider", "wchar_t *", string_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::WCharStringSummaryProvider, + "wchar_t * summary provider", "wchar_t ?\\[[0-9]+\\]", + string_array_flags, true); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::Char16StringSummaryProvider, - "unichar * summary provider", ConstString("unichar *"), string_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char16StringSummaryProvider, + "unichar * summary provider", "unichar *", string_flags); TypeSummaryImpl::Flags widechar_flags; widechar_flags.SetDontShowValue(true) @@ -1325,21 +1292,19 @@ static void LoadSystemFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { .SetShowMembersOneLiner(false); AddCXXSummary(cpp_category_sp, lldb_private::formatters::Char8SummaryProvider, - "char8_t summary provider", ConstString("char8_t"), - widechar_flags); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, - "char16_t summary provider", ConstString("char16_t"), widechar_flags); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::Char32SummaryProvider, - "char32_t summary provider", ConstString("char32_t"), widechar_flags); + "char8_t summary provider", "char8_t", widechar_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char16SummaryProvider, + "char16_t summary provider", "char16_t", widechar_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char32SummaryProvider, + "char32_t summary provider", "char32_t", widechar_flags); AddCXXSummary(cpp_category_sp, lldb_private::formatters::WCharSummaryProvider, - "wchar_t summary provider", ConstString("wchar_t"), - widechar_flags); + "wchar_t summary provider", "wchar_t", widechar_flags); - AddCXXSummary( - cpp_category_sp, lldb_private::formatters::Char16SummaryProvider, - "unichar summary provider", ConstString("unichar"), widechar_flags); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::Char16SummaryProvider, + "unichar summary provider", "unichar", widechar_flags); } std::unique_ptr<Language::TypeScavenger> CPlusPlusLanguage::GetTypeScavenger() { @@ -1390,7 +1355,8 @@ CPlusPlusLanguage::GetHardcodedSummaries() { TypeSummaryImpl::Flags(), lldb_private::formatters::CXXFunctionPointerSummaryProvider, "Function pointer summary provider")); - if (valobj.GetCompilerType().IsFunctionPointerType()) { + if (CompilerType CT = valobj.GetCompilerType(); + CT.IsFunctionPointerType() || CT.IsMemberFunctionPointerType()) { return formatter_sp; } return nullptr; @@ -1499,7 +1465,7 @@ bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c", ".h", ".hh", ".hpp", ".hxx", ".h++"}; for (auto suffix : suffixes) { - if (file_path.endswith_insensitive(suffix)) + if (file_path.ends_with_insensitive(suffix)) return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index 809996497c11..7712a60b7795 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -165,6 +165,8 @@ public: ConstString FindBestAlternateFunctionMangledName( const Mangled mangled, const SymbolContext &sym_ctx) const override; + llvm::StringRef GetInstanceVariableName() override { return "this"; } + // PluginInterface protocol llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp index 617181a35d1d..d8c095d6edeb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp @@ -172,7 +172,7 @@ CPlusPlusNameParser::ParseFuncPtr(bool expect_return_type) { // // Consume inner function name. This will fail unless // we stripped all the pointers on the left hand side - // of the funciton name. + // of the function name. { Bookmark before_inner_function_pos = SetBookmark(); auto maybe_inner_function_name = ParseFunctionImpl(false); @@ -750,6 +750,7 @@ static const clang::LangOptions &GetLangOptions() { g_options.CPlusPlus11 = true; g_options.CPlusPlus14 = true; g_options.CPlusPlus17 = true; + g_options.CPlusPlus20 = true; }); return g_options; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp index c5170757496f..6aeae97667c1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp @@ -24,7 +24,7 @@ static lldb::addr_t GetCoroFramePtrFromHandle(ValueObjectSP valobj_sp) { // We don't care about its name. if (valobj_sp->GetNumChildren() != 1) return LLDB_INVALID_ADDRESS; - ValueObjectSP ptr_sp(valobj_sp->GetChildAtIndex(0, true)); + ValueObjectSP ptr_sp(valobj_sp->GetChildAtIndex(0)); if (!ptr_sp) return LLDB_INVALID_ADDRESS; if (!ptr_sp->GetCompilerType().IsPointerType()) diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index bbd1e52ebaaf..6781c96210a4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -17,7 +17,6 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Host/Time.h" -#include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp index bc65570fe339..cd3ac92ae4a8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericBitset.cpp @@ -90,8 +90,8 @@ bool GenericBitsetFrontEnd::Update() { size = arg->value.getLimitedValue(); m_elements.assign(size, ValueObjectSP()); - m_first = m_backend.GetChildMemberWithName(GetDataContainerMemberName(), true) - .get(); + m_first = + m_backend.GetChildMemberWithName(GetDataContainerMemberName()).get(); return false; } @@ -111,7 +111,7 @@ ValueObjectSP GenericBitsetFrontEnd::GetChildAtIndex(size_t idx) { type.GetBitSize(ctx.GetBestExecutionContextScope()); if (!bit_size || *bit_size == 0) return {}; - chunk = m_first->GetChildAtIndex(idx / *bit_size, true); + chunk = m_first->GetChildAtIndex(idx / *bit_size); } else { type = m_first->GetCompilerType(); chunk = m_first->GetSP(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp index 74b3f711de35..7415e915844f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/GenericOptional.cpp @@ -65,12 +65,10 @@ bool GenericOptionalFrontend::Update() { ValueObjectSP engaged_sp; if (m_stdlib == StdLib::LibCxx) - engaged_sp = - m_backend.GetChildMemberWithName(ConstString("__engaged_"), true); + engaged_sp = m_backend.GetChildMemberWithName("__engaged_"); else if (m_stdlib == StdLib::LibStdcpp) - engaged_sp = - m_backend.GetChildMemberWithName(ConstString("_M_payload"), true) - ->GetChildMemberWithName(ConstString("_M_engaged"), true); + engaged_sp = m_backend.GetChildMemberWithName("_M_payload") + ->GetChildMemberWithName("_M_engaged"); if (!engaged_sp) return false; @@ -94,18 +92,17 @@ ValueObjectSP GenericOptionalFrontend::GetChildAtIndex(size_t _idx) { // Currently because it is part of an anonymous union // GetChildMemberWithName() does not peer through and find it unless we are // at the parent itself. We can obtain the parent through __engaged_. - val_sp = m_backend.GetChildMemberWithName(ConstString("__engaged_"), true) + val_sp = m_backend.GetChildMemberWithName("__engaged_") ->GetParent() - ->GetChildAtIndex(0, true) - ->GetChildMemberWithName(ConstString("__val_"), true); + ->GetChildAtIndex(0) + ->GetChildMemberWithName("__val_"); else if (m_stdlib == StdLib::LibStdcpp) { - val_sp = m_backend.GetChildMemberWithName(ConstString("_M_payload"), true) - ->GetChildMemberWithName(ConstString("_M_payload"), true); + val_sp = m_backend.GetChildMemberWithName("_M_payload") + ->GetChildMemberWithName("_M_payload"); // In some implementations, _M_value contains the underlying value of an // optional, and in other versions, it's in the payload member. - ValueObjectSP candidate = - val_sp->GetChildMemberWithName(ConstString("_M_value"), true); + ValueObjectSP candidate = val_sp->GetChildMemberWithName("_M_value"); if (candidate) val_sp = candidate; } 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 faa33ecefc2d..cae17ef992b2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -16,7 +16,6 @@ #include "lldb/DataFormatters/StringPrinter.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/DataFormatters/VectorIterator.h" -#include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ConstString.h" @@ -38,7 +37,7 @@ using namespace lldb_private::formatters; lldb::ValueObjectSP lldb_private::formatters::GetChildMemberWithName( ValueObject &obj, llvm::ArrayRef<ConstString> alternative_names) { for (ConstString name : alternative_names) { - lldb::ValueObjectSP child_sp = obj.GetChildMemberWithName(name, true); + lldb::ValueObjectSP child_sp = obj.GetChildMemberWithName(name); if (child_sp) return child_sp; @@ -46,26 +45,35 @@ lldb::ValueObjectSP lldb_private::formatters::GetChildMemberWithName( return {}; } -bool lldb_private::formatters::LibcxxOptionalSummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); - if (!valobj_sp) - return false; - - // An optional either contains a value or not, the member __engaged_ is - // a bool flag, it is true if the optional has a value and false otherwise. - ValueObjectSP engaged_sp( - valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true)); - - if (!engaged_sp) - return false; - - llvm::StringRef engaged_as_cstring( - engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false"); - - stream.Printf(" Has Value=%s ", engaged_as_cstring.data()); +lldb::ValueObjectSP +lldb_private::formatters::GetFirstValueOfLibCXXCompressedPair( + ValueObject &pair) { + ValueObjectSP value; + ValueObjectSP first_child = pair.GetChildAtIndex(0); + if (first_child) + value = first_child->GetChildMemberWithName("__value_"); + if (!value) { + // pre-r300140 member name + value = pair.GetChildMemberWithName("__first_"); + } + return value; +} - return true; +lldb::ValueObjectSP +lldb_private::formatters::GetSecondValueOfLibCXXCompressedPair( + ValueObject &pair) { + ValueObjectSP value; + if (pair.GetNumChildren() > 1) { + ValueObjectSP second_child = pair.GetChildAtIndex(1); + if (second_child) { + value = second_child->GetChildMemberWithName("__value_"); + } + } + if (!value) { + // pre-r300140 member name + value = pair.GetChildMemberWithName("__second_"); + } + return value; } bool lldb_private::formatters::LibcxxFunctionSummaryProvider( @@ -121,12 +129,11 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider( ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); if (!valobj_sp) return false; - ValueObjectSP ptr_sp( - valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); - ValueObjectSP count_sp(valobj_sp->GetChildAtNamePath( - {ConstString("__cntrl_"), ConstString("__shared_owners_")})); - ValueObjectSP weakcount_sp(valobj_sp->GetChildAtNamePath( - {ConstString("__cntrl_"), ConstString("__shared_weak_owners_")})); + ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("__ptr_")); + ValueObjectSP count_sp( + valobj_sp->GetChildAtNamePath({"__cntrl_", "__shared_owners_"})); + ValueObjectSP weakcount_sp( + valobj_sp->GetChildAtNamePath({"__cntrl_", "__shared_weak_owners_"})); if (!ptr_sp) return false; @@ -165,12 +172,11 @@ bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider( if (!valobj_sp) return false; - ValueObjectSP ptr_sp( - valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); + ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("__ptr_")); if (!ptr_sp) return false; - ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp); + ptr_sp = GetFirstValueOfLibCXXCompressedPair(*ptr_sp); if (!ptr_sp) return false; @@ -241,8 +247,6 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { if (!valobj_sp) return false; - 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 // with a loop (iterator -> synthetic -> child -> parent == iterator) and @@ -271,7 +275,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("__i_")); if (!__i_) { m_pair_ptr = nullptr; return false; @@ -313,7 +317,7 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { // +-----------------------------+ // CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( - ConstString(), + llvm::StringRef(), {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, {"ptr1", @@ -338,7 +342,7 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { "pair", extractor, valobj_sp->GetExecutionContextRef(), tree_node_type); if (pair_sp) - m_pair_sp = pair_sp->GetChildAtIndex(4, true); + m_pair_sp = pair_sp->GetChildAtIndex(4); } } } @@ -355,9 +359,9 @@ lldb::ValueObjectSP lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::GetChildAtIndex( size_t idx) { if (m_pair_ptr) - return m_pair_ptr->GetChildAtIndex(idx, true); + return m_pair_ptr->GetChildAtIndex(idx); if (m_pair_sp) - return m_pair_sp->GetChildAtIndex(idx, true); + return m_pair_sp->GetChildAtIndex(idx); return lldb::ValueObjectSP(); } @@ -430,8 +434,7 @@ bool lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd:: .get(); if (m_iter_ptr) { - auto iter_child( - valobj_sp->GetChildMemberWithName(ConstString("__i_"), true)); + auto iter_child(valobj_sp->GetChildMemberWithName("__i_")); if (!iter_child) { m_iter_ptr = nullptr; return false; @@ -479,7 +482,7 @@ bool lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd:: // +-----------------------------+ // CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( - ConstString(), + llvm::StringRef(), {{"__next_", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, {"__hash_", ast_ctx->GetBasicType(lldb::eBasicTypeUnsignedLongLong)}, @@ -499,7 +502,7 @@ bool lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd:: auto pair_sp = CreateValueObjectFromData( "pair", extractor, valobj_sp->GetExecutionContextRef(), tree_node_type); if (pair_sp) - m_pair_sp = pair_sp->GetChildAtIndex(2, true); + m_pair_sp = pair_sp->GetChildAtIndex(2); } return false; @@ -513,7 +516,7 @@ size_t lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd:: lldb::ValueObjectSP lldb_private::formatters:: LibCxxUnorderedMapIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx) { if (m_pair_sp) - return m_pair_sp->GetChildAtIndex(idx, true); + return m_pair_sp->GetChildAtIndex(idx); return lldb::ValueObjectSP(); } @@ -578,17 +581,18 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex( return lldb::ValueObjectSP(); if (idx == 0) - return valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true); + return valobj_sp->GetChildMemberWithName("__ptr_"); if (idx == 1) { - if (auto ptr_sp = - valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)) { + if (auto ptr_sp = valobj_sp->GetChildMemberWithName("__ptr_")) { Status status; - auto value_sp = ptr_sp->Dereference(status); + auto value_type_sp = + valobj_sp->GetCompilerType() + .GetTypeTemplateArgument(0).GetPointerType(); + ValueObjectSP cast_ptr_sp = ptr_sp->Cast(value_type_sp); + ValueObjectSP value_sp = cast_ptr_sp->Dereference(status); if (status.Success()) { - auto value_type_sp = - valobj_sp->GetCompilerType().GetTypeTemplateArgument(0); - return value_sp->Cast(value_type_sp); + return value_sp; } } } @@ -607,8 +611,7 @@ bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() { if (!target_sp) return false; - lldb::ValueObjectSP cntrl_sp( - valobj_sp->GetChildMemberWithName(ConstString("__cntrl_"), true)); + lldb::ValueObjectSP cntrl_sp(valobj_sp->GetChildMemberWithName("__cntrl_")); m_cntrl = cntrl_sp.get(); // need to store the raw pointer to avoid a circular // dependency @@ -658,7 +661,9 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEndCreator( size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: CalculateNumChildren() { - return (m_value_ptr_sp ? 1 : 0); + if (m_value_ptr_sp) + return m_deleter_sp ? 2 : 1; + return 0; } lldb::ValueObjectSP @@ -670,7 +675,10 @@ lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::GetChildAtIndex( if (idx == 0) return m_value_ptr_sp; - if (idx == 1) { + if (idx == 1) + return m_deleter_sp; + + if (idx == 2) { Status status; auto value_sp = m_value_ptr_sp->Dereference(status); if (status.Success()) { @@ -686,12 +694,19 @@ bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::Update() { if (!valobj_sp) return false; - ValueObjectSP ptr_sp( - valobj_sp->GetChildMemberWithName(ConstString("__ptr_"), true)); + ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("__ptr_")); if (!ptr_sp) return false; - m_value_ptr_sp = GetValueOfLibCXXCompressedPair(*ptr_sp); + // Retrieve the actual pointer and the deleter, and clone them to give them + // user-friendly names. + ValueObjectSP value_pointer_sp = GetFirstValueOfLibCXXCompressedPair(*ptr_sp); + if (value_pointer_sp) + m_value_ptr_sp = value_pointer_sp->Clone(ConstString("pointer")); + + ValueObjectSP deleter_sp = GetSecondValueOfLibCXXCompressedPair(*ptr_sp); + if (deleter_sp) + m_deleter_sp = deleter_sp->Clone(ConstString("deleter")); return false; } @@ -703,10 +718,12 @@ bool lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { - if (name == "__value_") + if (name == "pointer") return 0; - if (name == "$$dereference$$") + if (name == "deleter") return 1; + if (name == "$$dereference$$") + return 2; return UINT32_MAX; } @@ -732,29 +749,26 @@ enum class StringLayout { CSD, DSC }; // TODO: Support big-endian architectures. static std::optional<std::pair<uint64_t, ValueObjectSP>> ExtractLibcxxStringInfo(ValueObject &valobj) { - ValueObjectSP valobj_r_sp = - valobj.GetChildMemberWithName(ConstString("__r_"), /*can_create=*/true); + ValueObjectSP valobj_r_sp = valobj.GetChildMemberWithName("__r_"); if (!valobj_r_sp || !valobj_r_sp->GetError().Success()) return {}; // __r_ is a compressed_pair of the actual data and the allocator. The data we // want is in the first base class. - ValueObjectSP valobj_r_base_sp = - valobj_r_sp->GetChildAtIndex(0, /*can_create=*/true); + ValueObjectSP valobj_r_base_sp = valobj_r_sp->GetChildAtIndex(0); if (!valobj_r_base_sp) return {}; - ValueObjectSP valobj_rep_sp = valobj_r_base_sp->GetChildMemberWithName( - ConstString("__value_"), /*can_create=*/true); + ValueObjectSP valobj_rep_sp = + valobj_r_base_sp->GetChildMemberWithName("__value_"); if (!valobj_rep_sp) return {}; - ValueObjectSP l = valobj_rep_sp->GetChildMemberWithName(ConstString("__l"), - /*can_create=*/true); + ValueObjectSP l = valobj_rep_sp->GetChildMemberWithName("__l"); if (!l) return {}; - StringLayout layout = l->GetIndexOfChildWithName(ConstString("__data_")) == 0 + StringLayout layout = l->GetIndexOfChildWithName("__data_") == 0 ? StringLayout::DSC : StringLayout::CSD; @@ -765,15 +779,12 @@ ExtractLibcxxStringInfo(ValueObject &valobj) { uint64_t size; uint64_t size_mode_value = 0; - ValueObjectSP short_sp = valobj_rep_sp->GetChildMemberWithName( - ConstString("__s"), /*can_create=*/true); + ValueObjectSP short_sp = valobj_rep_sp->GetChildMemberWithName("__s"); if (!short_sp) return {}; - ValueObjectSP is_long = - short_sp->GetChildMemberWithName(ConstString("__is_long_"), true); - ValueObjectSP size_sp = - short_sp->GetChildAtNamePath({ConstString("__size_")}); + ValueObjectSP is_long = short_sp->GetChildMemberWithName("__is_long_"); + ValueObjectSP size_sp = short_sp->GetChildMemberWithName("__size_"); if (!size_sp) return {}; @@ -789,8 +800,7 @@ ExtractLibcxxStringInfo(ValueObject &valobj) { } if (short_mode) { - ValueObjectSP location_sp = - short_sp->GetChildMemberWithName(ConstString("__data_"), true); + ValueObjectSP location_sp = short_sp->GetChildMemberWithName("__data_"); if (using_bitmasks) size = (layout == StringLayout::DSC) ? size_mode_value : ((size_mode_value >> 1) % 256); @@ -809,12 +819,9 @@ ExtractLibcxxStringInfo(ValueObject &valobj) { } // we can use the layout_decider object as the data pointer - 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); + ValueObjectSP location_sp = l->GetChildMemberWithName("__data_"); + ValueObjectSP size_vo = l->GetChildMemberWithName("__size_"); + ValueObjectSP capacity_vo = l->GetChildMemberWithName("__cap_"); if (!size_vo || !location_sp || !capacity_vo) return {}; size = size_vo->GetValueAsUnsigned(LLDB_INVALID_OFFSET); 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 9ab22153a92a..f65801e2cb1b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -23,6 +23,10 @@ lldb::ValueObjectSP GetChildMemberWithName(ValueObject &obj, llvm::ArrayRef<ConstString> alternative_names); +lldb::ValueObjectSP GetFirstValueOfLibCXXCompressedPair(ValueObject &pair); +lldb::ValueObjectSP GetSecondValueOfLibCXXCompressedPair(ValueObject &pair); + + bool LibcxxStringSummaryProviderASCII( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options); // libc++ std::string @@ -55,10 +59,6 @@ bool LibcxxWStringViewSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libc++ std::wstring_view -bool LibcxxOptionalSummaryProvider( - ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &options); // libc++ std::optional<> - bool LibcxxSmartPointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions @@ -200,6 +200,7 @@ public: private: lldb::ValueObjectSP m_value_ptr_sp; + lldb::ValueObjectSP m_deleter_sp; }; SyntheticChildrenFrontEnd * 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 4eec79a27840..eacc60886c6e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp @@ -55,13 +55,12 @@ lldb_private::formatters::GetLibCxxAtomicValue(ValueObject &valobj) { if (!non_sythetic) return {}; - ValueObjectSP member__a_ = - non_sythetic->GetChildMemberWithName(ConstString("__a_"), true); + ValueObjectSP member__a_ = non_sythetic->GetChildMemberWithName("__a_"); if (!member__a_) return {}; ValueObjectSP member__a_value = - member__a_->GetChildMemberWithName(ConstString("__a_value"), true); + member__a_->GetChildMemberWithName("__a_value"); if (!member__a_value) return member__a_; @@ -139,7 +138,7 @@ lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd::GetChildAtIndex( size_t lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: GetIndexOfChildWithName(ConstString name) { - return formatters::ExtractIndexFromString(name.GetCString()); + return name == "Value" ? 0 : UINT32_MAX; } SyntheticChildrenFrontEnd * 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 fbea4ec01717..bfd7b881a728 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -61,9 +61,8 @@ lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: size_t lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: CalculateNumChildren() { - static ConstString g_size_("__size_"); m_num_elements = 0; - ValueObjectSP size_sp(m_backend.GetChildMemberWithName(g_size_, true)); + ValueObjectSP size_sp(m_backend.GetChildMemberWithName("__size_")); if (size_sp) m_num_elements = size_sp->GetValueAsUnsigned(0); return m_num_elements; @@ -85,8 +84,6 @@ lldb::ValueObjectSP lldb_private::formatters:: bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: Update() { - static ConstString g_begin_("__begin_"); - m_start = nullptr; m_num_elements = 0; m_element_type = m_backend.GetCompilerType().GetTypeTemplateArgument(0); @@ -96,7 +93,7 @@ bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: if (std::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("__begin_").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 a1953a1c7a22..2e2e2a8b0515 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -32,19 +32,15 @@ public: : m_entry_sp(entry ? entry->GetSP() : ValueObjectSP()) {} ListEntry next() { - static ConstString g_next("__next_"); - if (!m_entry_sp) return ListEntry(); - return ListEntry(m_entry_sp->GetChildMemberWithName(g_next, true)); + return ListEntry(m_entry_sp->GetChildMemberWithName("__next_")); } ListEntry prev() { - static ConstString g_prev("__prev_"); - if (!m_entry_sp) return ListEntry(); - return ListEntry(m_entry_sp->GetChildMemberWithName(g_prev, true)); + return ListEntry(m_entry_sp->GetChildMemberWithName("__prev_")); } uint64_t value() const { @@ -271,7 +267,7 @@ ValueObjectSP ForwardListFrontEnd::GetChildAtIndex(size_t idx) { if (!current_sp) return nullptr; - current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child + current_sp = current_sp->GetChildAtIndex(1); // get the __value_ child if (!current_sp) return nullptr; @@ -296,14 +292,13 @@ bool ForwardListFrontEnd::Update() { if (err.Fail() || !backend_addr) return false; - ValueObjectSP impl_sp( - m_backend.GetChildMemberWithName(ConstString("__before_begin_"), true)); + ValueObjectSP impl_sp(m_backend.GetChildMemberWithName("__before_begin_")); if (!impl_sp) return false; - impl_sp = GetValueOfLibCXXCompressedPair(*impl_sp); + impl_sp = GetFirstValueOfLibCXXCompressedPair(*impl_sp); if (!impl_sp) return false; - m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); + m_head = impl_sp->GetChildMemberWithName("__next_").get(); return false; } @@ -318,10 +313,9 @@ size_t ListFrontEnd::CalculateNumChildren() { return m_count; if (!m_head || !m_tail || m_node_address == 0) return 0; - ValueObjectSP size_alloc( - m_backend.GetChildMemberWithName(ConstString("__size_alloc_"), true)); + ValueObjectSP size_alloc(m_backend.GetChildMemberWithName("__size_alloc_")); if (size_alloc) { - ValueObjectSP value = GetValueOfLibCXXCompressedPair(*size_alloc); + ValueObjectSP value = GetFirstValueOfLibCXXCompressedPair(*size_alloc); if (value) { m_count = value->GetValueAsUnsigned(UINT32_MAX); } @@ -366,7 +360,7 @@ lldb::ValueObjectSP ListFrontEnd::GetChildAtIndex(size_t idx) { if (!current_sp) return lldb::ValueObjectSP(); - current_sp = current_sp->GetChildAtIndex(1, true); // get the __value_ child + current_sp = current_sp->GetChildAtIndex(1); // get the __value_ child if (!current_sp) return lldb::ValueObjectSP(); @@ -412,12 +406,11 @@ bool ListFrontEnd::Update() { m_node_address = backend_addr->GetValueAsUnsigned(0); if (!m_node_address || m_node_address == LLDB_INVALID_ADDRESS) return false; - ValueObjectSP impl_sp( - m_backend.GetChildMemberWithName(ConstString("__end_"), true)); + ValueObjectSP impl_sp(m_backend.GetChildMemberWithName("__end_")); if (!impl_sp) return false; - m_head = impl_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); - m_tail = impl_sp->GetChildMemberWithName(ConstString("__prev_"), true).get(); + m_head = impl_sp->GetChildMemberWithName("__next_").get(); + m_tail = impl_sp->GetChildMemberWithName("__prev_").get(); return false; } 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 bf6c65c8d9c2..092a4120376b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -211,27 +211,23 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: CalculateNumChildren() { - 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("__pair3_")); 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("__first_"); 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); + ValueObjectSP first_elem_parent = m_item->GetChildAtIndex(0); + m_item = first_elem_parent->GetChildMemberWithName("__value_"); break; } default: @@ -245,10 +241,6 @@ size_t lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd:: } bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() { - static ConstString g_value_("__value_"); - static ConstString g_tree_("__tree_"); - static ConstString g_pair3("__pair3_"); - if (m_element_type.IsValid()) return true; m_element_type.Clear(); @@ -257,12 +249,12 @@ 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("__value_"); if (deref) { m_element_type = deref->GetCompilerType(); return true; } - deref = m_backend.GetChildAtNamePath({g_tree_, g_pair3}); + deref = m_backend.GetChildAtNamePath({"__tree_", "__pair3_"}); if (!deref) return false; m_element_type = deref->GetCompilerType() @@ -299,7 +291,7 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset( if (!ast_ctx) return; CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( - ConstString(), + llvm::StringRef(), {{"ptr0", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, {"ptr1", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, {"ptr2", ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, @@ -329,7 +321,6 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( size_t idx) { static ConstString g_cc_("__cc_"), g_cc("__cc"); static ConstString g_nc("__nc"); - static ConstString g_value_("__value_"); if (idx >= CalculateNumChildren()) return lldb::ValueObjectSP(); @@ -364,7 +355,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("__value_"); if (child_sp) iterated_sp = child_sp; else @@ -397,30 +388,21 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( // at this point we have a valid // we need to copy current_sp into a new object otherwise we will end up with // all items named __value_ - DataExtractor data; - Status error; - iterated_sp->GetData(data, error); - if (error.Fail()) { - m_tree = nullptr; - return lldb::ValueObjectSP(); - } StreamString name; name.Printf("[%" PRIu64 "]", (uint64_t)idx); - auto potential_child_sp = CreateValueObjectFromData( - name.GetString(), data, m_backend.GetExecutionContextRef(), - m_element_type); + auto potential_child_sp = iterated_sp->Clone(ConstString(name.GetString())); if (potential_child_sp) { switch (potential_child_sp->GetNumChildren()) { case 1: { - auto child0_sp = potential_child_sp->GetChildAtIndex(0, true); + auto child0_sp = potential_child_sp->GetChildAtIndex(0); if (child0_sp && (child0_sp->GetName() == g_cc_ || 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); + auto child0_sp = potential_child_sp->GetChildAtIndex(0); + auto child1_sp = potential_child_sp->GetChildAtIndex(1); if (child0_sp && (child0_sp->GetName() == g_cc_ || child0_sp->GetName() == g_cc) && child1_sp && child1_sp->GetName() == g_nc) @@ -434,15 +416,13 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex( } bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::Update() { - 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("__tree_").get(); if (!m_tree) return false; - m_root_node = m_tree->GetChildMemberWithName(g_begin_node_, true).get(); + m_root_node = m_tree->GetChildMemberWithName("__begin_node_").get(); return false; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp index 616ffdca107d..c31940af0881 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxQueue.cpp @@ -33,7 +33,7 @@ public: } ValueObjectSP GetChildAtIndex(size_t idx) override { - return m_container_sp ? m_container_sp->GetChildAtIndex(idx, true) + return m_container_sp ? m_container_sp->GetChildAtIndex(idx) : nullptr; } @@ -49,7 +49,7 @@ private: bool QueueFrontEnd::Update() { m_container_sp = nullptr; - ValueObjectSP c_sp = m_backend.GetChildMemberWithName(ConstString("c"), true); + ValueObjectSP c_sp = m_backend.GetChildMemberWithName("c"); if (!c_sp) return false; m_container_sp = c_sp->GetSyntheticValue().get(); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp index a113fe98c6b6..9024ed4dba45 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxTuple.cpp @@ -45,10 +45,10 @@ bool TupleFrontEnd::Update() { m_base = nullptr; ValueObjectSP base_sp; - base_sp = m_backend.GetChildMemberWithName(ConstString("__base_"), true); + base_sp = m_backend.GetChildMemberWithName("__base_"); if (!base_sp) { // Pre r304382 name of the base element. - base_sp = m_backend.GetChildMemberWithName(ConstString("base_"), true); + base_sp = m_backend.GetChildMemberWithName("base_"); } if (!base_sp) return false; @@ -70,11 +70,11 @@ ValueObjectSP TupleFrontEnd::GetChildAtIndex(size_t idx) { m_base->GetCompilerType().GetDirectBaseClassAtIndex(idx, nullptr); if (!holder_type) return ValueObjectSP(); - ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx, true); + ValueObjectSP holder_sp = m_base->GetChildAtIndex(idx); if (!holder_sp) return ValueObjectSP(); - ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0, true); + ValueObjectSP elem_sp = holder_sp->GetChildAtIndex(0); if (elem_sp) m_elements[idx] = elem_sp->Clone(ConstString(llvm::formatv("[{0}]", idx).str())).get(); 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 cba1078d05d7..14776cdf8081 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -108,14 +108,11 @@ lldb::ValueObjectSP lldb_private::formatters:: if (!node_sp || error.Fail()) return lldb::ValueObjectSP(); - ValueObjectSP value_sp = - node_sp->GetChildMemberWithName(ConstString("__value_"), true); - ValueObjectSP hash_sp = - node_sp->GetChildMemberWithName(ConstString("__hash_"), true); + ValueObjectSP value_sp = node_sp->GetChildMemberWithName("__value_"); + ValueObjectSP hash_sp = node_sp->GetChildMemberWithName("__hash_"); if (!hash_sp || !value_sp) { if (!m_element_type) { - auto p1_sp = m_backend.GetChildAtNamePath({ConstString("__table_"), - ConstString("__p1_")}); + auto p1_sp = m_backend.GetChildAtNamePath({"__table_", "__p1_"}); if (!p1_sp) return nullptr; @@ -123,15 +120,13 @@ lldb::ValueObjectSP lldb_private::formatters:: switch (p1_sp->GetCompilerType().GetNumDirectBaseClasses()) { case 1: // Assume a pre llvm r300140 __compressed_pair implementation: - first_sp = p1_sp->GetChildMemberWithName(ConstString("__first_"), - true); + first_sp = p1_sp->GetChildMemberWithName("__first_"); break; case 2: { // Assume a post llvm r300140 __compressed_pair implementation: ValueObjectSP first_elem_parent_sp = - p1_sp->GetChildAtIndex(0, true); - first_sp = p1_sp->GetChildMemberWithName(ConstString("__value_"), - true); + p1_sp->GetChildAtIndex(0); + first_sp = p1_sp->GetChildMemberWithName("__value_"); break; } default: @@ -162,16 +157,19 @@ lldb::ValueObjectSP lldb_private::formatters:: } if (!m_node_type) return nullptr; - node_sp = node_sp->Cast(m_node_type); - value_sp = node_sp->GetChildMemberWithName(ConstString("__value_"), true); - hash_sp = node_sp->GetChildMemberWithName(ConstString("__hash_"), true); + node_sp = m_next_element->Cast(m_node_type.GetPointerType()) + ->Dereference(error); + if (!node_sp || error.Fail()) + return nullptr; + + value_sp = node_sp->GetChildMemberWithName("__value_"); + hash_sp = node_sp->GetChildMemberWithName("__hash_"); if (!value_sp || !hash_sp) return nullptr; } m_elements_cache.push_back( {value_sp.get(), hash_sp->GetValueAsUnsigned(0)}); - m_next_element = - node_sp->GetChildMemberWithName(ConstString("__next_"), true).get(); + m_next_element = node_sp->GetChildMemberWithName("__next_").get(); if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0) m_next_element = nullptr; } @@ -198,30 +196,24 @@ bool lldb_private::formatters::LibcxxStdUnorderedMapSyntheticFrontEnd:: m_num_elements = 0; m_next_element = nullptr; m_elements_cache.clear(); - ValueObjectSP table_sp = - m_backend.GetChildMemberWithName(ConstString("__table_"), true); + ValueObjectSP table_sp = m_backend.GetChildMemberWithName("__table_"); if (!table_sp) return false; - ValueObjectSP p2_sp = table_sp->GetChildMemberWithName( - ConstString("__p2_"), true); + ValueObjectSP p2_sp = table_sp->GetChildMemberWithName("__p2_"); ValueObjectSP num_elements_sp = nullptr; - llvm::SmallVector<ConstString, 3> next_path; + llvm::SmallVector<llvm::StringRef, 3> next_path; switch (p2_sp->GetCompilerType().GetNumDirectBaseClasses()) { case 1: // Assume a pre llvm r300140 __compressed_pair implementation: - num_elements_sp = p2_sp->GetChildMemberWithName( - ConstString("__first_"), true); - next_path.append({ConstString("__p1_"), ConstString("__first_"), - ConstString("__next_")}); + num_elements_sp = p2_sp->GetChildMemberWithName("__first_"); + next_path.append({"__p1_", "__first_", "__next_"}); break; case 2: { // Assume a post llvm r300140 __compressed_pair implementation: - ValueObjectSP first_elem_parent = p2_sp->GetChildAtIndex(0, true); - num_elements_sp = first_elem_parent->GetChildMemberWithName( - ConstString("__value_"), true); - next_path.append({ConstString("__p1_"), ConstString("__value_"), - ConstString("__next_")}); + ValueObjectSP first_elem_parent = p2_sp->GetChildAtIndex(0); + num_elements_sp = first_elem_parent->GetChildMemberWithName("__value_"); + next_path.append({"__p1_", "__value_", "__next_"}); break; } default: diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp index 4e54e7b5b7fa..e863ccca2be8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp @@ -83,8 +83,7 @@ uint64_t VariantNposValue(uint64_t index_byte_size) { LibcxxVariantIndexValidity LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) { - ValueObjectSP index_sp( - impl_sp->GetChildMemberWithName(ConstString("__index"), true)); + ValueObjectSP index_sp(impl_sp->GetChildMemberWithName("__index")); if (!index_sp) return LibcxxVariantIndexValidity::Invalid; @@ -112,8 +111,7 @@ LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) { } std::optional<uint64_t> LibcxxVariantIndexValue(ValueObjectSP &impl_sp) { - ValueObjectSP index_sp( - impl_sp->GetChildMemberWithName(ConstString("__index"), true)); + ValueObjectSP index_sp(impl_sp->GetChildMemberWithName("__index")); if (!index_sp) return {}; @@ -122,16 +120,14 @@ std::optional<uint64_t> LibcxxVariantIndexValue(ValueObjectSP &impl_sp) { } ValueObjectSP LibcxxVariantGetNthHead(ValueObjectSP &impl_sp, uint64_t index) { - ValueObjectSP data_sp( - impl_sp->GetChildMemberWithName(ConstString("__data"), true)); + ValueObjectSP data_sp(impl_sp->GetChildMemberWithName("__data")); if (!data_sp) return ValueObjectSP{}; ValueObjectSP current_level = data_sp; for (uint64_t n = index; n != 0; --n) { - ValueObjectSP tail_sp( - current_level->GetChildMemberWithName(ConstString("__tail"), true)); + ValueObjectSP tail_sp(current_level->GetChildMemberWithName("__tail")); if (!tail_sp) return ValueObjectSP{}; @@ -139,7 +135,7 @@ ValueObjectSP LibcxxVariantGetNthHead(ValueObjectSP &impl_sp, uint64_t index) { current_level = tail_sp; } - return current_level->GetChildMemberWithName(ConstString("__head"), true); + return current_level->GetChildMemberWithName("__head"); } } // namespace @@ -268,8 +264,7 @@ ValueObjectSP VariantFrontEnd::GetChildAtIndex(size_t idx) { if (!template_type) return {}; - ValueObjectSP head_value( - nth_head->GetChildMemberWithName(ConstString("__value"), true)); + ValueObjectSP head_value(nth_head->GetChildMemberWithName("__value")); if (!head_value) return {}; 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 218ff9cd4741..db7cc5bce26e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -119,22 +119,22 @@ lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::GetChildAtIndex( bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() { m_start = m_finish = nullptr; ValueObjectSP data_type_finder_sp( - m_backend.GetChildMemberWithName(ConstString("__end_cap_"), true)); + m_backend.GetChildMemberWithName("__end_cap_")); if (!data_type_finder_sp) return false; switch (data_type_finder_sp->GetCompilerType().GetNumDirectBaseClasses()) { case 1: // Assume a pre llvm r300140 __compressed_pair implementation: - data_type_finder_sp = data_type_finder_sp->GetChildMemberWithName( - ConstString("__first_"), true); + data_type_finder_sp = + data_type_finder_sp->GetChildMemberWithName("__first_"); break; case 2: { // Assume a post llvm r300140 __compressed_pair implementation: ValueObjectSP first_elem_parent_sp = - data_type_finder_sp->GetChildAtIndex(0, true); - data_type_finder_sp = first_elem_parent_sp->GetChildMemberWithName( - ConstString("__value_"), true); + data_type_finder_sp->GetChildAtIndex(0); + data_type_finder_sp = + first_elem_parent_sp->GetChildMemberWithName("__value_"); break; } default: @@ -149,10 +149,8 @@ bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() { if (m_element_size > 0) { // store raw pointers or end up with a circular dependency - m_start = - m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get(); - m_finish = - m_backend.GetChildMemberWithName(ConstString("__end_"), true).get(); + m_start = m_backend.GetChildMemberWithName("__begin_").get(); + m_finish = m_backend.GetChildMemberWithName("__end_").get(); } } return false; @@ -249,15 +247,13 @@ bool lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::Update() { if (!valobj_sp) return false; m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); - ValueObjectSP size_sp( - valobj_sp->GetChildMemberWithName(ConstString("__size_"), true)); + ValueObjectSP size_sp(valobj_sp->GetChildMemberWithName("__size_")); if (!size_sp) return false; m_count = size_sp->GetValueAsUnsigned(0); if (!m_count) return true; - ValueObjectSP begin_sp( - valobj_sp->GetChildMemberWithName(ConstString("__begin_"), true)); + ValueObjectSP begin_sp(valobj_sp->GetChildMemberWithName("__begin_")); if (!begin_sp) { m_count = 0; return false; 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 90976fa053b8..c65bb9b6bc9b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -73,6 +73,15 @@ public: bool MightHaveChildren() override; size_t GetIndexOfChildWithName(ConstString name) override; +private: + + // The lifetime of a ValueObject and all its derivative ValueObjects + // (children, clones, etc.) is managed by a ClusterManager. These + // objects are only destroyed when every shared pointer to any of them + // is destroyed, so we must not store a shared pointer to any ValueObject + // derived from our backend ValueObject (since we're in the same cluster). + ValueObject* m_ptr_obj = nullptr; // Underlying pointer (held, not owned) + ValueObject* m_obj_obj = nullptr; // Underlying object (held, not owned) }; } // end of anonymous namespace @@ -101,8 +110,7 @@ bool LibstdcppMapIteratorSyntheticFrontEnd::Update() { return false; m_exe_ctx_ref = valobj_sp->GetExecutionContextRef(); - ValueObjectSP _M_node_sp( - valobj_sp->GetChildMemberWithName(ConstString("_M_node"), true)); + ValueObjectSP _M_node_sp(valobj_sp->GetChildMemberWithName("_M_node")); if (!_M_node_sp) return false; @@ -135,7 +143,7 @@ LibstdcppMapIteratorSyntheticFrontEnd::GetChildAtIndex(size_t idx) { m_pair_sp = CreateValueObjectFromAddress("pair", m_pair_address, m_exe_ctx_ref, m_pair_type); if (m_pair_sp) - return m_pair_sp->GetChildAtIndex(idx, true); + return m_pair_sp->GetChildAtIndex(idx); } return lldb::ValueObjectSP(); } @@ -233,8 +241,15 @@ bool lldb_private::formatters::LibStdcppStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { const bool scalar_is_load_addr = true; AddressType addr_type; - lldb::addr_t addr_of_string = - valobj.GetAddressOf(scalar_is_load_addr, &addr_type); + lldb::addr_t addr_of_string = LLDB_INVALID_ADDRESS; + if (valobj.IsPointerOrReferenceType()) { + Status error; + ValueObjectSP pointee_sp = valobj.Dereference(error); + if (pointee_sp && error.Success()) + addr_of_string = pointee_sp->GetAddressOf(scalar_is_load_addr, &addr_type); + } else + addr_of_string = + valobj.GetAddressOf(scalar_is_load_addr, &addr_type); if (addr_of_string != LLDB_INVALID_ADDRESS) { switch (addr_type) { case eAddressTypeLoad: { @@ -360,24 +375,48 @@ size_t LibStdcppSharedPtrSyntheticFrontEnd::CalculateNumChildren() { return 1; } lldb::ValueObjectSP LibStdcppSharedPtrSyntheticFrontEnd::GetChildAtIndex(size_t idx) { - ValueObjectSP valobj_sp = m_backend.GetSP(); - if (!valobj_sp) - return lldb::ValueObjectSP(); - if (idx == 0) - return valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true); - else - return lldb::ValueObjectSP(); + return m_ptr_obj->GetSP(); + if (idx == 1) + return m_obj_obj->GetSP(); + + return lldb::ValueObjectSP(); } -bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { return false; } +bool LibStdcppSharedPtrSyntheticFrontEnd::Update() { + auto backend = m_backend.GetSP(); + if (!backend) + return false; + + auto valobj_sp = backend->GetNonSyntheticValue(); + if (!valobj_sp) + return false; + + auto ptr_obj_sp = valobj_sp->GetChildMemberWithName("_M_ptr"); + if (!ptr_obj_sp) + return false; + + m_ptr_obj = ptr_obj_sp->Clone(ConstString("pointer")).get(); + + if (m_ptr_obj) { + Status error; + ValueObjectSP obj_obj = m_ptr_obj->Dereference(error); + if (error.Success()) { + m_obj_obj = obj_obj->Clone(ConstString("object")).get(); + } + } + + return false; +} bool LibStdcppSharedPtrSyntheticFrontEnd::MightHaveChildren() { return true; } size_t LibStdcppSharedPtrSyntheticFrontEnd::GetIndexOfChildWithName( ConstString name) { - if (name == "_M_ptr") + if (name == "pointer") return 0; + if (name == "object" || name == "$$dereference$$") + return 1; return UINT32_MAX; } @@ -394,14 +433,12 @@ bool lldb_private::formatters::LibStdcppSmartPointerSummaryProvider( if (!valobj_sp) return false; - ValueObjectSP ptr_sp( - valobj_sp->GetChildMemberWithName(ConstString("_M_ptr"), true)); + ValueObjectSP ptr_sp(valobj_sp->GetChildMemberWithName("_M_ptr")); if (!ptr_sp) return false; - ValueObjectSP usecount_sp(valobj_sp->GetChildAtNamePath( - {ConstString("_M_refcount"), ConstString("_M_pi"), - ConstString("_M_use_count")})); + ValueObjectSP usecount_sp( + valobj_sp->GetChildAtNamePath({"_M_refcount", "_M_pi", "_M_use_count"})); if (!usecount_sp) return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp index 7ba59ff9d1ad..aef7cbac603f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppTuple.cpp @@ -67,13 +67,13 @@ bool LibStdcppTupleSyntheticFrontEnd::Update() { size_t child_count = current_child->GetNumChildren(); for (size_t i = 0; i < child_count; ++i) { - ValueObjectSP child_sp = current_child->GetChildAtIndex(i, true); + ValueObjectSP child_sp = current_child->GetChildAtIndex(i); llvm::StringRef name_str = child_sp->GetName().GetStringRef(); if (name_str.startswith("std::_Tuple_impl<")) { next_child_sp = child_sp; } else if (name_str.startswith("std::_Head_base<")) { ValueObjectSP value_sp = - child_sp->GetChildMemberWithName(ConstString("_M_head_impl"), true); + child_sp->GetChildMemberWithName("_M_head_impl"); if (value_sp) { StreamString name; name.Printf("[%zd]", m_members.size()); diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp index 79e864a2cbd5..7174e9102e1b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp @@ -69,13 +69,11 @@ ValueObjectSP LibStdcppUniquePtrSyntheticFrontEnd::GetTuple() { if (!valobj_sp) return nullptr; - ValueObjectSP obj_child_sp = - valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true); + ValueObjectSP obj_child_sp = valobj_sp->GetChildMemberWithName("_M_t"); if (!obj_child_sp) return nullptr; - ValueObjectSP obj_subchild_sp = - obj_child_sp->GetChildMemberWithName(ConstString("_M_t"), true); + ValueObjectSP obj_subchild_sp = obj_child_sp->GetChildMemberWithName("_M_t"); // if there is a _M_t subchild, the tuple is found in the obj_subchild_sp // (for libstdc++ 6.0.23). diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp index 6b78ce5de697..6e56e29f8c31 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp @@ -23,7 +23,7 @@ using namespace lldb_private; bool ClangHighlighter::isKeyword(llvm::StringRef token) const { - return keywords.find(token) != keywords.end(); + return keywords.contains(token); } ClangHighlighter::ClangHighlighter() { 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 fa2130e4b01e..0926192a4f38 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/CF.cpp @@ -44,7 +44,7 @@ bool lldb_private::formatters::CFAbsoluteTimeSummaryProvider( bool lldb_private::formatters::CFBagSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - static ConstString g_TypeHint("CFBag"); + static constexpr llvm::StringLiteral g_TypeHint("CFBag"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) @@ -92,17 +92,13 @@ bool lldb_private::formatters::CFBagSummaryProvider( } else return false; - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(options.GetLanguage())) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(options.GetLanguage())) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s\"%u value%s\"%s", prefix.c_str(), count, - (count == 1 ? "" : "s"), suffix.c_str()); + stream << prefix; + stream.Printf("\"%u value%s\"", count, (count == 1 ? "" : "s")); + stream << suffix; return true; } @@ -226,7 +222,7 @@ bool lldb_private::formatters::CFBitVectorSummaryProvider( bool lldb_private::formatters::CFBinaryHeapSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - static ConstString g_TypeHint("CFBinaryHeap"); + static constexpr llvm::StringLiteral g_TypeHint("CFBinaryHeap"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) @@ -279,16 +275,12 @@ bool lldb_private::formatters::CFBinaryHeapSummaryProvider( } else return false; - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(options.GetLanguage())) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(options.GetLanguage())) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s\"%u item%s\"%s", prefix.c_str(), count, - (count == 1 ? "" : "s"), suffix.c_str()); + stream << prefix; + stream.Printf("\"%u item%s\"", count, (count == 1 ? "" : "s")); + stream << suffix; return true; } 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 46f82daaff8d..374ac763ab18 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -21,7 +21,6 @@ #include "lldb/Host/Time.h" #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" -#include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" @@ -305,120 +304,97 @@ bool lldb_private::formatters::NSIndexSetSummaryProvider( static void NSNumber_FormatChar(ValueObject &valobj, Stream &stream, char value, lldb::LanguageType lang) { - static ConstString g_TypeHint("NSNumber:char"); - - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(lang)) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + static constexpr llvm::StringLiteral g_TypeHint("NSNumber:char"); + + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(lang)) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%hhd%s", prefix.c_str(), value, suffix.c_str()); + stream << prefix; + stream.Printf("%hhd", value); + stream << suffix; } static void NSNumber_FormatShort(ValueObject &valobj, Stream &stream, short value, lldb::LanguageType lang) { - static ConstString g_TypeHint("NSNumber:short"); - - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(lang)) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + static constexpr llvm::StringLiteral g_TypeHint("NSNumber:short"); + + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(lang)) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%hd%s", prefix.c_str(), value, suffix.c_str()); + stream << prefix; + stream.Printf("%hd", value); + stream << suffix; } static void NSNumber_FormatInt(ValueObject &valobj, Stream &stream, int value, lldb::LanguageType lang) { - static ConstString g_TypeHint("NSNumber:int"); - - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(lang)) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + static constexpr llvm::StringLiteral g_TypeHint("NSNumber:int"); + + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(lang)) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%d%s", prefix.c_str(), value, suffix.c_str()); + stream << prefix; + stream.Printf("%d", value); + stream << suffix; } static void NSNumber_FormatLong(ValueObject &valobj, Stream &stream, int64_t value, lldb::LanguageType lang) { - static ConstString g_TypeHint("NSNumber:long"); - - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(lang)) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + static constexpr llvm::StringLiteral g_TypeHint("NSNumber:long"); + + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(lang)) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%" PRId64 "%s", prefix.c_str(), value, suffix.c_str()); + stream << prefix; + stream.Printf("%" PRId64 "", value); + stream << suffix; } static void NSNumber_FormatInt128(ValueObject &valobj, Stream &stream, const llvm::APInt &value, lldb::LanguageType lang) { - static ConstString g_TypeHint("NSNumber:int128_t"); - - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(lang)) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + static constexpr llvm::StringLiteral g_TypeHint("NSNumber:int128_t"); + + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(lang)) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.PutCString(prefix.c_str()); + stream << prefix; const int radix = 10; const bool isSigned = true; std::string str = llvm::toString(value, radix, isSigned); stream.PutCString(str.c_str()); - stream.PutCString(suffix.c_str()); + stream << suffix; } static void NSNumber_FormatFloat(ValueObject &valobj, Stream &stream, float value, lldb::LanguageType lang) { - static ConstString g_TypeHint("NSNumber:float"); - - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(lang)) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + static constexpr llvm::StringLiteral g_TypeHint("NSNumber:float"); + + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(lang)) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%f%s", prefix.c_str(), value, suffix.c_str()); + stream << prefix; + stream.Printf("%f", value); + stream << suffix; } static void NSNumber_FormatDouble(ValueObject &valobj, Stream &stream, double value, lldb::LanguageType lang) { - static ConstString g_TypeHint("NSNumber:double"); - - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(lang)) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + static constexpr llvm::StringLiteral g_TypeHint("NSNumber:double"); + + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(lang)) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%g%s", prefix.c_str(), value, suffix.c_str()); + stream << prefix; + stream.Printf("%g", value); + stream << suffix; } bool lldb_private::formatters::NSNumberSummaryProvider( @@ -813,29 +789,27 @@ bool lldb_private::formatters::NSURLSummaryProvider( if (!NSStringSummaryProvider(*text, summary, options) || summary.Empty()) return false; - const char quote_char = '"'; - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(options.GetLanguage())) { - if (!language->GetFormatterPrefixSuffix(*text, ConstString("NSString"), - prefix, suffix)) { - prefix.clear(); - suffix.clear(); - } - } + static constexpr llvm::StringLiteral quote_char("\""); + static constexpr llvm::StringLiteral g_TypeHint("NSString"); + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(options.GetLanguage())) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); + // @"A" -> @"A llvm::StringRef summary_str = summary.GetString(); - bool back_consumed = summary_str.consume_back(quote_char + suffix); + bool back_consumed = + summary_str.consume_back(suffix) && summary_str.consume_back(quote_char); assert(back_consumed); UNUSED_IF_ASSERT_DISABLED(back_consumed); // @"B" -> B" llvm::StringRef base_summary_str = base_summary.GetString(); - bool front_consumed = base_summary_str.consume_front(prefix + quote_char); + bool front_consumed = base_summary_str.consume_front(prefix) && + base_summary_str.consume_front(quote_char); assert(front_consumed); UNUSED_IF_ASSERT_DISABLED(front_consumed); // @"A -- B" if (!summary_str.empty() && !base_summary_str.empty()) { - stream.Printf("%s -- %s", summary_str.str().c_str(), - base_summary_str.str().c_str()); + stream << summary_str << " -- " << base_summary_str; return true; } @@ -1124,7 +1098,7 @@ bool lldb_private::formatters::ObjCBOOLSummaryProvider( if (err.Fail() || !real_guy_sp) return false; } else if (type_info & eTypeIsReference) { - real_guy_sp = valobj.GetChildAtIndex(0, true); + real_guy_sp = valobj.GetChildAtIndex(0); if (!real_guy_sp) return false; } 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 18bb2b8c4fdc..bd356a61161a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSArray.cpp @@ -334,7 +334,7 @@ public: bool lldb_private::formatters::NSArraySummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - static ConstString g_TypeHint("NSArray"); + static constexpr llvm::StringLiteral g_TypeHint("NSArray"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) @@ -445,17 +445,13 @@ bool lldb_private::formatters::NSArraySummaryProvider( return false; } - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(options.GetLanguage())) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(options.GetLanguage())) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element", - value == 1 ? "" : "s", suffix.c_str()); + stream << prefix; + stream.Printf("%" PRIu64 " %s%s", value, "element", value == 1 ? "" : "s"); + stream << suffix; return true; } 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 4bab8924f3a5..2e927eb8d856 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -65,32 +65,30 @@ NSDictionary_Additionals::GetAdditionalSynthetics() { static CompilerType GetLLDBNSPairType(TargetSP target_sp) { CompilerType compiler_type; - TypeSystemClangSP scratch_ts_sp = ScratchTypeSystemClang::GetForTarget(*target_sp); - if (scratch_ts_sp) { - ConstString g_lldb_autogen_nspair("__lldb_autogen_nspair"); - - compiler_type = scratch_ts_sp->GetTypeForIdentifier<clang::CXXRecordDecl>( - g_lldb_autogen_nspair); - - if (!compiler_type) { - compiler_type = scratch_ts_sp->CreateRecordType( - nullptr, OptionalClangModuleID(), lldb::eAccessPublic, - g_lldb_autogen_nspair.GetCString(), clang::TTK_Struct, - lldb::eLanguageTypeC); - - if (compiler_type) { - TypeSystemClang::StartTagDeclarationDefinition(compiler_type); - CompilerType id_compiler_type = - scratch_ts_sp->GetBasicType(eBasicTypeObjCID); - TypeSystemClang::AddFieldToRecordType( - compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0); - TypeSystemClang::AddFieldToRecordType( - compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0); - TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); - } + if (!scratch_ts_sp) + return compiler_type; + + static constexpr llvm::StringLiteral g_lldb_autogen_nspair("__lldb_autogen_nspair"); + + compiler_type = scratch_ts_sp->GetTypeForIdentifier<clang::CXXRecordDecl>(g_lldb_autogen_nspair); + + if (!compiler_type) { + compiler_type = scratch_ts_sp->CreateRecordType( + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, + g_lldb_autogen_nspair, clang::TTK_Struct, lldb::eLanguageTypeC); + + if (compiler_type) { + TypeSystemClang::StartTagDeclarationDefinition(compiler_type); + CompilerType id_compiler_type = + scratch_ts_sp->GetBasicType(eBasicTypeObjCID); + TypeSystemClang::AddFieldToRecordType( + compiler_type, "key", id_compiler_type, lldb::eAccessPublic, 0); + TypeSystemClang::AddFieldToRecordType( + compiler_type, "value", id_compiler_type, lldb::eAccessPublic, 0); + TypeSystemClang::CompleteTagDeclarationDefinition(compiler_type); } } return compiler_type; @@ -409,7 +407,7 @@ namespace Foundation1437 { template <bool name_entries> bool lldb_private::formatters::NSDictionarySummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - static ConstString g_TypeHint("NSDictionary"); + static constexpr llvm::StringLiteral g_TypeHint("NSDictionary"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; @@ -501,17 +499,14 @@ bool lldb_private::formatters::NSDictionarySummaryProvider( return false; } - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(options.GetLanguage())) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(options.GetLanguage())) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "key/value pair", - value == 1 ? "" : "s", suffix.c_str()); + stream << prefix; + stream.Printf("%" PRIu64 " %s%s", value, "key/value pair", + value == 1 ? "" : "s"); + stream << suffix; return true; } 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 c267089f763d..99eeb2d5092f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSError.cpp @@ -14,7 +14,6 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" 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 875a30c11877..29805bb2d5fe 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSException.cpp @@ -13,7 +13,6 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Target/ProcessStructReader.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" 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 fac8594d0c7d..44097ee0c42b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSSet.cpp @@ -249,7 +249,7 @@ public: template <bool cf_style> bool lldb_private::formatters::NSSetSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - static ConstString g_TypeHint("NSSet"); + static constexpr llvm::StringLiteral g_TypeHint("NSSet"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) @@ -322,17 +322,13 @@ bool lldb_private::formatters::NSSetSummaryProvider( return false; } - std::string prefix, suffix; - if (Language *language = Language::FindPlugin(options.GetLanguage())) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(options.GetLanguage())) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); - stream.Printf("%s%" PRIu64 " %s%s%s", prefix.c_str(), value, "element", - value == 1 ? "" : "s", suffix.c_str()); + stream << prefix; + stream.Printf("%" PRIu64 " %s%s", value, "element", value == 1 ? "" : "s"); + stream << suffix; return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp index 61705c866778..0a30737d9723 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/NSString.cpp @@ -33,7 +33,7 @@ NSString_Additionals::GetAdditionalSummaries() { bool lldb_private::formatters::NSStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &summary_options) { - static ConstString g_TypeHint("NSString"); + static constexpr llvm::StringLiteral g_TypeHint("NSString"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) @@ -126,19 +126,13 @@ bool lldb_private::formatters::NSStringSummaryProvider( return true; } - std::string prefix, suffix; - if (Language *language = - Language::FindPlugin(summary_options.GetLanguage())) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(summary_options.GetLanguage())) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); - options.SetPrefixToken(prefix); - options.SetSuffixToken(suffix); + options.SetPrefixToken(prefix.str()); + options.SetSuffixToken(suffix.str()); if (is_mutable) { uint64_t location = 2 * ptr_size + valobj_addr; @@ -318,7 +312,7 @@ bool lldb_private::formatters::NSMutableAttributedStringSummaryProvider( bool lldb_private::formatters::NSTaggedString_SummaryProvider( ValueObject &valobj, ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream &stream, const TypeSummaryOptions &summary_options) { - static ConstString g_TypeHint("NSString"); + static constexpr llvm::StringLiteral g_TypeHint("NSString"); if (!descriptor) return false; @@ -336,23 +330,17 @@ bool lldb_private::formatters::NSTaggedString_SummaryProvider( if (len_bits > g_fiveBitMaxLen) return false; - std::string prefix, suffix; - if (Language *language = - Language::FindPlugin(summary_options.GetLanguage())) { - if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, - suffix)) { - prefix.clear(); - suffix.clear(); - } - } + llvm::StringRef prefix, suffix; + if (Language *language = Language::FindPlugin(summary_options.GetLanguage())) + std::tie(prefix, suffix) = language->GetFormatterPrefixSuffix(g_TypeHint); // this is a fairly ugly trick - pretend that the numeric value is actually a // char* this works under a few assumptions: little endian architecture // sizeof(uint64_t) > g_MaxNonBitmaskedLen if (len_bits <= g_MaxNonBitmaskedLen) { - stream.Printf("%s", prefix.c_str()); + stream << prefix; stream.Printf("\"%s\"", (const char *)&data_bits); - stream.Printf("%s", suffix.c_str()); + stream << suffix; return true; } @@ -375,8 +363,8 @@ bool lldb_private::formatters::NSTaggedString_SummaryProvider( bytes.insert(bytes.begin(), sixBitToCharLookup[packed]); } - stream.Printf("%s", prefix.c_str()); + stream << prefix; stream.Printf("\"%s\"", &bytes[0]); - stream.Printf("%s", suffix.c_str()); + stream << suffix; return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 9cbb40419167..82b037129c24 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -60,201 +60,160 @@ Language *ObjCLanguage::CreateInstance(lldb::LanguageType language) { } } -void ObjCLanguage::MethodName::Clear() { - m_full.Clear(); - m_class.Clear(); - m_category.Clear(); - m_selector.Clear(); - m_type = eTypeUnspecified; - m_category_is_valid = false; -} - -bool ObjCLanguage::MethodName::SetName(llvm::StringRef name, bool strict) { - Clear(); +std::optional<const ObjCLanguage::MethodName> +ObjCLanguage::MethodName::Create(llvm::StringRef name, bool strict) { if (name.empty()) - return IsValid(strict); - - // If "strict" is true. then the method must be specified with a '+' or '-' - // at the beginning. If "strict" is false, then the '+' or '-' can be omitted - bool valid_prefix = false; - - if (name.size() > 1 && (name[0] == '+' || name[0] == '-')) { - valid_prefix = name[1] == '['; - if (name[0] == '+') - m_type = eTypeClassMethod; - else - m_type = eTypeInstanceMethod; - } else if (!strict) { - // "strict" is false, the name just needs to start with '[' - valid_prefix = name[0] == '['; - } - - if (valid_prefix) { - int name_len = name.size(); - // Objective-C methods must have at least: - // "-[" or "+[" prefix - // One character for a class name - // One character for the space between the class name - // One character for the method name - // "]" suffix - if (name_len >= (5 + (strict ? 1 : 0)) && name.back() == ']') { - m_full.SetString(name); - } - } - return IsValid(strict); + return std::nullopt; + + // Objective-C method minimum requirements: + // - If `strict` is true, must start with '-' or '+' (1 char) + // - Must be followed by '[' (1 char) + // - Must have at least one character for class name (1 char) + // - Must have a space between class name and method name (1 char) + // - Must have at least one character for method name (1 char) + // - Must be end with ']' (1 char) + // This means that the minimum size is 5 characters (6 if `strict`) + // e.g. [a a] (-[a a] or +[a a] if `strict`) + + // We can check length and ending invariants first + if (name.size() < (5 + (strict ? 1 : 0)) || name.back() != ']') + return std::nullopt; + + // Figure out type + Type type = eTypeUnspecified; + if (name.startswith("+[")) + type = eTypeClassMethod; + else if (name.startswith("-[")) + type = eTypeInstanceMethod; + + // If there's no type and it's strict, this is invalid + if (strict && type == eTypeUnspecified) + return std::nullopt; + + // If not strict and type unspecified, make sure we start with '[' + if (type == eTypeUnspecified && name.front() != '[') + return std::nullopt; + + // If we've gotten here, we're confident that this looks enough like an + // Objective-C method to treat it like one. + ObjCLanguage::MethodName method_name(name, type); + return method_name; } -bool ObjCLanguage::MethodName::SetName(const char *name, bool strict) { - return SetName(llvm::StringRef(name), strict); +llvm::StringRef ObjCLanguage::MethodName::GetClassName() const { + llvm::StringRef full = m_full; + const size_t class_start_pos = (full.front() == '[' ? 1 : 2); + const size_t paren_pos = full.find('(', class_start_pos); + // If there's a category we want to stop there + if (paren_pos != llvm::StringRef::npos) + return full.substr(class_start_pos, paren_pos - class_start_pos); + + // Otherwise we find the space separating the class and method + const size_t space_pos = full.find(' ', class_start_pos); + return full.substr(class_start_pos, space_pos - class_start_pos); } -ConstString ObjCLanguage::MethodName::GetClassName() { - if (!m_class) { - if (IsValid(false)) { - const char *full = m_full.GetCString(); - const char *class_start = (full[0] == '[' ? full + 1 : full + 2); - const char *paren_pos = strchr(class_start, '('); - if (paren_pos) { - m_class.SetCStringWithLength(class_start, paren_pos - class_start); - } else { - // No '(' was found in the full name, we can definitively say that our - // category was valid (and empty). - m_category_is_valid = true; - const char *space_pos = strchr(full, ' '); - if (space_pos) { - m_class.SetCStringWithLength(class_start, space_pos - class_start); - if (!m_class_category) { - // No category in name, so we can also fill in the m_class_category - m_class_category = m_class; - } - } - } - } - } - return m_class; +llvm::StringRef ObjCLanguage::MethodName::GetClassNameWithCategory() const { + llvm::StringRef full = m_full; + const size_t class_start_pos = (full.front() == '[' ? 1 : 2); + const size_t space_pos = full.find(' ', class_start_pos); + return full.substr(class_start_pos, space_pos - class_start_pos); } -ConstString ObjCLanguage::MethodName::GetClassNameWithCategory() { - if (!m_class_category) { - if (IsValid(false)) { - const char *full = m_full.GetCString(); - const char *class_start = (full[0] == '[' ? full + 1 : full + 2); - const char *space_pos = strchr(full, ' '); - if (space_pos) { - m_class_category.SetCStringWithLength(class_start, - space_pos - class_start); - // If m_class hasn't been filled in and the class with category doesn't - // contain a '(', then we can also fill in the m_class - if (!m_class && strchr(m_class_category.GetCString(), '(') == nullptr) { - m_class = m_class_category; - // No '(' was found in the full name, we can definitively say that - // our category was valid (and empty). - m_category_is_valid = true; - } - } - } - } - return m_class_category; +llvm::StringRef ObjCLanguage::MethodName::GetSelector() const { + llvm::StringRef full = m_full; + const size_t space_pos = full.find(' '); + if (space_pos == llvm::StringRef::npos) + return llvm::StringRef(); + const size_t closing_bracket = full.find(']', space_pos); + return full.substr(space_pos + 1, closing_bracket - space_pos - 1); } -ConstString ObjCLanguage::MethodName::GetSelector() { - if (!m_selector) { - if (IsValid(false)) { - const char *full = m_full.GetCString(); - const char *space_pos = strchr(full, ' '); - if (space_pos) { - ++space_pos; // skip the space - m_selector.SetCStringWithLength(space_pos, m_full.GetLength() - - (space_pos - full) - 1); - } - } - } - return m_selector; -} +llvm::StringRef ObjCLanguage::MethodName::GetCategory() const { + llvm::StringRef full = m_full; + const size_t open_paren_pos = full.find('('); + const size_t close_paren_pos = full.find(')'); -ConstString ObjCLanguage::MethodName::GetCategory() { - if (!m_category_is_valid && !m_category) { - if (IsValid(false)) { - m_category_is_valid = true; - const char *full = m_full.GetCString(); - const char *class_start = (full[0] == '[' ? full + 1 : full + 2); - const char *open_paren_pos = strchr(class_start, '('); - if (open_paren_pos) { - ++open_paren_pos; // Skip the open paren - const char *close_paren_pos = strchr(open_paren_pos, ')'); - if (close_paren_pos) - m_category.SetCStringWithLength(open_paren_pos, - close_paren_pos - open_paren_pos); - } - } - } - return m_category; -} + if (open_paren_pos == llvm::StringRef::npos || + close_paren_pos == llvm::StringRef::npos) + return llvm::StringRef(); -ConstString ObjCLanguage::MethodName::GetFullNameWithoutCategory( - bool empty_if_no_category) { - if (IsValid(false)) { - if (HasCategory()) { - StreamString strm; - if (m_type == eTypeClassMethod) - strm.PutChar('+'); - else if (m_type == eTypeInstanceMethod) - strm.PutChar('-'); - strm.Printf("[%s %s]", GetClassName().GetCString(), - GetSelector().GetCString()); - return ConstString(strm.GetString()); - } + return full.substr(open_paren_pos + 1, + close_paren_pos - (open_paren_pos + 1)); +} - if (!empty_if_no_category) { - // Just return the full name since it doesn't have a category - return GetFullName(); - } - } - return ConstString(); +std::string ObjCLanguage::MethodName::GetFullNameWithoutCategory() const { + llvm::StringRef full = m_full; + const size_t open_paren_pos = full.find('('); + const size_t close_paren_pos = full.find(')'); + if (open_paren_pos == llvm::StringRef::npos || + close_paren_pos == llvm::StringRef::npos) + return std::string(); + + llvm::StringRef class_name = GetClassName(); + llvm::StringRef selector_name = GetSelector(); + + // Compute the total size to avoid reallocations + // class name + selector name + '[' + ' ' + ']' + size_t total_size = class_name.size() + selector_name.size() + 3; + if (m_type != eTypeUnspecified) + total_size++; // For + or - + + std::string name_sans_category; + name_sans_category.reserve(total_size); + + if (m_type == eTypeClassMethod) + name_sans_category += '+'; + else if (m_type == eTypeInstanceMethod) + name_sans_category += '-'; + + name_sans_category += '['; + name_sans_category.append(class_name.data(), class_name.size()); + name_sans_category += ' '; + name_sans_category.append(selector_name.data(), selector_name.size()); + name_sans_category += ']'; + + return name_sans_category; } std::vector<Language::MethodNameVariant> ObjCLanguage::GetMethodNameVariants(ConstString method_name) const { std::vector<Language::MethodNameVariant> variant_names; - ObjCLanguage::MethodName objc_method(method_name.GetCString(), false); - if (!objc_method.IsValid(false)) { + std::optional<const ObjCLanguage::MethodName> objc_method = + ObjCLanguage::MethodName::Create(method_name.GetStringRef(), false); + if (!objc_method) return variant_names; - } - variant_names.emplace_back(objc_method.GetSelector(), + variant_names.emplace_back(ConstString(objc_method->GetSelector()), lldb::eFunctionNameTypeSelector); - const bool is_class_method = - objc_method.GetType() == MethodName::eTypeClassMethod; - const bool is_instance_method = - objc_method.GetType() == MethodName::eTypeInstanceMethod; - ConstString name_sans_category = - objc_method.GetFullNameWithoutCategory(/*empty_if_no_category*/ true); + const std::string name_sans_category = + objc_method->GetFullNameWithoutCategory(); - if (is_class_method || is_instance_method) { - if (name_sans_category) - variant_names.emplace_back(name_sans_category, + if (objc_method->IsClassMethod() || objc_method->IsInstanceMethod()) { + if (!name_sans_category.empty()) + variant_names.emplace_back(ConstString(name_sans_category.c_str()), lldb::eFunctionNameTypeFull); } else { StreamString strm; - strm.Printf("+%s", objc_method.GetFullName().GetCString()); + strm.Printf("+%s", objc_method->GetFullName().c_str()); variant_names.emplace_back(ConstString(strm.GetString()), lldb::eFunctionNameTypeFull); strm.Clear(); - strm.Printf("-%s", objc_method.GetFullName().GetCString()); + strm.Printf("-%s", objc_method->GetFullName().c_str()); variant_names.emplace_back(ConstString(strm.GetString()), lldb::eFunctionNameTypeFull); strm.Clear(); - if (name_sans_category) { - strm.Printf("+%s", name_sans_category.GetCString()); + if (!name_sans_category.empty()) { + strm.Printf("+%s", name_sans_category.c_str()); variant_names.emplace_back(ConstString(strm.GetString()), lldb::eFunctionNameTypeFull); strm.Clear(); - strm.Printf("-%s", name_sans_category.GetCString()); + strm.Printf("-%s", name_sans_category.c_str()); variant_names.emplace_back(ConstString(strm.GetString()), lldb::eFunctionNameTypeFull); } @@ -297,23 +256,23 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { objc_flags.SetSkipPointers(true); AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, - "SEL summary provider", ConstString("SEL"), objc_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, - "SEL summary provider", ConstString("struct objc_selector"), objc_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<false>, - "SEL summary provider", ConstString("objc_selector"), objc_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, - "SEL summary provider", ConstString("objc_selector *"), objc_flags); + "SEL summary provider", "SEL", objc_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::ObjCSELSummaryProvider<false>, + "SEL summary provider", "struct objc_selector", objc_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::ObjCSELSummaryProvider<false>, + "SEL summary provider", "objc_selector", objc_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::ObjCSELSummaryProvider<true>, + "SEL summary provider", "objc_selector *", objc_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCSELSummaryProvider<true>, - "SEL summary provider", ConstString("SEL *"), objc_flags); + "SEL summary provider", "SEL *", objc_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::ObjCClassSummaryProvider, - "Class summary provider", ConstString("Class"), objc_flags); + "Class summary provider", "Class", objc_flags); SyntheticChildren::Flags class_synth_flags; class_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences( @@ -321,61 +280,62 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { AddCXXSynthetic(objc_category_sp, lldb_private::formatters::ObjCClassSyntheticFrontEndCreator, - "Class synthetic children", ConstString("Class"), - class_synth_flags); + "Class synthetic children", "Class", class_synth_flags); objc_flags.SetSkipPointers(false); objc_flags.SetCascades(true); objc_flags.SetSkipReferences(false); AddStringSummary(objc_category_sp, "${var.__FuncPtr%A}", - ConstString("__block_literal_generic"), objc_flags); + "__block_literal_generic", objc_flags); - AddStringSummary(objc_category_sp, "${var.years} years, ${var.months} " - "months, ${var.days} days, ${var.hours} " - "hours, ${var.minutes} minutes " - "${var.seconds} seconds", - ConstString("CFGregorianUnits"), objc_flags); AddStringSummary(objc_category_sp, - "location=${var.location} length=${var.length}", - ConstString("CFRange"), objc_flags); + "${var.years} years, ${var.months} " + "months, ${var.days} days, ${var.hours} " + "hours, ${var.minutes} minutes " + "${var.seconds} seconds", + "CFGregorianUnits", objc_flags); + AddStringSummary(objc_category_sp, + "location=${var.location} length=${var.length}", "CFRange", + objc_flags); AddStringSummary(objc_category_sp, - "location=${var.location}, length=${var.length}", - ConstString("NSRange"), objc_flags); + "location=${var.location}, length=${var.length}", "NSRange", + objc_flags); AddStringSummary(objc_category_sp, "(${var.origin}, ${var.size}), ...", - ConstString("NSRectArray"), objc_flags); + "NSRectArray", objc_flags); - AddOneLineSummary(objc_category_sp, ConstString("NSPoint"), objc_flags); - AddOneLineSummary(objc_category_sp, ConstString("NSSize"), objc_flags); - AddOneLineSummary(objc_category_sp, ConstString("NSRect"), objc_flags); + AddOneLineSummary(objc_category_sp, "NSPoint", objc_flags); + AddOneLineSummary(objc_category_sp, "NSSize", objc_flags); + AddOneLineSummary(objc_category_sp, "NSRect", objc_flags); - AddOneLineSummary(objc_category_sp, ConstString("CGSize"), objc_flags); - AddOneLineSummary(objc_category_sp, ConstString("CGPoint"), objc_flags); - AddOneLineSummary(objc_category_sp, ConstString("CGRect"), objc_flags); + AddOneLineSummary(objc_category_sp, "CGSize", objc_flags); + AddOneLineSummary(objc_category_sp, "CGPoint", objc_flags); + AddOneLineSummary(objc_category_sp, "CGRect", objc_flags); AddStringSummary(objc_category_sp, "red=${var.red} green=${var.green} blue=${var.blue}", - ConstString("RGBColor"), objc_flags); + "RGBColor", objc_flags); AddStringSummary( objc_category_sp, - "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})", - ConstString("Rect"), objc_flags); - AddStringSummary(objc_category_sp, "{(v=${var.v}, h=${var.h})}", - ConstString("Point"), objc_flags); + "(t=${var.top}, l=${var.left}, b=${var.bottom}, r=${var.right})", "Rect", + objc_flags); + AddStringSummary(objc_category_sp, "{(v=${var.v}, h=${var.h})}", "Point", + objc_flags); AddStringSummary(objc_category_sp, "${var.month}/${var.day}/${var.year} ${var.hour} " ":${var.minute} :${var.second} dayOfWeek:${var.dayOfWeek}", - ConstString("DateTimeRect *"), objc_flags); - AddStringSummary(objc_category_sp, "${var.ld.month}/${var.ld.day}/" - "${var.ld.year} ${var.ld.hour} " - ":${var.ld.minute} :${var.ld.second} " - "dayOfWeek:${var.ld.dayOfWeek}", - ConstString("LongDateRect"), objc_flags); - AddStringSummary(objc_category_sp, "(x=${var.x}, y=${var.y})", - ConstString("HIPoint"), objc_flags); + "DateTimeRect *", objc_flags); + AddStringSummary(objc_category_sp, + "${var.ld.month}/${var.ld.day}/" + "${var.ld.year} ${var.ld.hour} " + ":${var.ld.minute} :${var.ld.second} " + "dayOfWeek:${var.ld.dayOfWeek}", + "LongDateRect", objc_flags); + AddStringSummary(objc_category_sp, "(x=${var.x}, y=${var.y})", "HIPoint", + objc_flags); AddStringSummary(objc_category_sp, "origin=${var.origin} size=${var.size}", - ConstString("HIRect"), objc_flags); + "HIRect", objc_flags); TypeSummaryImpl::Flags appkit_flags; appkit_flags.SetCascades(true) @@ -388,129 +348,126 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { appkit_flags.SetDontShowChildren(false); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("NSArray"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("NSConstantArray"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("NSMutableArray"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("__NSArrayI"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("__NSArray0"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", - ConstString("__NSSingleObjectArrayI"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("__NSArrayM"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("_NSCallStackArray"), appkit_flags); + "NSArray summary provider", "NSArray", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", "NSConstantArray", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", "NSMutableArray", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", "__NSArrayI", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", "__NSArray0", appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags); + "NSArray summary provider", "__NSSingleObjectArrayI", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, - "NSArray summary provider", ConstString("CFMutableArrayRef"), - appkit_flags); + "NSArray summary provider", "__NSArrayM", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", "__NSCFArray", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", "_NSCallStackArray", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", "CFArrayRef", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", "CFMutableArrayRef", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, - "NSDictionary summary provider", ConstString("NSDictionary"), - appkit_flags); + "NSDictionary summary provider", "NSDictionary", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, - "NSDictionary summary provider", - ConstString("NSConstantDictionary"), appkit_flags); + "NSDictionary summary provider", "NSConstantDictionary", + appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, - "NSDictionary summary provider", - ConstString("NSMutableDictionary"), appkit_flags); + "NSDictionary summary provider", "NSMutableDictionary", + appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, - "NSDictionary summary provider", - ConstString("__NSCFDictionary"), appkit_flags); + "NSDictionary summary provider", "__NSCFDictionary", + appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, - "NSDictionary summary provider", ConstString("__NSDictionaryI"), + "NSDictionary summary provider", "__NSDictionaryI", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, - "NSDictionary summary provider", - ConstString("__NSSingleEntryDictionaryI"), appkit_flags); + "NSDictionary summary provider", "__NSSingleEntryDictionaryI", + appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<false>, - "NSDictionary summary provider", ConstString("__NSDictionaryM"), + "NSDictionary summary provider", "__NSDictionaryM", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, - "NSDictionary summary provider", ConstString("CFDictionaryRef"), + "NSDictionary summary provider", "CFDictionaryRef", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, - "NSDictionary summary provider", ConstString("__CFDictionary"), + "NSDictionary summary provider", "__CFDictionary", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDictionarySummaryProvider<true>, - "NSDictionary summary provider", - ConstString("CFMutableDictionaryRef"), appkit_flags); + "NSDictionary summary provider", "CFMutableDictionaryRef", + appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "NSSet summary", ConstString("NSSet"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags); + "NSSet summary", "NSSet", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider<false>, + "NSMutableSet summary", "NSMutableSet", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, - "CFSetRef summary", ConstString("CFSetRef"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<true>, - "CFMutableSetRef summary", ConstString("CFMutableSetRef"), appkit_flags); + "CFSetRef summary", "CFSetRef", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider<true>, + "CFMutableSetRef summary", "CFMutableSetRef", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "__NSCFSet summary", ConstString("__NSCFSet"), appkit_flags); + "__NSCFSet summary", "__NSCFSet", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "__CFSet summary", ConstString("__CFSet"), appkit_flags); + "__CFSet summary", "__CFSet", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "__NSSetI summary", ConstString("__NSSetI"), appkit_flags); + "__NSSetI summary", "__NSSetI", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "__NSSetM summary", ConstString("__NSSetM"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "NSCountedSet summary", ConstString("NSCountedSet"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "NSMutableSet summary", ConstString("NSMutableSet"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "NSOrderedSet summary", ConstString("NSOrderedSet"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "__NSOrderedSetI summary", ConstString("__NSOrderedSetI"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSSetSummaryProvider<false>, - "__NSOrderedSetM summary", ConstString("__NSOrderedSetM"), appkit_flags); + "__NSSetM summary", "__NSSetM", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider<false>, + "NSCountedSet summary", "NSCountedSet", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider<false>, + "NSMutableSet summary", "NSMutableSet", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider<false>, + "NSOrderedSet summary", "NSOrderedSet", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider<false>, + "__NSOrderedSetI summary", "__NSOrderedSetI", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSSetSummaryProvider<false>, + "__NSOrderedSetM summary", "__NSOrderedSetM", appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSError_SummaryProvider, - "NSError summary provider", ConstString("NSError"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSException_SummaryProvider, - "NSException summary provider", ConstString("NSException"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSError_SummaryProvider, + "NSError summary provider", "NSError", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSException_SummaryProvider, + "NSException summary provider", "NSException", appkit_flags); // AddSummary(appkit_category_sp, "${var.key%@} -> ${var.value%@}", // ConstString("$_lldb_typegen_nspair"), appkit_flags); @@ -519,384 +476,359 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("__NSArrayM"), + "NSArray synthetic children", "__NSArrayM", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("__NSArrayI"), + "NSArray synthetic children", "__NSArrayI", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("__NSArray0"), + "NSArray synthetic children", "__NSArray0", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", - ConstString("__NSSingleObjectArrayI"), + "NSArray synthetic children", "__NSSingleObjectArrayI", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("NSArray"), + "NSArray synthetic children", "NSArray", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("NSConstantArray"), + "NSArray synthetic children", "NSConstantArray", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("NSMutableArray"), + "NSArray synthetic children", "NSMutableArray", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("__NSCFArray"), + "NSArray synthetic children", "__NSCFArray", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("_NSCallStackArray"), + "NSArray synthetic children", "_NSCallStackArray", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", - ConstString("CFMutableArrayRef"), + "NSArray synthetic children", "CFMutableArrayRef", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, - "NSArray synthetic children", ConstString("CFArrayRef"), + "NSArray synthetic children", "CFArrayRef", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("__NSDictionaryM"), + "NSDictionary synthetic children", "__NSDictionaryM", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("NSConstantDictionary"), + "NSDictionary synthetic children", "NSConstantDictionary", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("__NSDictionaryI"), + "NSDictionary synthetic children", "__NSDictionaryI", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", - ConstString("__NSSingleEntryDictionaryI"), + "NSDictionary synthetic children", "__NSSingleEntryDictionaryI", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("__NSCFDictionary"), + "NSDictionary synthetic children", "__NSCFDictionary", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("NSDictionary"), + "NSDictionary synthetic children", "NSDictionary", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("NSMutableDictionary"), + "NSDictionary synthetic children", "NSMutableDictionary", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("CFDictionaryRef"), + "NSDictionary synthetic children", "CFDictionaryRef", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("CFMutableDictionaryRef"), + "NSDictionary synthetic children", "CFMutableDictionaryRef", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic( objc_category_sp, lldb_private::formatters::NSDictionarySyntheticFrontEndCreator, - "NSDictionary synthetic children", ConstString("__CFDictionary"), + "NSDictionary synthetic children", "__CFDictionary", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSErrorSyntheticFrontEndCreator, - "NSError synthetic children", ConstString("NSError"), + "NSError synthetic children", "NSError", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSExceptionSyntheticFrontEndCreator, - "NSException synthetic children", ConstString("NSException"), + "NSException synthetic children", "NSException", ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic( + objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "NSSet synthetic children", "NSSet", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "NSSet synthetic children", ConstString("NSSet"), + "__NSSetI synthetic children", "__NSSetI", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "__NSSetI synthetic children", ConstString("__NSSetI"), + "__NSSetM synthetic children", "__NSSetM", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "__NSSetM synthetic children", ConstString("__NSSetM"), + "__NSCFSet synthetic children", "__NSCFSet", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "__NSCFSet synthetic children", ConstString("__NSCFSet"), + "CFSetRef synthetic children", "CFSetRef", ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "CFSetRef synthetic children", ConstString("CFSetRef"), + "NSMutableSet synthetic children", "NSMutableSet", + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "NSOrderedSet synthetic children", "NSOrderedSet", + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "__NSOrderedSetI synthetic children", "__NSOrderedSetI", ScriptedSyntheticChildren::Flags()); - - AddCXXSynthetic( - objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "NSMutableSet synthetic children", ConstString("NSMutableSet"), - ScriptedSyntheticChildren::Flags()); - AddCXXSynthetic( - objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "NSOrderedSet synthetic children", ConstString("NSOrderedSet"), - ScriptedSyntheticChildren::Flags()); - AddCXXSynthetic( - objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "__NSOrderedSetI synthetic children", ConstString("__NSOrderedSetI"), - ScriptedSyntheticChildren::Flags()); - AddCXXSynthetic( - objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "__NSOrderedSetM synthetic children", ConstString("__NSOrderedSetM"), - ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSSetSyntheticFrontEndCreator, - "__CFSet synthetic children", ConstString("__CFSet"), + "__NSOrderedSetM synthetic children", "__NSOrderedSetM", + ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSSetSyntheticFrontEndCreator, + "__CFSet synthetic children", "__CFSet", ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSIndexPathSyntheticFrontEndCreator, - "NSIndexPath synthetic children", ConstString("NSIndexPath"), + "NSIndexPath synthetic children", "NSIndexPath", ScriptedSyntheticChildren::Flags()); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::CFBagSummaryProvider, - "CFBag summary provider", ConstString("CFBagRef"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBagSummaryProvider, - "CFBag summary provider", ConstString("__CFBag"), appkit_flags); + "CFBag summary provider", "CFBagRef", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBagSummaryProvider, - "CFBag summary provider", ConstString("const struct __CFBag"), - appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::CFBagSummaryProvider, - "CFBag summary provider", ConstString("CFMutableBagRef"), appkit_flags); - + "CFBag summary provider", "__CFBag", appkit_flags); AddCXXSummary(objc_category_sp, - lldb_private::formatters::CFBinaryHeapSummaryProvider, - "CFBinaryHeap summary provider", ConstString("CFBinaryHeapRef"), - appkit_flags); + lldb_private::formatters::CFBagSummaryProvider, + "CFBag summary provider", "const struct __CFBag", appkit_flags); AddCXXSummary(objc_category_sp, - lldb_private::formatters::CFBinaryHeapSummaryProvider, - "CFBinaryHeap summary provider", ConstString("__CFBinaryHeap"), - appkit_flags); + lldb_private::formatters::CFBagSummaryProvider, + "CFBag summary provider", "CFMutableBagRef", appkit_flags); AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("NSString"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("CFStringRef"), appkit_flags); + objc_category_sp, lldb_private::formatters::CFBinaryHeapSummaryProvider, + "CFBinaryHeap summary provider", "CFBinaryHeapRef", appkit_flags); AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("__CFString"), appkit_flags); + objc_category_sp, lldb_private::formatters::CFBinaryHeapSummaryProvider, + "CFBinaryHeap summary provider", "__CFBinaryHeap", appkit_flags); + AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("CFMutableStringRef"), - appkit_flags); + "NSString summary provider", "NSString", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("NSMutableString"), - appkit_flags); + "NSString summary provider", "CFStringRef", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", - ConstString("__NSCFConstantString"), appkit_flags); + "NSString summary provider", "__CFString", appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("__NSCFString"), appkit_flags); + "NSString summary provider", "CFMutableStringRef", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("NSCFConstantString"), - appkit_flags); + "NSString summary provider", "NSMutableString", appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("NSCFString"), appkit_flags); + "NSString summary provider", "__NSCFConstantString", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSStringSummaryProvider, + "NSString summary provider", "__NSCFString", appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", ConstString("NSPathStore2"), appkit_flags); + "NSString summary provider", "NSCFConstantString", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSStringSummaryProvider, + "NSString summary provider", "NSCFString", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, - "NSString summary provider", - ConstString("NSTaggedPointerString"), appkit_flags); + "NSString summary provider", "NSPathStore2", appkit_flags); + AddCXXSummary( + objc_category_sp, lldb_private::formatters::NSStringSummaryProvider, + "NSString summary provider", "NSTaggedPointerString", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSAttributedStringSummaryProvider, - "NSAttributedString summary provider", - ConstString("NSAttributedString"), appkit_flags); + "NSAttributedString summary provider", "NSAttributedString", + appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, - "NSMutableAttributedString summary provider", - ConstString("NSMutableAttributedString"), appkit_flags); + "NSMutableAttributedString summary provider", "NSMutableAttributedString", + appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSMutableAttributedStringSummaryProvider, "NSMutableAttributedString summary provider", - ConstString("NSConcreteMutableAttributedString"), appkit_flags); + "NSConcreteMutableAttributedString", appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSBundleSummaryProvider, - "NSBundle summary provider", ConstString("NSBundle"), appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSBundleSummaryProvider, + "NSBundle summary provider", "NSBundle", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, - "NSData summary provider", ConstString("NSData"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, - "NSData summary provider", ConstString("_NSInlineData"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, - "NSData summary provider", ConstString("NSConcreteData"), appkit_flags); + "NSData summary provider", "NSData", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, - "NSData summary provider", ConstString("NSConcreteMutableData"), - appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, - "NSData summary provider", ConstString("NSMutableData"), appkit_flags); + "NSData summary provider", "_NSInlineData", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDataSummaryProvider<false>, + "NSData summary provider", "NSConcreteData", appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<false>, - "NSData summary provider", ConstString("__NSCFData"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, - "NSData summary provider", ConstString("CFDataRef"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSDataSummaryProvider<true>, - "NSData summary provider", ConstString("CFMutableDataRef"), appkit_flags); - - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSMachPortSummaryProvider, - "NSMachPort summary provider", ConstString("NSMachPort"), appkit_flags); - + "NSData summary provider", "NSConcreteMutableData", appkit_flags); AddCXXSummary(objc_category_sp, - lldb_private::formatters::NSNotificationSummaryProvider, - "NSNotification summary provider", - ConstString("NSNotification"), appkit_flags); + lldb_private::formatters::NSDataSummaryProvider<false>, + "NSData summary provider", "NSMutableData", appkit_flags); AddCXXSummary(objc_category_sp, - lldb_private::formatters::NSNotificationSummaryProvider, - "NSNotification summary provider", - ConstString("NSConcreteNotification"), appkit_flags); + lldb_private::formatters::NSDataSummaryProvider<false>, + "NSData summary provider", "__NSCFData", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDataSummaryProvider<true>, + "NSData summary provider", "CFDataRef", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDataSummaryProvider<true>, + "NSData summary provider", "CFMutableDataRef", appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, - "NSNumber summary provider", ConstString("NSNumber"), appkit_flags); AddCXXSummary(objc_category_sp, - lldb_private::formatters::NSNumberSummaryProvider, - "NSNumber summary provider", - ConstString("NSConstantIntegerNumber"), appkit_flags); + lldb_private::formatters::NSMachPortSummaryProvider, + "NSMachPort summary provider", "NSMachPort", appkit_flags); + + AddCXXSummary( + objc_category_sp, lldb_private::formatters::NSNotificationSummaryProvider, + "NSNotification summary provider", "NSNotification", appkit_flags); AddCXXSummary(objc_category_sp, - lldb_private::formatters::NSNumberSummaryProvider, - "NSNumber summary provider", - ConstString("NSConstantDoubleNumber"), appkit_flags); + lldb_private::formatters::NSNotificationSummaryProvider, + "NSNotification summary provider", "NSConcreteNotification", + appkit_flags); + AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, - "NSNumber summary provider", - ConstString("NSConstantFloatNumber"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, - "CFNumberRef summary provider", ConstString("CFNumberRef"), appkit_flags); + "NSNumber summary provider", "NSNumber", appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, - "NSNumber summary provider", ConstString("__NSCFBoolean"), appkit_flags); + "NSNumber summary provider", "NSConstantIntegerNumber", appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, - "NSNumber summary provider", ConstString("__NSCFNumber"), appkit_flags); + "NSNumber summary provider", "NSConstantDoubleNumber", appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, - "NSNumber summary provider", ConstString("NSCFBoolean"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, - "NSNumber summary provider", ConstString("NSCFNumber"), appkit_flags); + "NSNumber summary provider", "NSConstantFloatNumber", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, - "NSDecimalNumber summary provider", - ConstString("NSDecimalNumber"), appkit_flags); + "CFNumberRef summary provider", "CFNumberRef", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSNumberSummaryProvider, + "NSNumber summary provider", "__NSCFBoolean", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSNumberSummaryProvider, + "NSNumber summary provider", "__NSCFNumber", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSNumberSummaryProvider, + "NSNumber summary provider", "NSCFBoolean", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSNumberSummaryProvider, + "NSNumber summary provider", "NSCFNumber", appkit_flags); + AddCXXSummary( + objc_category_sp, lldb_private::formatters::NSNumberSummaryProvider, + "NSDecimalNumber summary provider", "NSDecimalNumber", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, - "NSURL summary provider", ConstString("NSURL"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSURLSummaryProvider, - "NSURL summary provider", ConstString("CFURLRef"), appkit_flags); + "NSURL summary provider", "NSURL", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSURLSummaryProvider, + "NSURL summary provider", "CFURLRef", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, - "NSDate summary provider", ConstString("NSDate"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, - "NSDate summary provider", ConstString("__NSDate"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, - "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSDateSummaryProvider, - "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags); + "NSDate summary provider", "NSDate", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDateSummaryProvider, + "NSDate summary provider", "__NSDate", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDateSummaryProvider, + "NSDate summary provider", "__NSTaggedDate", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSDateSummaryProvider, + "NSDate summary provider", "NSCalendarDate", appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, - "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, - "NSTimeZone summary provider", ConstString("CFTimeZoneRef"), - appkit_flags); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, - "NSTimeZone summary provider", ConstString("__NSTimeZone"), appkit_flags); + "NSTimeZone summary provider", "NSTimeZone", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSTimeZoneSummaryProvider, + "NSTimeZone summary provider", "CFTimeZoneRef", appkit_flags); + AddCXXSummary(objc_category_sp, + lldb_private::formatters::NSTimeZoneSummaryProvider, + "NSTimeZone summary provider", "__NSTimeZone", appkit_flags); // CFAbsoluteTime is actually a double rather than a pointer to an object we // do not care about the numeric value, since it is probably meaningless to // users appkit_flags.SetDontShowValue(true); - AddCXXSummary(objc_category_sp, - lldb_private::formatters::CFAbsoluteTimeSummaryProvider, - "CFAbsoluteTime summary provider", - ConstString("CFAbsoluteTime"), appkit_flags); + AddCXXSummary( + objc_category_sp, lldb_private::formatters::CFAbsoluteTimeSummaryProvider, + "CFAbsoluteTime summary provider", "CFAbsoluteTime", appkit_flags); appkit_flags.SetDontShowValue(false); - AddCXXSummary( - objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, - "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, - "NSIndexSet summary provider", ConstString("NSMutableIndexSet"), - appkit_flags); + "NSIndexSet summary provider", "NSIndexSet", appkit_flags); + AddCXXSummary( + objc_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, + "NSIndexSet summary provider", "NSMutableIndexSet", appkit_flags); AddStringSummary(objc_category_sp, "@\"${var.month%d}/${var.day%d}/${var.year%d} " "${var.hour%d}:${var.minute%d}:${var.second}\"", - ConstString("CFGregorianDate"), appkit_flags); + "CFGregorianDate", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, - "CFBitVector summary provider", ConstString("CFBitVectorRef"), - appkit_flags); - AddCXXSummary(objc_category_sp, - lldb_private::formatters::CFBitVectorSummaryProvider, - "CFBitVector summary provider", - ConstString("CFMutableBitVectorRef"), appkit_flags); - AddCXXSummary(objc_category_sp, - lldb_private::formatters::CFBitVectorSummaryProvider, - "CFBitVector summary provider", ConstString("__CFBitVector"), - appkit_flags); + "CFBitVector summary provider", "CFBitVectorRef", appkit_flags); + AddCXXSummary( + objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, + "CFBitVector summary provider", "CFMutableBitVectorRef", appkit_flags); AddCXXSummary(objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, - "CFBitVector summary provider", - ConstString("__CFMutableBitVector"), appkit_flags); + "CFBitVector summary provider", "__CFBitVector", appkit_flags); + AddCXXSummary( + objc_category_sp, lldb_private::formatters::CFBitVectorSummaryProvider, + "CFBitVector summary provider", "__CFMutableBitVector", appkit_flags); } static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) { @@ -914,7 +846,7 @@ static void LoadCoreMediaFormatters(TypeCategoryImplSP objc_category_sp) { AddCXXSummary(objc_category_sp, lldb_private::formatters::CMTimeSummaryProvider, - "CMTime summary provider", ConstString("CMTime"), cm_flags); + "CMTime summary provider", "CMTime", cm_flags); } lldb::TypeCategoryImplSP ObjCLanguage::GetFormatters() { @@ -1047,7 +979,7 @@ std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() { friend class lldb_private::ObjCLanguage; }; - + class ObjCDebugInfoScavenger : public Language::ImageListTypeScavenger { public: CompilerType AdjustForInclusion(CompilerType &candidate) override { @@ -1066,78 +998,27 @@ std::unique_ptr<Language::TypeScavenger> ObjCLanguage::GetTypeScavenger() { ObjCDebugInfoScavenger>()); } -bool ObjCLanguage::GetFormatterPrefixSuffix(ValueObject &valobj, - ConstString type_hint, - std::string &prefix, - std::string &suffix) { - static ConstString g_CFBag("CFBag"); - static ConstString g_CFBinaryHeap("CFBinaryHeap"); - - static ConstString g_NSNumberChar("NSNumber:char"); - static ConstString g_NSNumberShort("NSNumber:short"); - static ConstString g_NSNumberInt("NSNumber:int"); - static ConstString g_NSNumberLong("NSNumber:long"); - static ConstString g_NSNumberInt128("NSNumber:int128_t"); - static ConstString g_NSNumberFloat("NSNumber:float"); - static ConstString g_NSNumberDouble("NSNumber:double"); - - static ConstString g_NSData("NSData"); - static ConstString g_NSArray("NSArray"); - static ConstString g_NSString("NSString"); - static ConstString g_NSStringStar("NSString*"); - - if (type_hint.IsEmpty()) - return false; - - prefix.clear(); - suffix.clear(); - - if (type_hint == g_CFBag || type_hint == g_CFBinaryHeap) { - prefix = "@"; - return true; - } - - if (type_hint == g_NSNumberChar) { - prefix = "(char)"; - return true; - } - if (type_hint == g_NSNumberShort) { - prefix = "(short)"; - return true; - } - if (type_hint == g_NSNumberInt) { - prefix = "(int)"; - return true; - } - if (type_hint == g_NSNumberLong) { - prefix = "(long)"; - return true; - } - if (type_hint == g_NSNumberInt128) { - prefix = "(int128_t)"; - return true; - } - if (type_hint == g_NSNumberFloat) { - prefix = "(float)"; - return true; - } - if (type_hint == g_NSNumberDouble) { - prefix = "(double)"; - return true; - } - - if (type_hint == g_NSData || type_hint == g_NSArray) { - prefix = "@\""; - suffix = "\""; - return true; - } - - if (type_hint == g_NSString || type_hint == g_NSStringStar) { - prefix = "@"; - return true; - } - - return false; +std::pair<llvm::StringRef, llvm::StringRef> +ObjCLanguage::GetFormatterPrefixSuffix(llvm::StringRef type_hint) { + static constexpr llvm::StringRef empty; + static const llvm::StringMap< + std::pair<const llvm::StringRef, const llvm::StringRef>> + g_affix_map = { + {"CFBag", {"@", empty}}, + {"CFBinaryHeap", {"@", empty}}, + {"NSString", {"@", empty}}, + {"NSString*", {"@", empty}}, + {"NSNumber:char", {"(char)", empty}}, + {"NSNumber:short", {"(short)", empty}}, + {"NSNumber:int", {"(int)", empty}}, + {"NSNumber:long", {"(long)", empty}}, + {"NSNumber:int128_t", {"(int128_t)", empty}}, + {"NSNumber:float", {"(float)", empty}}, + {"NSNumber:double", {"(double)", empty}}, + {"NSData", {"@\"", "\""}}, + {"NSArray", {"@\"", "\""}}, + }; + return g_affix_map.lookup(type_hint); } bool ObjCLanguage::IsNilReference(ValueObject &valobj) { @@ -1154,7 +1035,7 @@ bool ObjCLanguage::IsNilReference(ValueObject &valobj) { bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const { const auto suffixes = {".h", ".m", ".M"}; for (auto suffix : suffixes) { - if (file_path.endswith_insensitive(suffix)) + if (file_path.ends_with_insensitive(suffix)) return true; } return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index b61348a3280e..bb8057846bb7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -25,62 +25,98 @@ class ObjCLanguage : public Language { public: class MethodName { public: - enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod }; - - MethodName() : m_full(), m_class(), m_category(), m_selector() {} - - MethodName(const char *name, bool strict) - : m_full(), m_class(), m_category(), m_selector(), - m_type(eTypeUnspecified), m_category_is_valid(false) { - SetName(name, strict); - } - MethodName(llvm::StringRef name, bool strict) - : m_full(), m_class(), m_category(), m_selector(), - m_type(eTypeUnspecified), m_category_is_valid(false) { - SetName(name, strict); - } - - void Clear(); - - bool IsValid(bool strict) const { - // If "strict" is true, the name must have everything specified including - // the leading "+" or "-" on the method name - if (strict && m_type == eTypeUnspecified) - return false; - // Other than that, m_full will only be filled in if the objective C - // name is valid. - return (bool)m_full; - } - - bool HasCategory() { return !GetCategory().IsEmpty(); } - - Type GetType() const { return m_type; } - - ConstString GetFullName() const { return m_full; } + /// The static factory method for creating a MethodName. + /// + /// \param[in] name + /// The name of the method. + /// + /// \param[in] strict + /// Control whether or not the name parser is strict about +/- in the + /// front of the name. + /// + /// \return If the name failed to parse as a valid Objective-C method name, + /// returns std::nullopt. Otherwise returns a const MethodName. + static std::optional<const MethodName> Create(llvm::StringRef name, + bool strict); + + /// Determines if this method is a class method + /// + /// \return Returns true if the method is a class method. False otherwise. + bool IsClassMethod() const { return m_type == eTypeClassMethod; } + + /// Determines if this method is an instance method + /// + /// \return Returns true if the method is an instance method. False + /// otherwise. + bool IsInstanceMethod() const { return m_type == eTypeInstanceMethod; } + + /// Returns the full name of the method. + /// + /// This includes the class name, the category name (if applicable), and the + /// selector name. + /// + /// \return The name of the method in the form of a const std::string + /// reference. + const std::string &GetFullName() const { return m_full; } + + /// Creates a variation of this method without the category. + /// If this method has no category, it returns an empty string. + /// + /// Example: + /// Full name: "+[NSString(my_additions) myStringWithCString:]" + /// becomes "+[NSString myStringWithCString:]" + /// + /// \return The method name without the category or an empty string if there + /// was no category to begin with. + std::string GetFullNameWithoutCategory() const; + + /// Returns a reference to the class name. + /// + /// Example: + /// Full name: "+[NSString(my_additions) myStringWithCString:]" + /// will give you "NSString" + /// + /// \return A StringRef to the class name of this method. + llvm::StringRef GetClassName() const; + + /// Returns a reference to the class name with the category. + /// + /// Example: + /// Full name: "+[NSString(my_additions) myStringWithCString:]" + /// will give you "NSString(my_additions)" + /// + /// Note: If your method has no category, this will give the same output as + /// `GetClassName`. + /// + /// \return A StringRef to the class name (including the category) of this + /// method. If there was no category, returns the same as `GetClassName`. + llvm::StringRef GetClassNameWithCategory() const; + + /// Returns a reference to the category name. + /// + /// Example: + /// Full name: "+[NSString(my_additions) myStringWithCString:]" + /// will give you "my_additions" + /// \return A StringRef to the category name of this method. If no category + /// is present, the StringRef is empty. + llvm::StringRef GetCategory() const; + + /// Returns a reference to the selector name. + /// + /// Example: + /// Full name: "+[NSString(my_additions) myStringWithCString:]" + /// will give you "myStringWithCString:" + /// \return A StringRef to the selector of this method. + llvm::StringRef GetSelector() const; - ConstString GetFullNameWithoutCategory(bool empty_if_no_category); - - bool SetName(const char *name, bool strict); - bool SetName(llvm::StringRef name, bool strict); - - ConstString GetClassName(); - - ConstString GetClassNameWithCategory(); - - ConstString GetCategory(); + protected: + enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod }; - ConstString GetSelector(); + MethodName(llvm::StringRef name, Type type) + : m_full(name.str()), m_type(type) {} - protected: - ConstString - m_full; // Full name: "+[NSString(my_additions) myStringWithCString:]" - ConstString m_class; // Class name: "NSString" - ConstString - m_class_category; // Class with category: "NSString(my_additions)" - ConstString m_category; // Category: "my_additions" - ConstString m_selector; // Selector: "myStringWithCString:" - Type m_type = eTypeUnspecified; - bool m_category_is_valid = false; + const std::string m_full; + Type m_type; }; ObjCLanguage() = default; @@ -114,9 +150,8 @@ public: std::unique_ptr<TypeScavenger> GetTypeScavenger() override; - bool GetFormatterPrefixSuffix(ValueObject &valobj, ConstString type_hint, - std::string &prefix, - std::string &suffix) override; + std::pair<llvm::StringRef, llvm::StringRef> + GetFormatterPrefixSuffix(llvm::StringRef type_hint) override; bool IsNilReference(ValueObject &valobj) override; @@ -155,6 +190,8 @@ public: return false; } + llvm::StringRef GetInstanceVariableName() override { return "self"; } + // PluginInterface protocol llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp index 700dda3d33bb..79830e529df2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp @@ -19,7 +19,7 @@ LLDB_PLUGIN_DEFINE(ObjCPlusPlusLanguage) bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { const auto suffixes = {".h", ".mm"}; for (auto suffix : suffixes) { - if (file_path.endswith_insensitive(suffix)) + if (file_path.ends_with_insensitive(suffix)) return true; } return false; diff --git a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h index 20184fd709d5..b7c71b5dbb1c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h +++ b/contrib/llvm-project/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h @@ -40,6 +40,8 @@ public: static lldb_private::Language *CreateInstance(lldb::LanguageType language); + llvm::StringRef GetInstanceVariableName() override { return "self"; } + static llvm::StringRef GetPluginNameStatic() { return "objcplusplus"; } // PluginInterface protocol 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 0028a5141287..c2488eaa9f5b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.cpp @@ -138,12 +138,10 @@ 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_( - valobj_sp->GetChildMemberWithName(ConstString("__f_"), true)); + ValueObjectSP member_f_(valobj_sp->GetChildMemberWithName("__f_")); if (member_f_) { - ValueObjectSP sub_member_f_( - member_f_->GetChildMemberWithName(ConstString("__f_"), true)); + ValueObjectSP sub_member_f_(member_f_->GetChildMemberWithName("__f_")); if (sub_member_f_) member_f_ = sub_member_f_; 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 f05997fa03af..711a696ff9b4 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 @@ -318,9 +318,9 @@ ItaniumABILanguageRuntime::CreateInstance(Process *process, class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed { public: CommandObjectMultiwordItaniumABI_Demangle(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "demangle", - "Demangle a C++ mangled name.", - "language cplusplus demangle") { + : CommandObjectParsed( + interpreter, "demangle", "Demangle a C++ mangled name.", + "language cplusplus demangle [<mangled-name> ...]") { CommandArgumentEntry arg; CommandArgumentData index_arg; @@ -583,7 +583,11 @@ ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread( ValueObjectSP exception = ValueObject::CreateValueObjectFromData( "exception", exception_isw.GetAsData(m_process->GetByteOrder()), exe_ctx, voidstar); - exception = exception->GetDynamicValue(eDynamicDontRunTarget); + ValueObjectSP dyn_exception + = exception->GetDynamicValue(eDynamicDontRunTarget); + // If we succeed in making a dynamic value, return that: + if (dyn_exception) + return dyn_exception; return exception; } 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 438842db4eec..39969520b745 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,8 +10,10 @@ #include "lldb/Expression/FunctionCaller.h" #include "lldb/Target/ABI.h" +#include "lldb/Target/Language.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" +#include "lldb/lldb-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -370,6 +372,155 @@ bool ClassDescriptorV2::ivar_t::Read(Process *process, lldb::addr_t addr) { return !error.Fail(); } +bool ClassDescriptorV2::relative_list_entry_t::Read(Process *process, + lldb::addr_t addr) { + Log *log = GetLog(LLDBLog::Types); + size_t size = sizeof(uint64_t); // m_image_index : 16 + // m_list_offset : 48 + + DataBufferHeap buffer(size, '\0'); + Status error; + + process->ReadMemory(addr, buffer.GetBytes(), size, error); + // FIXME: Propagate this error up + if (error.Fail()) { + LLDB_LOG(log, "Failed to read relative_list_entry_t at address {0:x}", + addr); + return false; + } + + DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), + process->GetAddressByteSize()); + lldb::offset_t cursor = 0; + uint64_t raw_entry = extractor.GetU64_unchecked(&cursor); + m_image_index = raw_entry & 0xFFFF; + m_list_offset = (int64_t)(raw_entry >> 16); + return true; +} + +bool ClassDescriptorV2::relative_list_list_t::Read(Process *process, + lldb::addr_t addr) { + Log *log = GetLog(LLDBLog::Types); + size_t size = sizeof(uint32_t) // m_entsize + + sizeof(uint32_t); // m_count + + DataBufferHeap buffer(size, '\0'); + Status error; + + // FIXME: Propagate this error up + process->ReadMemory(addr, buffer.GetBytes(), size, error); + if (error.Fail()) { + LLDB_LOG(log, "Failed to read relative_list_list_t at address 0x" PRIx64, + addr); + return false; + } + + DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), + process->GetAddressByteSize()); + lldb::offset_t cursor = 0; + m_entsize = extractor.GetU32_unchecked(&cursor); + m_count = extractor.GetU32_unchecked(&cursor); + m_first_ptr = addr + cursor; + return true; +} + +std::optional<ClassDescriptorV2::method_list_t> +ClassDescriptorV2::GetMethodList(Process *process, + lldb::addr_t method_list_ptr) const { + Log *log = GetLog(LLDBLog::Types); + ClassDescriptorV2::method_list_t method_list; + if (!method_list.Read(process, method_list_ptr)) + return std::nullopt; + + const size_t method_size = method_t::GetSize(process, method_list.m_is_small); + if (method_list.m_entsize != method_size) { + LLDB_LOG(log, + "method_list_t at address 0x" PRIx64 " has an entsize of " PRIu16 + " but method size should be " PRIu64, + method_list_ptr, method_list.m_entsize, method_size); + return std::nullopt; + } + + return method_list; +} + +bool ClassDescriptorV2::ProcessMethodList( + std::function<bool(const char *, const char *)> const &instance_method_func, + ClassDescriptorV2::method_list_t &method_list) const { + lldb_private::Process *process = m_runtime.GetProcess(); + auto method = std::make_unique<method_t>(); + lldb::addr_t relative_selector_base_addr = + m_runtime.GetRelativeSelectorBaseAddr(); + for (uint32_t i = 0, e = method_list.m_count; i < e; ++i) { + method->Read(process, method_list.m_first_ptr + (i * method_list.m_entsize), + relative_selector_base_addr, method_list.m_is_small, + method_list.m_has_direct_selector); + if (instance_method_func(method->m_name.c_str(), method->m_types.c_str())) + break; + } + return true; +} + +// The relevant data structures: +// - relative_list_list_t +// - uint32_t count +// - uint32_t entsize +// - Followed by <count> number of relative_list_entry_t of size <entsize> +// +// - relative_list_entry_t +// - uint64_t image_index : 16 +// - int64_t list_offset : 48 +// - Note: The above 2 fit into 8 bytes always +// +// image_index corresponds to an image in the shared cache +// list_offset is used to calculate the address of the method_list_t we want +bool ClassDescriptorV2::ProcessRelativeMethodLists( + std::function<bool(const char *, const char *)> const &instance_method_func, + lldb::addr_t relative_method_list_ptr) const { + lldb_private::Process *process = m_runtime.GetProcess(); + auto relative_method_lists = std::make_unique<relative_list_list_t>(); + + // 1. Process the count and entsize of the relative_list_list_t + if (!relative_method_lists->Read(process, relative_method_list_ptr)) + return false; + + auto entry = std::make_unique<relative_list_entry_t>(); + for (uint32_t i = 0; i < relative_method_lists->m_count; i++) { + // 2. Extract the image index and the list offset from the + // relative_list_entry_t + const lldb::addr_t entry_addr = relative_method_lists->m_first_ptr + + (i * relative_method_lists->m_entsize); + if (!entry->Read(process, entry_addr)) + return false; + + // 3. Calculate the pointer to the method_list_t from the + // relative_list_entry_t + const lldb::addr_t method_list_addr = entry_addr + entry->m_list_offset; + + // 4. Get the method_list_t from the pointer + std::optional<method_list_t> method_list = + GetMethodList(process, method_list_addr); + if (!method_list) + return false; + + // 5. Cache the result so we don't need to reconstruct it later. + m_image_to_method_lists[entry->m_image_index].emplace_back(*method_list); + + // 6. If the relevant image is loaded, add the methods to the Decl + if (!m_runtime.IsSharedCacheImageLoaded(entry->m_image_index)) + continue; + + if (!ProcessMethodList(instance_method_func, *method_list)) + return false; + } + + // We need to keep track of the last time we updated so we can re-update the + // type information in the future + m_last_version_updated = m_runtime.GetSharedCacheImageHeaderVersion(); + + return true; +} + bool ClassDescriptorV2::Describe( std::function<void(ObjCLanguageRuntime::ObjCISA)> const &superclass_func, std::function<bool(const char *, const char *)> const &instance_method_func, @@ -393,29 +544,18 @@ bool ClassDescriptorV2::Describe( superclass_func(objc_class->m_superclass); if (instance_method_func) { - std::unique_ptr<method_list_t> base_method_list; - - base_method_list = std::make_unique<method_list_t>(); - if (!base_method_list->Read(process, class_ro->m_baseMethods_ptr)) - return false; - - bool is_small = base_method_list->m_is_small; - bool has_direct_selector = base_method_list->m_has_direct_selector; - - if (base_method_list->m_entsize != method_t::GetSize(process, is_small)) - return false; - - std::unique_ptr<method_t> method = std::make_unique<method_t>(); - lldb::addr_t relative_selector_base_addr = - m_runtime.GetRelativeSelectorBaseAddr(); - for (uint32_t i = 0, e = base_method_list->m_count; i < e; ++i) { - method->Read(process, - base_method_list->m_first_ptr + - (i * base_method_list->m_entsize), - relative_selector_base_addr, is_small, has_direct_selector); - - if (instance_method_func(method->m_name.c_str(), method->m_types.c_str())) - break; + // This is a relative list of lists + if (class_ro->m_baseMethods_ptr & 1) { + if (!ProcessRelativeMethodLists(instance_method_func, + class_ro->m_baseMethods_ptr ^ 1)) + return false; + } else { + std::optional<method_list_t> base_method_list = + GetMethodList(process, class_ro->m_baseMethods_ptr); + if (!base_method_list) + return false; + if (!ProcessMethodList(instance_method_func, *base_method_list)) + return false; } } @@ -530,6 +670,19 @@ uint64_t ClassDescriptorV2::GetInstanceSize() { return 0; } +// From the ObjC runtime. +static uint8_t IS_SWIFT_STABLE = 1U << 1; + +LanguageType ClassDescriptorV2::GetImplementationLanguage() const { + std::unique_ptr<objc_class_t> objc_class; + if (auto *process = m_runtime.GetProcess()) + if (Read_objc_class(process, objc_class)) + if (objc_class->m_flags & IS_SWIFT_STABLE) + return lldb::eLanguageTypeSwift; + + return lldb::eLanguageTypeObjC; +} + ClassDescriptorV2::iVarsStorage::iVarsStorage() : m_ivars(), m_mutex() {} size_t ClassDescriptorV2::iVarsStorage::size() { return m_ivars.size(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h index 0c6eccab9f27..d298af92ba5e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h @@ -12,6 +12,7 @@ #include <mutex> #include "AppleObjCRuntimeV2.h" +#include "lldb/lldb-enumerations.h" #include "lldb/lldb-private.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" @@ -34,6 +35,8 @@ public: return true; // any Objective-C v2 runtime class descriptor we vend is valid } + lldb::LanguageType GetImplementationLanguage() const override; + // a custom descriptor is used for tagged pointers bool GetTaggedPointerInfo(uint64_t *info_bits = nullptr, uint64_t *value_bits = nullptr, @@ -146,6 +149,9 @@ private: bool Read(Process *process, lldb::addr_t addr); }; + std::optional<method_list_t> + GetMethodList(Process *process, lldb::addr_t method_list_ptr) const; + struct method_t { lldb::addr_t m_name_ptr; lldb::addr_t m_types_ptr; @@ -201,6 +207,21 @@ private: bool Read(Process *process, lldb::addr_t addr); }; + struct relative_list_entry_t { + uint16_t m_image_index; + int64_t m_list_offset; + + bool Read(Process *process, lldb::addr_t addr); + }; + + struct relative_list_list_t { + uint32_t m_entsize; + uint32_t m_count; + lldb::addr_t m_first_ptr; + + bool Read(Process *process, lldb::addr_t addr); + }; + class iVarsStorage { public: iVarsStorage(); @@ -223,7 +244,8 @@ private: ClassDescriptorV2(AppleObjCRuntimeV2 &runtime, ObjCLanguageRuntime::ObjCISA isa, const char *name) : m_runtime(runtime), m_objc_class_ptr(isa), m_name(name), - m_ivars_storage() {} + m_ivars_storage(), m_image_to_method_lists(), m_last_version_updated() { + } bool Read_objc_class(Process *process, std::unique_ptr<objc_class_t> &objc_class) const; @@ -232,6 +254,15 @@ private: std::unique_ptr<class_ro_t> &class_ro, std::unique_ptr<class_rw_t> &class_rw) const; + bool ProcessMethodList(std::function<bool(const char *, const char *)> const + &instance_method_func, + method_list_t &method_list) const; + + bool ProcessRelativeMethodLists( + std::function<bool(const char *, const char *)> const + &instance_method_func, + lldb::addr_t relative_method_list_ptr) const; + AppleObjCRuntimeV2 &m_runtime; // The runtime, so we can read information lazily. lldb::addr_t m_objc_class_ptr; // The address of the objc_class_t. (I.e., @@ -239,6 +270,10 @@ private: // their ISA) ConstString m_name; // May be NULL iVarsStorage m_ivars_storage; + + mutable std::map<uint16_t, std::vector<method_list_t>> + m_image_to_method_lists; + mutable std::optional<uint64_t> m_last_version_updated; }; // tagged pointer descriptor 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 4d6c86f7d28c..2764a2aa39fa 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 @@ -502,10 +502,10 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) { return false; }; - LLDB_LOG(log, - "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C " - "interface for %s", - descriptor->GetClassName().AsCString()); + LLDB_LOGF(log, + "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C " + "interface for %s", + descriptor->GetClassName().AsCString()); if (!descriptor->Describe(superclass_func, instance_method_func, class_method_func, ivar_func)) @@ -563,9 +563,9 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append, if (metadata) isa_value = metadata->GetISAPtr(); - LLDB_LOG(log, - "AOCTV::FT Found %s (isa 0x%" PRIx64 ") in the ASTContext", - result_iface_type.getAsString(), isa_value); + LLDB_LOGF(log, + "AOCTV::FT Found %s (isa 0x%" PRIx64 ") in the ASTContext", + result_iface_type.getAsString().data(), isa_value); } decls.push_back(m_ast_ctx->GetCompilerDecl(result_iface_decl)); diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index a413c846b0c0..80c7bd071d6b 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 @@ -156,7 +156,7 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value, thread = exe_ctx.GetThreadPtr(); } if (thread) { - exe_ctx.SetFrameSP(thread->GetSelectedFrame()); + exe_ctx.SetFrameSP(thread->GetSelectedFrame(DoNoSelectMostRelevantFrame)); } } @@ -514,7 +514,7 @@ static ThreadSP FailExceptionParsing(llvm::StringRef msg) { ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( lldb::ValueObjectSP exception_sp) { ValueObjectSP reserved_dict = - exception_sp->GetChildMemberWithName(ConstString("reserved"), true); + exception_sp->GetChildMemberWithName("reserved"); if (!reserved_dict) return FailExceptionParsing("Failed to get 'reserved' member."); @@ -540,7 +540,7 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( }; for (size_t idx = 0; idx < reserved_dict->GetNumChildren(); idx++) { - ValueObjectSP dict_entry = reserved_dict->GetChildAtIndex(idx, true); + ValueObjectSP dict_entry = reserved_dict->GetChildAtIndex(idx); DataExtractor data; data.SetAddressByteSize(dict_entry->GetProcessSP()->GetAddressByteSize()); @@ -567,18 +567,15 @@ ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( if (!return_addresses) return FailExceptionParsing("Failed to get return addresses."); - auto frames_value = - return_addresses->GetChildMemberWithName(ConstString("_frames"), true); + auto frames_value = return_addresses->GetChildMemberWithName("_frames"); if (!frames_value) return FailExceptionParsing("Failed to get frames_value."); addr_t frames_addr = frames_value->GetValueAsUnsigned(0); - auto count_value = - return_addresses->GetChildMemberWithName(ConstString("_cnt"), true); + auto count_value = return_addresses->GetChildMemberWithName("_cnt"); if (!count_value) return FailExceptionParsing("Failed to get count_value."); size_t count = count_value->GetValueAsUnsigned(0); - auto ignore_value = - return_addresses->GetChildMemberWithName(ConstString("_ignore"), true); + auto ignore_value = return_addresses->GetChildMemberWithName("_ignore"); if (!ignore_value) return FailExceptionParsing("Failed to get ignore_value."); size_t ignore = ignore_value->GetValueAsUnsigned(0); 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 7d376f2b9ac1..d5357b94d68e 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 @@ -33,6 +33,7 @@ #include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -753,6 +754,19 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, RegisterObjCExceptionRecognizer(process); } +LanguageRuntime * +AppleObjCRuntimeV2::GetPreferredLanguageRuntime(ValueObject &in_value) { + if (auto process_sp = in_value.GetProcessSP()) { + assert(process_sp.get() == m_process); + if (auto descriptor_sp = GetNonKVOClassDescriptor(in_value)) { + LanguageType impl_lang = descriptor_sp->GetImplementationLanguage(); + if (impl_lang != eLanguageTypeUnknown) + return process_sp->GetLanguageRuntime(impl_lang); + } + } + return nullptr; +} + bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress( ValueObject &in_value, lldb::DynamicValueType use_dynamic, TypeAndOrName &class_type_or_name, Address &address, @@ -1619,6 +1633,146 @@ lldb::addr_t AppleObjCRuntimeV2::GetISAHashTablePointer() { return m_isa_hash_table_ptr; } +std::unique_ptr<AppleObjCRuntimeV2::SharedCacheImageHeaders> +AppleObjCRuntimeV2::SharedCacheImageHeaders::CreateSharedCacheImageHeaders( + AppleObjCRuntimeV2 &runtime) { + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); + Process *process = runtime.GetProcess(); + ModuleSP objc_module_sp(runtime.GetObjCModule()); + if (!objc_module_sp || !process) + return nullptr; + + const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType( + ConstString("objc_debug_headerInfoRWs"), lldb::eSymbolTypeAny); + if (!symbol) { + LLDB_LOG(log, "Symbol 'objc_debug_headerInfoRWs' unavailable. Some " + "information concerning the shared cache may be unavailable"); + return nullptr; + } + + lldb::addr_t objc_debug_headerInfoRWs_addr = + symbol->GetLoadAddress(&process->GetTarget()); + if (objc_debug_headerInfoRWs_addr == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "Symbol 'objc_debug_headerInfoRWs' was found but we were " + "unable to get its load address"); + return nullptr; + } + + Status error; + lldb::addr_t objc_debug_headerInfoRWs_ptr = + process->ReadPointerFromMemory(objc_debug_headerInfoRWs_addr, error); + if (error.Fail()) { + LLDB_LOG(log, + "Failed to read address of 'objc_debug_headerInfoRWs' at {0:x}", + objc_debug_headerInfoRWs_addr); + return nullptr; + } + + const size_t metadata_size = + sizeof(uint32_t) + sizeof(uint32_t); // count + entsize + DataBufferHeap metadata_buffer(metadata_size, '\0'); + process->ReadMemory(objc_debug_headerInfoRWs_ptr, metadata_buffer.GetBytes(), + metadata_size, error); + if (error.Fail()) { + LLDB_LOG(log, + "Unable to read metadata for 'objc_debug_headerInfoRWs' at {0:x}", + objc_debug_headerInfoRWs_ptr); + return nullptr; + } + + DataExtractor metadata_extractor(metadata_buffer.GetBytes(), metadata_size, + process->GetByteOrder(), + process->GetAddressByteSize()); + lldb::offset_t cursor = 0; + uint32_t count = metadata_extractor.GetU32_unchecked(&cursor); + uint32_t entsize = metadata_extractor.GetU32_unchecked(&cursor); + if (count == 0 || entsize == 0) { + LLDB_LOG(log, + "'objc_debug_headerInfoRWs' had count {0} with entsize {1}. These " + "should both be non-zero.", + count, entsize); + return nullptr; + } + + std::unique_ptr<SharedCacheImageHeaders> shared_cache_image_headers( + new SharedCacheImageHeaders(runtime, objc_debug_headerInfoRWs_ptr, count, + entsize)); + if (auto Err = shared_cache_image_headers->UpdateIfNeeded()) { + LLDB_LOG_ERROR(log, std::move(Err), + "Failed to update SharedCacheImageHeaders: {0}"); + return nullptr; + } + + return shared_cache_image_headers; +} + +llvm::Error AppleObjCRuntimeV2::SharedCacheImageHeaders::UpdateIfNeeded() { + if (!m_needs_update) + return llvm::Error::success(); + + Process *process = m_runtime.GetProcess(); + constexpr lldb::addr_t metadata_size = + sizeof(uint32_t) + sizeof(uint32_t); // count + entsize + + Status error; + const lldb::addr_t first_header_addr = m_headerInfoRWs_ptr + metadata_size; + DataBufferHeap header_buffer(m_entsize, '\0'); + lldb::offset_t cursor = 0; + for (uint32_t i = 0; i < m_count; i++) { + const lldb::addr_t header_addr = first_header_addr + (i * m_entsize); + process->ReadMemory(header_addr, header_buffer.GetBytes(), m_entsize, + error); + if (error.Fail()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "Failed to read memory from inferior when " + "populating SharedCacheImageHeaders"); + + DataExtractor header_extractor(header_buffer.GetBytes(), m_entsize, + process->GetByteOrder(), + process->GetAddressByteSize()); + cursor = 0; + bool is_loaded = false; + if (m_entsize == 4) { + uint32_t header = header_extractor.GetU32_unchecked(&cursor); + if (header & 1) + is_loaded = true; + } else { + uint64_t header = header_extractor.GetU64_unchecked(&cursor); + if (header & 1) + is_loaded = true; + } + + if (is_loaded) + m_loaded_images.set(i); + else + m_loaded_images.reset(i); + } + m_needs_update = false; + m_version++; + return llvm::Error::success(); +} + +bool AppleObjCRuntimeV2::SharedCacheImageHeaders::IsImageLoaded( + uint16_t image_index) { + if (image_index >= m_count) + return false; + if (auto Err = UpdateIfNeeded()) { + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); + LLDB_LOG_ERROR(log, std::move(Err), + "Failed to update SharedCacheImageHeaders: {0}"); + } + return m_loaded_images.test(image_index); +} + +uint64_t AppleObjCRuntimeV2::SharedCacheImageHeaders::GetVersion() { + if (auto Err = UpdateIfNeeded()) { + Log *log = GetLog(LLDBLog::Process | LLDBLog::Types); + LLDB_LOG_ERROR(log, std::move(Err), + "Failed to update SharedCacheImageHeaders: {0}"); + } + return m_version; +} + std::unique_ptr<UtilityFunction> AppleObjCRuntimeV2::DynamicClassInfoExtractor::GetClassInfoUtilityFunctionImpl( ExecutionContext &exe_ctx, Helper helper, std::string code, @@ -2168,7 +2322,10 @@ AppleObjCRuntimeV2::SharedCacheClassInfoExtractor::UpdateISAToDescriptorMap() { // The number of entries to pre-allocate room for. // Each entry is (addrsize + 4) bytes - const uint32_t max_num_classes = 163840; + // FIXME: It is not sustainable to continue incrementing this value every time + // the shared cache grows. This is because it requires allocating memory in + // the inferior process and some inferior processes have small memory limits. + const uint32_t max_num_classes = 212992; UtilityFunction *get_class_info_code = GetClassInfoUtilityFunction(exe_ctx); if (!get_class_info_code) { @@ -2370,7 +2527,7 @@ lldb::addr_t AppleObjCRuntimeV2::GetSharedCacheBaseAddress() { if (!value) return LLDB_INVALID_ADDRESS; - return value->GetIntegerValue(LLDB_INVALID_ADDRESS); + return value->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS); } void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { @@ -3239,6 +3396,34 @@ void AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, this->AppleObjCRuntime::GetValuesForGlobalCFBooleans(cf_true, cf_false); } +void AppleObjCRuntimeV2::ModulesDidLoad(const ModuleList &module_list) { + AppleObjCRuntime::ModulesDidLoad(module_list); + if (HasReadObjCLibrary() && m_shared_cache_image_headers_up) + m_shared_cache_image_headers_up->SetNeedsUpdate(); +} + +bool AppleObjCRuntimeV2::IsSharedCacheImageLoaded(uint16_t image_index) { + if (!m_shared_cache_image_headers_up) { + m_shared_cache_image_headers_up = + SharedCacheImageHeaders::CreateSharedCacheImageHeaders(*this); + } + if (m_shared_cache_image_headers_up) + return m_shared_cache_image_headers_up->IsImageLoaded(image_index); + + return false; +} + +std::optional<uint64_t> AppleObjCRuntimeV2::GetSharedCacheImageHeaderVersion() { + if (!m_shared_cache_image_headers_up) { + m_shared_cache_image_headers_up = + SharedCacheImageHeaders::CreateSharedCacheImageHeaders(*this); + } + if (m_shared_cache_image_headers_up) + return m_shared_cache_image_headers_up->GetVersion(); + + return std::nullopt; +} + #pragma mark Frame recognizers class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame { 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 bc8738094316..678865ecd918 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 @@ -19,6 +19,8 @@ #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" +#include "llvm/ADT/BitVector.h" + class RemoteNXMapTable; namespace lldb_private { @@ -36,6 +38,8 @@ public: static llvm::StringRef GetPluginNameStatic() { return "apple-objc-v2"; } + LanguageRuntime *GetPreferredLanguageRuntime(ValueObject &in_value) override; + static char ID; bool isA(const void *ClassID) const override { @@ -96,17 +100,11 @@ public: void GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, lldb::addr_t &cf_false) override; - // none of these are valid ISAs - we use them to infer the type - // of tagged pointers - if we have something meaningful to say - // we report an actual type - otherwise, we just say tagged - // there is no connection between the values here and the tagged pointers map - static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1; - static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2; - static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3; - static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4; - static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSManagedObject = - 5; - static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDate = 6; + void ModulesDidLoad(const ModuleList &module_list) override; + + bool IsSharedCacheImageLoaded(uint16_t image_index); + + std::optional<uint64_t> GetSharedCacheImageHeaderVersion(); protected: lldb::BreakpointResolverSP @@ -386,6 +384,35 @@ private: lldb::addr_t m_args = LLDB_INVALID_ADDRESS; }; + class SharedCacheImageHeaders { + public: + static std::unique_ptr<SharedCacheImageHeaders> + CreateSharedCacheImageHeaders(AppleObjCRuntimeV2 &runtime); + + void SetNeedsUpdate() { m_needs_update = true; } + + bool IsImageLoaded(uint16_t image_index); + + uint64_t GetVersion(); + + private: + SharedCacheImageHeaders(AppleObjCRuntimeV2 &runtime, + lldb::addr_t headerInfoRWs_ptr, uint32_t count, + uint32_t entsize) + : m_runtime(runtime), m_headerInfoRWs_ptr(headerInfoRWs_ptr), + m_loaded_images(count, false), m_version(0), m_count(count), + m_entsize(entsize), m_needs_update(true) {} + llvm::Error UpdateIfNeeded(); + + AppleObjCRuntimeV2 &m_runtime; + lldb::addr_t m_headerInfoRWs_ptr; + llvm::BitVector m_loaded_images; + uint64_t m_version; + uint32_t m_count; + uint32_t m_entsize; + bool m_needs_update; + }; + AppleObjCRuntimeV2(Process *process, const lldb::ModuleSP &objc_module_sp); ObjCISA GetPointerISA(ObjCISA isa); @@ -447,6 +474,7 @@ private: std::once_flag m_no_expanded_cache_warning; std::optional<std::pair<lldb::addr_t, lldb::addr_t>> m_CFBoolean_values; uint64_t m_realized_class_generation_count; + std::unique_ptr<SharedCacheImageHeaders> m_shared_cache_image_headers_up; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp index 987726379623..2cc5319c84bb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp @@ -234,15 +234,12 @@ clang::QualType AppleObjCTypeEncodingParser::BuildObjCObjectPointerType( auto types = decl_vendor->FindTypes(ConstString(name), /*max_matches*/ 1); -// The user can forward-declare something that has no definition. The runtime -// doesn't prohibit this at all. This is a rare and very weird case. We keep -// this assert in debug builds so we catch other weird cases. -#ifdef LLDB_CONFIGURATION_DEBUG - assert(!types.empty()); -#else + // The user can forward-declare something that has no definition. The runtime + // doesn't prohibit this at all. This is a rare and very weird case. We keep + // this assert in debug builds so we catch other weird cases. + lldbassert(!types.empty()); if (types.empty()) return ast_ctx.getObjCIdType(); -#endif return ClangUtil::GetQualType(types.front().GetPointerType()); } else { diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp new file mode 100644 index 000000000000..fb2656ef1385 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.cpp @@ -0,0 +1,204 @@ +//===-- GNUstepObjCRuntime.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 "GNUstepObjCRuntime.h" + +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/ValueObject.h" +#include "lldb/Expression/UtilityFunction.h" +#include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/ConstString.h" + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(GNUstepObjCRuntime) + +char GNUstepObjCRuntime::ID = 0; + +void GNUstepObjCRuntime::Initialize() { + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "GNUstep Objective-C Language Runtime - libobjc2", + CreateInstance); +} + +void GNUstepObjCRuntime::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +LanguageRuntime *GNUstepObjCRuntime::CreateInstance(Process *process, + LanguageType language) { + if (language != eLanguageTypeObjC) + return nullptr; + if (!process) + return nullptr; + + Target &target = process->GetTarget(); + const llvm::Triple &TT = target.GetArchitecture().GetTriple(); + if (TT.getVendor() == llvm::Triple::VendorType::Apple) + return nullptr; + + const ModuleList &images = target.GetImages(); + if (TT.isOSBinFormatELF()) { + SymbolContextList eh_pers; + RegularExpression regex("__gnustep_objc[x]*_personality_v[0-9]+"); + images.FindSymbolsMatchingRegExAndType(regex, eSymbolTypeCode, eh_pers); + if (eh_pers.GetSize() == 0) + return nullptr; + } else if (TT.isOSWindows()) { + SymbolContextList objc_mandatory; + images.FindSymbolsWithNameAndType(ConstString("__objc_load"), + eSymbolTypeCode, objc_mandatory); + if (objc_mandatory.GetSize() == 0) + return nullptr; + } + + return new GNUstepObjCRuntime(process); +} + +GNUstepObjCRuntime::~GNUstepObjCRuntime() = default; + +GNUstepObjCRuntime::GNUstepObjCRuntime(Process *process) + : ObjCLanguageRuntime(process), m_objc_module_sp(nullptr) { + ReadObjCLibraryIfNeeded(process->GetTarget().GetImages()); +} + +bool GNUstepObjCRuntime::GetObjectDescription(Stream &str, + ValueObject &valobj) { + // TODO: ObjC has a generic way to do this + return false; +} +bool GNUstepObjCRuntime::GetObjectDescription( + Stream &strm, Value &value, ExecutionContextScope *exe_scope) { + // TODO: ObjC has a generic way to do this + return false; +} + +bool GNUstepObjCRuntime::CouldHaveDynamicValue(ValueObject &in_value) { + static constexpr bool check_cxx = false; + static constexpr bool check_objc = true; + return in_value.GetCompilerType().IsPossibleDynamicType(nullptr, check_cxx, + check_objc); +} + +bool GNUstepObjCRuntime::GetDynamicTypeAndAddress( + ValueObject &in_value, DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, Address &address, + Value::ValueType &value_type) { + return false; +} + +TypeAndOrName +GNUstepObjCRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, + ValueObject &static_value) { + CompilerType static_type(static_value.GetCompilerType()); + Flags static_type_flags(static_type.GetTypeInfo()); + + TypeAndOrName ret(type_and_or_name); + if (type_and_or_name.HasType()) { + // The type will always be the type of the dynamic object. If our parent's + // type was a pointer, then our type should be a pointer to the type of the + // dynamic object. If a reference, then the original type should be + // okay... + CompilerType orig_type = type_and_or_name.GetCompilerType(); + CompilerType corrected_type = orig_type; + if (static_type_flags.AllSet(eTypeIsPointer)) + corrected_type = orig_type.GetPointerType(); + ret.SetCompilerType(corrected_type); + } else { + // If we are here we need to adjust our dynamic type name to include the + // correct & or * symbol + std::string corrected_name(type_and_or_name.GetName().GetCString()); + if (static_type_flags.AllSet(eTypeIsPointer)) + corrected_name.append(" *"); + // the parent type should be a correctly pointer'ed or referenc'ed type + ret.SetCompilerType(static_type); + ret.SetName(corrected_name.c_str()); + } + return ret; +} + +BreakpointResolverSP +GNUstepObjCRuntime::CreateExceptionResolver(const BreakpointSP &bkpt, + bool catch_bp, bool throw_bp) { + BreakpointResolverSP resolver_sp; + + if (throw_bp) + resolver_sp = std::make_shared<BreakpointResolverName>( + bkpt, "objc_exception_throw", eFunctionNameTypeBase, + eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo); + + return resolver_sp; +} + +llvm::Expected<std::unique_ptr<UtilityFunction>> +GNUstepObjCRuntime::CreateObjectChecker(std::string name, + ExecutionContext &exe_ctx) { + // TODO: This function is supposed to check whether an ObjC selector is + // present for an object. Might be implemented similar as in the Apple V2 + // runtime. + const char *function_template = R"( + extern "C" void + %s(void *$__lldb_arg_obj, void *$__lldb_arg_selector) {} + )"; + + char empty_function_code[2048]; + int len = ::snprintf(empty_function_code, sizeof(empty_function_code), + function_template, name.c_str()); + + assert(len < (int)sizeof(empty_function_code)); + UNUSED_IF_ASSERT_DISABLED(len); + + return GetTargetRef().CreateUtilityFunction(empty_function_code, name, + eLanguageTypeC, exe_ctx); +} + +ThreadPlanSP +GNUstepObjCRuntime::GetStepThroughTrampolinePlan(Thread &thread, + bool stop_others) { + // TODO: Implement this properly to avoid stepping into things like PLT stubs + return nullptr; +} + +void GNUstepObjCRuntime::UpdateISAToDescriptorMapIfNeeded() { + // TODO: Support lazily named and dynamically loaded Objective-C classes +} + +bool GNUstepObjCRuntime::IsModuleObjCLibrary(const ModuleSP &module_sp) { + if (!module_sp) + return false; + const FileSpec &module_file_spec = module_sp->GetFileSpec(); + if (!module_file_spec) + return false; + llvm::StringRef filename = module_file_spec.GetFilename().GetStringRef(); + const llvm::Triple &TT = GetTargetRef().GetArchitecture().GetTriple(); + if (TT.isOSBinFormatELF()) + return filename.starts_with("libobjc.so"); + if (TT.isOSWindows()) + return filename == "objc.dll"; + return false; +} + +bool GNUstepObjCRuntime::ReadObjCLibrary(const ModuleSP &module_sp) { + assert(m_objc_module_sp == nullptr && "Check HasReadObjCLibrary() first"); + m_objc_module_sp = module_sp; + + // Right now we don't use this, but we might want to check for debugger + // runtime support symbols like 'gdb_object_getClass' in the future. + return true; +} + +void GNUstepObjCRuntime::ModulesDidLoad(const ModuleList &module_list) { + ReadObjCLibraryIfNeeded(module_list); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h new file mode 100644 index 000000000000..b22088807f97 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/GNUstepObjCRuntime/GNUstepObjCRuntime.h @@ -0,0 +1,111 @@ +//===-- GNUstepObjCRuntime.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_LANGUAGERUNTIME_OBJC_GNUSTEPOBJCRUNTIME_GNUSTEPOBJCRUNTIME_H +#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_GNUSTEPOBJCRUNTIME_GNUSTEPOBJCRUNTIME_H + +#include "lldb/Target/LanguageRuntime.h" +#include "lldb/lldb-private.h" + +#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" + +#include <optional> + +namespace lldb_private { + +class GNUstepObjCRuntime : public lldb_private::ObjCLanguageRuntime { +public: + ~GNUstepObjCRuntime() override; + + // + // PluginManager, PluginInterface and LLVM RTTI implementation + // + + static char ID; + + static void Initialize(); + + static void Terminate(); + + static lldb_private::LanguageRuntime * + CreateInstance(Process *process, lldb::LanguageType language); + + static llvm::StringRef GetPluginNameStatic() { + return "gnustep-objc-libobjc2"; + } + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + void ModulesDidLoad(const ModuleList &module_list) override; + + bool isA(const void *ClassID) const override { + return ClassID == &ID || ObjCLanguageRuntime::isA(ClassID); + } + + static bool classof(const LanguageRuntime *runtime) { + return runtime->isA(&ID); + } + + // + // LanguageRuntime implementation + // + bool GetObjectDescription(Stream &str, Value &value, + ExecutionContextScope *exe_scope) override; + + bool GetObjectDescription(Stream &str, ValueObject &object) override; + + bool CouldHaveDynamicValue(ValueObject &in_value) override; + + bool GetDynamicTypeAndAddress(ValueObject &in_value, + lldb::DynamicValueType use_dynamic, + TypeAndOrName &class_type_or_name, + Address &address, + Value::ValueType &value_type) override; + + TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, + ValueObject &static_value) override; + + lldb::BreakpointResolverSP + CreateExceptionResolver(const lldb::BreakpointSP &bkpt, bool catch_bp, + bool throw_bp) override; + + lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, + bool stop_others) override; + + // + // ObjCLanguageRuntime implementation + // + + bool IsModuleObjCLibrary(const lldb::ModuleSP &module_sp) override; + + bool ReadObjCLibrary(const lldb::ModuleSP &module_sp) override; + + bool HasReadObjCLibrary() override { return m_objc_module_sp != nullptr; } + + llvm::Expected<std::unique_ptr<UtilityFunction>> + CreateObjectChecker(std::string name, ExecutionContext &exe_ctx) override; + + ObjCRuntimeVersions GetRuntimeVersion() const override { + return ObjCRuntimeVersions::eGNUstep_libobjc2; + } + + void UpdateISAToDescriptorMapIfNeeded() override; + +protected: + // Call CreateInstance instead. + GNUstepObjCRuntime(Process *process); + + lldb::ModuleSP m_objc_module_sp; +}; + +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_OBJC_GNUSTEPOBJCRUNTIME_GNUSTEPOBJCRUNTIME_H 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 e28f224101bb..214642f654e2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp @@ -235,6 +235,22 @@ ObjCLanguageRuntime::GetDescriptorIteratorPair(bool update_if_needed) { m_isa_to_descriptor.begin(), m_isa_to_descriptor.end()); } +void ObjCLanguageRuntime::ReadObjCLibraryIfNeeded( + const ModuleList &module_list) { + if (!HasReadObjCLibrary()) { + std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); + + size_t num_modules = module_list.GetSize(); + for (size_t i = 0; i < num_modules; i++) { + auto mod = module_list.GetModuleAtIndex(i); + if (IsModuleObjCLibrary(mod)) { + ReadObjCLibrary(mod); + break; + } + } + } +} + ObjCLanguageRuntime::ObjCISA ObjCLanguageRuntime::GetParentClass(ObjCLanguageRuntime::ObjCISA isa) { ClassDescriptorSP objc_class_sp(GetClassDescriptorFromISA(isa)); 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 f968a090c0f7..0a8b6e8d56ed 100644 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h +++ b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h @@ -19,11 +19,12 @@ #include "lldb/Breakpoint/BreakpointPrecondition.h" #include "lldb/Core/PluginInterface.h" -#include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Type.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/ThreadSafeDenseMap.h" +#include "lldb/lldb-enumerations.h" #include "lldb/lldb-private.h" class CommandObjectObjC_ClassTable_Dump; @@ -38,7 +39,8 @@ public: enum class ObjCRuntimeVersions { eObjC_VersionUnknown = 0, eAppleObjC_V1 = 1, - eAppleObjC_V2 = 2 + eAppleObjC_V2 = 2, + eGNUstep_libobjc2 = 3, }; typedef lldb::addr_t ObjCISA; @@ -85,6 +87,11 @@ public: return (m_is_cf == eLazyBoolYes); } + /// Determine whether this class is implemented in Swift. + virtual lldb::LanguageType GetImplementationLanguage() const { + return lldb::eLanguageTypeObjC; + } + virtual bool IsValid() = 0; /// There are two routines in the ObjC runtime that tagged pointer clients 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 deleted file mode 100644 index 2430ec3ff5d4..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp +++ /dev/null @@ -1,187 +0,0 @@ -//===-- RenderScriptExpressionOpts.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 <string> - -#include "llvm/ADT/StringRef.h" -#include "llvm/IR/Instruction.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/LegacyPassManager.h" -#include "llvm/IR/Module.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" - -#include "clang/Basic/TargetOptions.h" - -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include "lldb/Utility/LLDBLog.h" -#include "lldb/Utility/Log.h" - -#include "RenderScriptExpressionOpts.h" -#include "RenderScriptRuntime.h" -#include "RenderScriptx86ABIFixups.h" - -using namespace lldb_private; -using namespace lldb_renderscript; - -// [``slang``](https://android.googlesource.com/platform/frameworks/compile/slang), -// the compiler frontend for RenderScript embeds an ARM specific triple in IR -// that is shipped in the app, after generating IR that has some assumptions -// that an ARM device is the target. As the IR is then compiled on a device of -// unknown (at time the IR was generated at least) architecture, when calling -// RenderScript API function as part of debugger expressions, we have to -// perform a fixup pass that removes those assumptions right before the module -// is sent to be generated by the llvm backend. - -static bool registerRSDefaultTargetOpts(clang::TargetOptions &proto, - const llvm::Triple::ArchType &arch) { - switch (arch) { - case llvm::Triple::ArchType::x86: - proto.Triple = "i686--linux-android"; - proto.CPU = "atom"; - proto.Features.push_back("+long64"); - // Fallthrough for common x86 family features - [[fallthrough]]; - case llvm::Triple::ArchType::x86_64: - proto.Features.push_back("+mmx"); - proto.Features.push_back("+sse"); - proto.Features.push_back("+sse2"); - proto.Features.push_back("+sse3"); - proto.Features.push_back("+ssse3"); - proto.Features.push_back("+sse4.1"); - proto.Features.push_back("+sse4.2"); - break; - case llvm::Triple::ArchType::mipsel: - // pretend this is `arm' for the front-end - proto.Triple = "armv7-none-linux-android"; - proto.CPU = ""; - proto.Features.push_back("+long64"); - break; - case llvm::Triple::ArchType::mips64el: - // pretend this is `aarch64' for the front-end - proto.Triple = "aarch64-none-linux-android"; - proto.CPU = ""; - break; - default: - return false; - } - return true; -} - -bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) { - bool changed_module = false; - Log *log = GetLog(LLDBLog::Language | LLDBLog::Expressions); - - std::string err; - llvm::StringRef real_triple = - m_process_ptr->GetTarget().GetArchitecture().GetTriple().getTriple(); - const llvm::Target *target_info = - llvm::TargetRegistry::lookupTarget(std::string(real_triple), err); - if (!target_info) { - if (log) - log->Warning("couldn't determine real target architecture: '%s'", - err.c_str()); - return false; - } - - std::optional<llvm::Reloc::Model> reloc_model; - assert(m_process_ptr && "no available lldb process"); - switch (m_process_ptr->GetTarget().GetArchitecture().GetMachine()) { - case llvm::Triple::ArchType::x86: - changed_module |= fixupX86FunctionCalls(module); - // For some reason this triple gets totally missed by the backend, and must - // be set manually. There a reference in bcc/Main.cpp about auto feature- - // detection being removed from LLVM3.5, but I can't see that discussion - // anywhere public. - real_triple = "i686--linux-android"; - break; - case llvm::Triple::ArchType::x86_64: - changed_module |= fixupX86_64FunctionCalls(module); - break; - case llvm::Triple::ArchType::mipsel: - case llvm::Triple::ArchType::mips64el: - // No actual IR fixup pass is needed on MIPS, but the datalayout and - // targetmachine do need to be explicitly set. - - // bcc explicitly compiles MIPS code to use the static relocation model due - // to an issue with relocations in mclinker. see - // libbcc/support/CompilerConfig.cpp for details - reloc_model = llvm::Reloc::Static; - changed_module = true; - break; - case llvm::Triple::ArchType::arm: - case llvm::Triple::ArchType::aarch64: - // ARM subtargets need no fixup passes as they are the initial target as - // generated by the - // slang compiler frontend. - break; - default: - if (log) - log->Warning("Ignoring unknown renderscript target"); - return false; - } - - if (changed_module) { - llvm::TargetOptions options; - llvm::TargetMachine *target_machine = target_info->createTargetMachine( - real_triple, "", "", options, reloc_model); - assert(target_machine && - "failed to identify RenderScriptRuntime target machine"); - // We've been using a triple and datalayout of some ARM variant all along, - // so we need to let the backend know that this is no longer the case. - if (log) { - LLDB_LOGF(log, "%s - Changing RS target triple to '%s'", __FUNCTION__, - real_triple.str().c_str()); - LLDB_LOGF( - log, "%s - Changing RS datalayout to '%s'", __FUNCTION__, - target_machine->createDataLayout().getStringRepresentation().c_str()); - } - module.setTargetTriple(real_triple); - module.setDataLayout(target_machine->createDataLayout()); - } - return changed_module; -} - -char RenderScriptRuntimeModulePass::ID = 0; - -namespace lldb_private { - -bool RenderScriptRuntime::GetOverrideExprOptions(clang::TargetOptions &proto) { - auto *process = GetProcess(); - assert(process); - return registerRSDefaultTargetOpts( - proto, process->GetTarget().GetArchitecture().GetMachine()); -} - -bool RenderScriptRuntime::GetIRPasses(LLVMUserExpression::IRPasses &passes) { - if (!m_ir_passes) - m_ir_passes = new RSIRPasses(GetProcess()); - assert(m_ir_passes); - - passes.EarlyPasses = m_ir_passes->EarlyPasses; - passes.LatePasses = m_ir_passes->LatePasses; - - return true; -} - -namespace lldb_renderscript { - -RSIRPasses::RSIRPasses(Process *process) { - assert(process); - - EarlyPasses = std::make_shared<llvm::legacy::PassManager>(); - assert(EarlyPasses); - EarlyPasses->add(new RenderScriptRuntimeModulePass(process)); -} - -RSIRPasses::~RSIRPasses() = default; - -} // namespace lldb_renderscript -} // namespace lldb_private 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 deleted file mode 100644 index 61af4dc1d764..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h +++ /dev/null @@ -1,53 +0,0 @@ -//===-- RenderScriptExpressionOpts.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_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H -#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTEXPRESSIONOPTS_H - -#include "llvm/IR/Module.h" -#include "llvm/MC/TargetRegistry.h" -#include "llvm/Pass.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" - -#include "lldb/Target/LanguageRuntime.h" -#include "lldb/Target/Process.h" -#include "lldb/lldb-private.h" - -#include "RenderScriptRuntime.h" -#include "RenderScriptx86ABIFixups.h" - -// RenderScriptRuntimeModulePass is a simple llvm::ModulesPass that is used -// during expression evaluation to apply RenderScript-specific fixes for -// expression evaluation. In particular this is used to make expression IR -// conformant with the ABI generated by the slang frontend. This ModulePass is -// executed in ClangExpressionParser::PrepareForExecution whenever an -// expression's DWARF language is eLanguageTypeExtRenderscript - -class RenderScriptRuntimeModulePass : public llvm::ModulePass { -public: - static char ID; - RenderScriptRuntimeModulePass(const lldb_private::Process *process) - : ModulePass(ID), m_process_ptr(process) {} - - bool runOnModule(llvm::Module &module) override; - -private: - const lldb_private::Process *m_process_ptr; -}; - -namespace lldb_private { -namespace lldb_renderscript { -struct RSIRPasses : public lldb_private::LLVMUserExpression::IRPasses { - RSIRPasses(lldb_private::Process *process); - - ~RSIRPasses(); -}; -} // namespace lldb_renderscript -} // namespace lldb_private -#endif 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 deleted file mode 100644 index e168241fb2c9..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ /dev/null @@ -1,4937 +0,0 @@ -//===-- RenderScriptRuntime.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 "RenderScriptRuntime.h" -#include "RenderScriptScriptGroup.h" - -#include "lldb/Breakpoint/StoppointCallbackContext.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/ValueObjectVariable.h" -#include "lldb/DataFormatters/DumpValueObjectOptions.h" -#include "lldb/Expression/UserExpression.h" -#include "lldb/Host/OptionParser.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandObjectMultiword.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/Options.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Symbol/VariableList.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/Target.h" -#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" -#include "lldb/Utility/Status.h" - -#include "llvm/ADT/StringSwitch.h" - -#include <memory> - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_renderscript; - -LLDB_PLUGIN_DEFINE(RenderScriptRuntime) - -#define FMT_COORD "(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ")" - -char RenderScriptRuntime::ID = 0; - -namespace { - -// The empirical_type adds a basic level of validation to arbitrary data -// allowing us to track if data has been discovered and stored or not. An -// empirical_type will be marked as valid only if it has been explicitly -// assigned to. -template <typename type_t> class empirical_type { -public: - // Ctor. Contents is invalid when constructed. - empirical_type() = default; - - // Return true and copy contents to out if valid, else return false. - bool get(type_t &out) const { - if (valid) - out = data; - return valid; - } - - // Return a pointer to the contents or nullptr if it was not valid. - const type_t *get() const { return valid ? &data : nullptr; } - - // Assign data explicitly. - void set(const type_t in) { - data = in; - valid = true; - } - - // Mark contents as invalid. - void invalidate() { valid = false; } - - // Returns true if this type contains valid data. - bool isValid() const { return valid; } - - // Assignment operator. - empirical_type<type_t> &operator=(const type_t in) { - set(in); - return *this; - } - - // Dereference operator returns contents. - // Warning: Will assert if not valid so use only when you know data is valid. - const type_t &operator*() const { - assert(valid); - return data; - } - -protected: - bool valid = false; - type_t data; -}; - -// ArgItem is used by the GetArgs() function when reading function arguments -// from the target. -struct ArgItem { - enum { ePointer, eInt32, eInt64, eLong, eBool } type; - - uint64_t value; - - explicit operator uint64_t() const { return value; } -}; - -// Context structure to be passed into GetArgsXXX(), argument reading functions -// below. -struct GetArgsCtx { - RegisterContext *reg_ctx; - Process *process; -}; - -bool GetArgsX86(const GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { - Log *log = GetLog(LLDBLog::Language); - - Status err; - - // get the current stack pointer - uint64_t sp = ctx.reg_ctx->GetSP(); - - for (size_t i = 0; i < num_args; ++i) { - ArgItem &arg = arg_list[i]; - // advance up the stack by one argument - sp += sizeof(uint32_t); - // get the argument type size - size_t arg_size = sizeof(uint32_t); - // read the argument from memory - arg.value = 0; - Status err; - size_t read = - ctx.process->ReadMemory(sp, &arg.value, sizeof(uint32_t), err); - if (read != arg_size || !err.Success()) { - LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 " '%s'", - __FUNCTION__, uint64_t(i), err.AsCString()); - return false; - } - } - return true; -} - -bool GetArgsX86_64(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { - Log *log = GetLog(LLDBLog::Language); - - // number of arguments passed in registers - static const uint32_t args_in_reg = 6; - // register passing order - static const std::array<const char *, args_in_reg> reg_names{ - {"rdi", "rsi", "rdx", "rcx", "r8", "r9"}}; - // argument type to size mapping - static const std::array<size_t, 5> arg_size{{ - 8, // ePointer, - 4, // eInt32, - 8, // eInt64, - 8, // eLong, - 4, // eBool, - }}; - - Status err; - - // get the current stack pointer - uint64_t sp = ctx.reg_ctx->GetSP(); - // step over the return address - sp += sizeof(uint64_t); - - // check the stack alignment was correct (16 byte aligned) - if ((sp & 0xf) != 0x0) { - LLDB_LOGF(log, "%s - stack misaligned", __FUNCTION__); - return false; - } - - // find the start of arguments on the stack - uint64_t sp_offset = 0; - for (uint32_t i = args_in_reg; i < num_args; ++i) { - sp_offset += arg_size[arg_list[i].type]; - } - // round up to multiple of 16 - sp_offset = (sp_offset + 0xf) & 0xf; - sp += sp_offset; - - for (size_t i = 0; i < num_args; ++i) { - bool success = false; - ArgItem &arg = arg_list[i]; - // arguments passed in registers - if (i < args_in_reg) { - const RegisterInfo *reg = - ctx.reg_ctx->GetRegisterInfoByName(reg_names[i]); - RegisterValue reg_val; - if (ctx.reg_ctx->ReadRegister(reg, reg_val)) - arg.value = reg_val.GetAsUInt64(0, &success); - } - // arguments passed on the stack - else { - // get the argument type size - const size_t size = arg_size[arg_list[i].type]; - // read the argument from memory - arg.value = 0; - // note: due to little endian layout reading 4 or 8 bytes will give the - // correct value. - size_t read = ctx.process->ReadMemory(sp, &arg.value, size, err); - success = (err.Success() && read == size); - // advance past this argument - sp -= size; - } - // fail if we couldn't read this argument - if (!success) { - LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s", - __FUNCTION__, uint64_t(i), err.AsCString("n/a")); - return false; - } - } - return true; -} - -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 = GetLog(LLDBLog::Language); - - Status err; - - // get the current stack pointer - uint64_t sp = ctx.reg_ctx->GetSP(); - - for (size_t i = 0; i < num_args; ++i) { - bool success = false; - ArgItem &arg = arg_list[i]; - // arguments passed in registers - if (i < args_in_reg) { - const RegisterInfo *reg = ctx.reg_ctx->GetRegisterInfoAtIndex(i); - RegisterValue reg_val; - if (ctx.reg_ctx->ReadRegister(reg, reg_val)) - arg.value = reg_val.GetAsUInt32(0, &success); - } - // arguments passed on the stack - else { - // get the argument type size - const size_t arg_size = sizeof(uint32_t); - // clear all 64bits - arg.value = 0; - // read this argument from memory - size_t bytes_read = - ctx.process->ReadMemory(sp, &arg.value, arg_size, err); - success = (err.Success() && bytes_read == arg_size); - // advance the stack pointer - sp += sizeof(uint32_t); - } - // fail if we couldn't read this argument - if (!success) { - LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s", - __FUNCTION__, uint64_t(i), err.AsCString("n/a")); - return false; - } - } - return true; -} - -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 = GetLog(LLDBLog::Language); - - for (size_t i = 0; i < num_args; ++i) { - bool success = false; - ArgItem &arg = arg_list[i]; - // arguments passed in registers - if (i < args_in_reg) { - const RegisterInfo *reg = ctx.reg_ctx->GetRegisterInfoAtIndex(i); - RegisterValue reg_val; - if (ctx.reg_ctx->ReadRegister(reg, reg_val)) - arg.value = reg_val.GetAsUInt64(0, &success); - } - // arguments passed on the stack - else { - LLDB_LOGF(log, "%s - reading arguments spilled to stack not implemented", - __FUNCTION__); - } - // fail if we couldn't read this argument - if (!success) { - LLDB_LOGF(log, "%s - error reading argument: %" PRIu64, __FUNCTION__, - uint64_t(i)); - return false; - } - } - return true; -} - -bool GetArgsMipsel(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { - // number of arguments passed in registers - static const uint32_t args_in_reg = 4; - // register file offset to first argument - static const uint32_t reg_offset = 4; - - Log *log = GetLog(LLDBLog::Language); - - Status err; - - // find offset to arguments on the stack (+16 to skip over a0-a3 shadow - // space) - uint64_t sp = ctx.reg_ctx->GetSP() + 16; - - for (size_t i = 0; i < num_args; ++i) { - bool success = false; - ArgItem &arg = arg_list[i]; - // arguments passed in registers - if (i < args_in_reg) { - const RegisterInfo *reg = - ctx.reg_ctx->GetRegisterInfoAtIndex(i + reg_offset); - RegisterValue reg_val; - if (ctx.reg_ctx->ReadRegister(reg, reg_val)) - arg.value = reg_val.GetAsUInt64(0, &success); - } - // arguments passed on the stack - else { - const size_t arg_size = sizeof(uint32_t); - arg.value = 0; - size_t bytes_read = - ctx.process->ReadMemory(sp, &arg.value, arg_size, err); - success = (err.Success() && bytes_read == arg_size); - // advance the stack pointer - sp += arg_size; - } - // fail if we couldn't read this argument - if (!success) { - LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s", - __FUNCTION__, uint64_t(i), err.AsCString("n/a")); - return false; - } - } - return true; -} - -bool GetArgsMips64el(GetArgsCtx &ctx, ArgItem *arg_list, size_t num_args) { - // number of arguments passed in registers - static const uint32_t args_in_reg = 8; - // register file offset to first argument - static const uint32_t reg_offset = 4; - - Log *log = GetLog(LLDBLog::Language); - - Status err; - - // get the current stack pointer - uint64_t sp = ctx.reg_ctx->GetSP(); - - for (size_t i = 0; i < num_args; ++i) { - bool success = false; - ArgItem &arg = arg_list[i]; - // arguments passed in registers - if (i < args_in_reg) { - const RegisterInfo *reg = - ctx.reg_ctx->GetRegisterInfoAtIndex(i + reg_offset); - RegisterValue reg_val; - if (ctx.reg_ctx->ReadRegister(reg, reg_val)) - arg.value = reg_val.GetAsUInt64(0, &success); - } - // arguments passed on the stack - else { - // get the argument type size - const size_t arg_size = sizeof(uint64_t); - // clear all 64bits - arg.value = 0; - // read this argument from memory - size_t bytes_read = - ctx.process->ReadMemory(sp, &arg.value, arg_size, err); - success = (err.Success() && bytes_read == arg_size); - // advance the stack pointer - sp += arg_size; - } - // fail if we couldn't read this argument - if (!success) { - LLDB_LOGF(log, "%s - error reading argument: %" PRIu64 ", reason: %s", - __FUNCTION__, uint64_t(i), err.AsCString("n/a")); - return false; - } - } - return true; -} - -bool GetArgs(ExecutionContext &exe_ctx, ArgItem *arg_list, size_t num_args) { - Log *log = GetLog(LLDBLog::Language); - - // verify that we have a target - if (!exe_ctx.GetTargetPtr()) { - LLDB_LOGF(log, "%s - invalid target", __FUNCTION__); - return false; - } - - GetArgsCtx ctx = {exe_ctx.GetRegisterContext(), exe_ctx.GetProcessPtr()}; - assert(ctx.reg_ctx && ctx.process); - - // dispatch based on architecture - switch (exe_ctx.GetTargetPtr()->GetArchitecture().GetMachine()) { - case llvm::Triple::ArchType::x86: - return GetArgsX86(ctx, arg_list, num_args); - - case llvm::Triple::ArchType::x86_64: - return GetArgsX86_64(ctx, arg_list, num_args); - - case llvm::Triple::ArchType::arm: - return GetArgsArm(ctx, arg_list, num_args); - - case llvm::Triple::ArchType::aarch64: - return GetArgsAarch64(ctx, arg_list, num_args); - - case llvm::Triple::ArchType::mipsel: - return GetArgsMipsel(ctx, arg_list, num_args); - - case llvm::Triple::ArchType::mips64el: - return GetArgsMips64el(ctx, arg_list, num_args); - - default: - // unsupported architecture - if (log) { - LLDB_LOGF(log, "%s - architecture not supported: '%s'", __FUNCTION__, - exe_ctx.GetTargetRef().GetArchitecture().GetArchitectureName()); - } - return false; - } -} - -bool IsRenderScriptScriptModule(ModuleSP module) { - if (!module) - return false; - return module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), - eSymbolTypeData) != nullptr; -} - -bool ParseCoordinate(llvm::StringRef coord_s, RSCoordinate &coord) { - // takes an argument of the form 'num[,num][,num]'. Where 'coord_s' is a - // comma separated 1,2 or 3-dimensional coordinate with the whitespace - // trimmed. Missing coordinates are defaulted to zero. If parsing of any - // elements fails the contents of &coord are undefined and `false` is - // returned, `true` otherwise - - llvm::SmallVector<llvm::StringRef, 4> matches; - - if (!RegularExpression("^([0-9]+),([0-9]+),([0-9]+)$") - .Execute(coord_s, &matches) && - !RegularExpression("^([0-9]+),([0-9]+)$").Execute(coord_s, &matches) && - !RegularExpression("^([0-9]+)$").Execute(coord_s, &matches)) - return false; - - auto get_index = [&](size_t idx, uint32_t &i) -> bool { - std::string group; - errno = 0; - if (idx + 1 < matches.size()) { - return !llvm::StringRef(matches[idx + 1]).getAsInteger<uint32_t>(10, i); - } - return true; - }; - - return get_index(0, coord.x) && get_index(1, coord.y) && - get_index(2, coord.z); -} - -bool SkipPrologue(lldb::ModuleSP &module, Address &addr) { - Log *log = GetLog(LLDBLog::Language); - SymbolContext sc; - uint32_t resolved_flags = - module->ResolveSymbolContextForAddress(addr, eSymbolContextFunction, sc); - if (resolved_flags & eSymbolContextFunction) { - if (sc.function) { - const uint32_t offset = sc.function->GetPrologueByteSize(); - ConstString name = sc.GetFunctionName(); - if (offset) - addr.Slide(offset); - LLDB_LOGF(log, "%s: Prologue offset for %s is %" PRIu32, __FUNCTION__, - name.AsCString(), offset); - } - return true; - } else - return false; -} -} // anonymous namespace - -// The ScriptDetails class collects data associated with a single script -// instance. -struct RenderScriptRuntime::ScriptDetails { - ~ScriptDetails() = default; - - enum ScriptType { eScript, eScriptC }; - - // The derived type of the script. - empirical_type<ScriptType> type; - // The name of the original source file. - empirical_type<std::string> res_name; - // Path to script .so file on the device. - empirical_type<std::string> shared_lib; - // Directory where kernel objects are cached on device. - empirical_type<std::string> cache_dir; - // Pointer to the context which owns this script. - empirical_type<lldb::addr_t> context; - // Pointer to the script object itself. - empirical_type<lldb::addr_t> script; -}; - -// This Element class represents the Element object in RS, defining the type -// associated with an Allocation. -struct RenderScriptRuntime::Element { - // Taken from rsDefines.h - enum DataKind { - RS_KIND_USER, - RS_KIND_PIXEL_L = 7, - RS_KIND_PIXEL_A, - RS_KIND_PIXEL_LA, - RS_KIND_PIXEL_RGB, - RS_KIND_PIXEL_RGBA, - RS_KIND_PIXEL_DEPTH, - RS_KIND_PIXEL_YUV, - RS_KIND_INVALID = 100 - }; - - // Taken from rsDefines.h - enum DataType { - RS_TYPE_NONE = 0, - RS_TYPE_FLOAT_16, - RS_TYPE_FLOAT_32, - RS_TYPE_FLOAT_64, - RS_TYPE_SIGNED_8, - RS_TYPE_SIGNED_16, - RS_TYPE_SIGNED_32, - RS_TYPE_SIGNED_64, - RS_TYPE_UNSIGNED_8, - RS_TYPE_UNSIGNED_16, - RS_TYPE_UNSIGNED_32, - RS_TYPE_UNSIGNED_64, - RS_TYPE_BOOLEAN, - - RS_TYPE_UNSIGNED_5_6_5, - RS_TYPE_UNSIGNED_5_5_5_1, - RS_TYPE_UNSIGNED_4_4_4_4, - - RS_TYPE_MATRIX_4X4, - RS_TYPE_MATRIX_3X3, - RS_TYPE_MATRIX_2X2, - - RS_TYPE_ELEMENT = 1000, - RS_TYPE_TYPE, - RS_TYPE_ALLOCATION, - RS_TYPE_SAMPLER, - RS_TYPE_SCRIPT, - RS_TYPE_MESH, - RS_TYPE_PROGRAM_FRAGMENT, - RS_TYPE_PROGRAM_VERTEX, - RS_TYPE_PROGRAM_RASTER, - RS_TYPE_PROGRAM_STORE, - RS_TYPE_FONT, - - RS_TYPE_INVALID = 10000 - }; - - std::vector<Element> children; // Child Element fields for structs - empirical_type<lldb::addr_t> - element_ptr; // Pointer to the RS Element of the Type - empirical_type<DataType> - type; // Type of each data pointer stored by the allocation - empirical_type<DataKind> - type_kind; // Defines pixel type if Allocation is created from an image - empirical_type<uint32_t> - type_vec_size; // Vector size of each data point, e.g '4' for uchar4 - empirical_type<uint32_t> field_count; // Number of Subelements - empirical_type<uint32_t> datum_size; // Size of a single Element with padding - empirical_type<uint32_t> padding; // Number of padding bytes - empirical_type<uint32_t> - array_size; // Number of items in array, only needed for structs - ConstString type_name; // Name of type, only needed for structs - - static ConstString - GetFallbackStructName(); // Print this as the type name of a struct Element - // If we can't resolve the actual struct name - - bool ShouldRefresh() const { - const bool valid_ptr = element_ptr.isValid() && *element_ptr.get() != 0x0; - const bool valid_type = - type.isValid() && type_vec_size.isValid() && type_kind.isValid(); - return !valid_ptr || !valid_type || !datum_size.isValid(); - } -}; - -// This AllocationDetails class collects data associated with a single -// allocation instance. -struct RenderScriptRuntime::AllocationDetails { - struct Dimension { - uint32_t dim_1; - uint32_t dim_2; - uint32_t dim_3; - uint32_t cube_map; - - Dimension() { - dim_1 = 0; - dim_2 = 0; - dim_3 = 0; - cube_map = 0; - } - }; - - // The FileHeader struct specifies the header we use for writing allocations - // to a binary file. Our format begins with the ASCII characters "RSAD", - // identifying the file as an allocation dump. Member variables dims and - // hdr_size are then written consecutively, immediately followed by an - // instance of the ElementHeader struct. Because Elements can contain - // subelements, there may be more than one instance of the ElementHeader - // struct. With this first instance being the root element, and the other - // instances being the root's descendants. To identify which instances are an - // ElementHeader's children, each struct is immediately followed by a - // sequence of consecutive offsets to the start of its child structs. These - // offsets are - // 4 bytes in size, and the 0 offset signifies no more children. - struct FileHeader { - uint8_t ident[4]; // ASCII 'RSAD' identifying the file - uint32_t dims[3]; // Dimensions - uint16_t hdr_size; // Header size in bytes, including all element headers - }; - - struct ElementHeader { - uint16_t type; // DataType enum - uint32_t kind; // DataKind enum - uint32_t element_size; // Size of a single element, including padding - uint16_t vector_size; // Vector width - uint32_t array_size; // Number of elements in array - }; - - // Monotonically increasing from 1 - static uint32_t ID; - - // Maps Allocation DataType enum and vector size to printable strings using - // mapping from RenderScript numerical types summary documentation - static const char *RsDataTypeToString[][4]; - - // Maps Allocation DataKind enum to printable strings - static const char *RsDataKindToString[]; - - // Maps allocation types to format sizes for printing. - static const uint32_t RSTypeToFormat[][3]; - - // Give each allocation an ID as a way - // for commands to reference it. - const uint32_t id; - - // Allocation Element type - RenderScriptRuntime::Element element; - // Dimensions of the Allocation - empirical_type<Dimension> dimension; - // Pointer to address of the RS Allocation - empirical_type<lldb::addr_t> address; - // Pointer to the data held by the Allocation - empirical_type<lldb::addr_t> data_ptr; - // Pointer to the RS Type of the Allocation - empirical_type<lldb::addr_t> type_ptr; - // Pointer to the RS Context of the Allocation - empirical_type<lldb::addr_t> context; - // Size of the allocation - empirical_type<uint32_t> size; - // Stride between rows of the allocation - empirical_type<uint32_t> stride; - - // Give each allocation an id, so we can reference it in user commands. - AllocationDetails() : id(ID++) {} - - bool ShouldRefresh() const { - bool valid_ptrs = data_ptr.isValid() && *data_ptr.get() != 0x0; - valid_ptrs = valid_ptrs && type_ptr.isValid() && *type_ptr.get() != 0x0; - return !valid_ptrs || !dimension.isValid() || !size.isValid() || - element.ShouldRefresh(); - } -}; - -ConstString RenderScriptRuntime::Element::GetFallbackStructName() { - static const ConstString FallbackStructName("struct"); - return FallbackStructName; -} - -uint32_t RenderScriptRuntime::AllocationDetails::ID = 1; - -const char *RenderScriptRuntime::AllocationDetails::RsDataKindToString[] = { - "User", "Undefined", "Undefined", "Undefined", - "Undefined", "Undefined", "Undefined", // Enum jumps from 0 to 7 - "L Pixel", "A Pixel", "LA Pixel", "RGB Pixel", - "RGBA Pixel", "Pixel Depth", "YUV Pixel"}; - -const char *RenderScriptRuntime::AllocationDetails::RsDataTypeToString[][4] = { - {"None", "None", "None", "None"}, - {"half", "half2", "half3", "half4"}, - {"float", "float2", "float3", "float4"}, - {"double", "double2", "double3", "double4"}, - {"char", "char2", "char3", "char4"}, - {"short", "short2", "short3", "short4"}, - {"int", "int2", "int3", "int4"}, - {"long", "long2", "long3", "long4"}, - {"uchar", "uchar2", "uchar3", "uchar4"}, - {"ushort", "ushort2", "ushort3", "ushort4"}, - {"uint", "uint2", "uint3", "uint4"}, - {"ulong", "ulong2", "ulong3", "ulong4"}, - {"bool", "bool2", "bool3", "bool4"}, - {"packed_565", "packed_565", "packed_565", "packed_565"}, - {"packed_5551", "packed_5551", "packed_5551", "packed_5551"}, - {"packed_4444", "packed_4444", "packed_4444", "packed_4444"}, - {"rs_matrix4x4", "rs_matrix4x4", "rs_matrix4x4", "rs_matrix4x4"}, - {"rs_matrix3x3", "rs_matrix3x3", "rs_matrix3x3", "rs_matrix3x3"}, - {"rs_matrix2x2", "rs_matrix2x2", "rs_matrix2x2", "rs_matrix2x2"}, - - // Handlers - {"RS Element", "RS Element", "RS Element", "RS Element"}, - {"RS Type", "RS Type", "RS Type", "RS Type"}, - {"RS Allocation", "RS Allocation", "RS Allocation", "RS Allocation"}, - {"RS Sampler", "RS Sampler", "RS Sampler", "RS Sampler"}, - {"RS Script", "RS Script", "RS Script", "RS Script"}, - - // Deprecated - {"RS Mesh", "RS Mesh", "RS Mesh", "RS Mesh"}, - {"RS Program Fragment", "RS Program Fragment", "RS Program Fragment", - "RS Program Fragment"}, - {"RS Program Vertex", "RS Program Vertex", "RS Program Vertex", - "RS Program Vertex"}, - {"RS Program Raster", "RS Program Raster", "RS Program Raster", - "RS Program Raster"}, - {"RS Program Store", "RS Program Store", "RS Program Store", - "RS Program Store"}, - {"RS Font", "RS Font", "RS Font", "RS Font"}}; - -// Used as an index into the RSTypeToFormat array elements -enum TypeToFormatIndex { eFormatSingle = 0, eFormatVector, eElementSize }; - -// { format enum of single element, format enum of element vector, size of -// element} -const uint32_t RenderScriptRuntime::AllocationDetails::RSTypeToFormat[][3] = { - // RS_TYPE_NONE - {eFormatHex, eFormatHex, 1}, - // RS_TYPE_FLOAT_16 - {eFormatFloat, eFormatVectorOfFloat16, 2}, - // RS_TYPE_FLOAT_32 - {eFormatFloat, eFormatVectorOfFloat32, sizeof(float)}, - // RS_TYPE_FLOAT_64 - {eFormatFloat, eFormatVectorOfFloat64, sizeof(double)}, - // RS_TYPE_SIGNED_8 - {eFormatDecimal, eFormatVectorOfSInt8, sizeof(int8_t)}, - // RS_TYPE_SIGNED_16 - {eFormatDecimal, eFormatVectorOfSInt16, sizeof(int16_t)}, - // RS_TYPE_SIGNED_32 - {eFormatDecimal, eFormatVectorOfSInt32, sizeof(int32_t)}, - // RS_TYPE_SIGNED_64 - {eFormatDecimal, eFormatVectorOfSInt64, sizeof(int64_t)}, - // RS_TYPE_UNSIGNED_8 - {eFormatDecimal, eFormatVectorOfUInt8, sizeof(uint8_t)}, - // RS_TYPE_UNSIGNED_16 - {eFormatDecimal, eFormatVectorOfUInt16, sizeof(uint16_t)}, - // RS_TYPE_UNSIGNED_32 - {eFormatDecimal, eFormatVectorOfUInt32, sizeof(uint32_t)}, - // RS_TYPE_UNSIGNED_64 - {eFormatDecimal, eFormatVectorOfUInt64, sizeof(uint64_t)}, - // RS_TYPE_BOOL - {eFormatBoolean, eFormatBoolean, 1}, - // RS_TYPE_UNSIGNED_5_6_5 - {eFormatHex, eFormatHex, sizeof(uint16_t)}, - // RS_TYPE_UNSIGNED_5_5_5_1 - {eFormatHex, eFormatHex, sizeof(uint16_t)}, - // RS_TYPE_UNSIGNED_4_4_4_4 - {eFormatHex, eFormatHex, sizeof(uint16_t)}, - // RS_TYPE_MATRIX_4X4 - {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 16}, - // RS_TYPE_MATRIX_3X3 - {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 9}, - // RS_TYPE_MATRIX_2X2 - {eFormatVectorOfFloat32, eFormatVectorOfFloat32, sizeof(float) * 4}}; - -// Static Functions -LanguageRuntime * -RenderScriptRuntime::CreateInstance(Process *process, - lldb::LanguageType language) { - - if (language == eLanguageTypeExtRenderScript) - return new RenderScriptRuntime(process); - else - return nullptr; -} - -// Callback with a module to search for matching symbols. We first check that -// the module contains RS kernels. Then look for a symbol which matches our -// kernel name. The breakpoint address is finally set using the address of this -// symbol. -Searcher::CallbackReturn -RSBreakpointResolver::SearchCallback(SearchFilter &filter, - SymbolContext &context, Address *) { - BreakpointSP breakpoint_sp = GetBreakpoint(); - assert(breakpoint_sp); - - ModuleSP module = context.module_sp; - - if (!module || !IsRenderScriptScriptModule(module)) - return Searcher::eCallbackReturnContinue; - - // Attempt to set a breakpoint on the kernel name symbol within the module - // library. If it's not found, it's likely debug info is unavailable - try to - // set a breakpoint on <name>.expand. - const Symbol *kernel_sym = - module->FindFirstSymbolWithNameAndType(m_kernel_name, eSymbolTypeCode); - if (!kernel_sym) { - std::string kernel_name_expanded(m_kernel_name.AsCString()); - kernel_name_expanded.append(".expand"); - kernel_sym = module->FindFirstSymbolWithNameAndType( - ConstString(kernel_name_expanded.c_str()), eSymbolTypeCode); - } - - if (kernel_sym) { - Address bp_addr = kernel_sym->GetAddress(); - if (filter.AddressPasses(bp_addr)) - breakpoint_sp->AddLocation(bp_addr); - } - - return Searcher::eCallbackReturnContinue; -} - -Searcher::CallbackReturn -RSReduceBreakpointResolver::SearchCallback(lldb_private::SearchFilter &filter, - lldb_private::SymbolContext &context, - Address *) { - BreakpointSP breakpoint_sp = GetBreakpoint(); - assert(breakpoint_sp); - - // We need to have access to the list of reductions currently parsed, as - // reduce names don't actually exist as symbols in a module. They are only - // 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 = GetLog(LLDBLog::Breakpoints); - ModuleSP module = context.module_sp; - - if (!module || !IsRenderScriptScriptModule(module)) - return Searcher::eCallbackReturnContinue; - - if (!m_rsmodules) - return Searcher::eCallbackReturnContinue; - - for (const auto &module_desc : *m_rsmodules) { - if (module_desc->m_module != module) - continue; - - for (const auto &reduction : module_desc->m_reductions) { - if (reduction.m_reduce_name != m_reduce_name) - continue; - - std::array<std::pair<ConstString, int>, 5> funcs{ - {{reduction.m_init_name, eKernelTypeInit}, - {reduction.m_accum_name, eKernelTypeAccum}, - {reduction.m_comb_name, eKernelTypeComb}, - {reduction.m_outc_name, eKernelTypeOutC}, - {reduction.m_halter_name, eKernelTypeHalter}}}; - - for (const auto &kernel : funcs) { - // Skip constituent functions that don't match our spec - if (!(m_kernel_types & kernel.second)) - continue; - - const auto kernel_name = kernel.first; - const auto symbol = module->FindFirstSymbolWithNameAndType( - kernel_name, eSymbolTypeCode); - if (!symbol) - continue; - - auto address = symbol->GetAddress(); - if (filter.AddressPasses(address)) { - bool new_bp; - if (!SkipPrologue(module, address)) { - LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__); - } - breakpoint_sp->AddLocation(address, &new_bp); - LLDB_LOGF(log, "%s: %s reduction breakpoint on %s in %s", - __FUNCTION__, new_bp ? "new" : "existing", - kernel_name.GetCString(), - address.GetModule()->GetFileSpec().GetPath().c_str()); - } - } - } - } - return eCallbackReturnContinue; -} - -Searcher::CallbackReturn RSScriptGroupBreakpointResolver::SearchCallback( - SearchFilter &filter, SymbolContext &context, Address *addr) { - - BreakpointSP breakpoint_sp = GetBreakpoint(); - if (!breakpoint_sp) - return eCallbackReturnContinue; - - Log *log = GetLog(LLDBLog::Breakpoints); - ModuleSP &module = context.module_sp; - - if (!module || !IsRenderScriptScriptModule(module)) - return Searcher::eCallbackReturnContinue; - - std::vector<std::string> names; - Breakpoint& breakpoint = *breakpoint_sp; - breakpoint.GetNames(names); - if (names.empty()) - return eCallbackReturnContinue; - - for (auto &name : names) { - const RSScriptGroupDescriptorSP sg = FindScriptGroup(ConstString(name)); - if (!sg) { - LLDB_LOGF(log, "%s: could not find script group for %s", __FUNCTION__, - name.c_str()); - continue; - } - - LLDB_LOGF(log, "%s: Found ScriptGroup for %s", __FUNCTION__, name.c_str()); - - for (const RSScriptGroupDescriptor::Kernel &k : sg->m_kernels) { - if (log) { - LLDB_LOGF(log, "%s: Adding breakpoint for %s", __FUNCTION__, - k.m_name.AsCString()); - LLDB_LOGF(log, "%s: Kernel address 0x%" PRIx64, __FUNCTION__, k.m_addr); - } - - const lldb_private::Symbol *sym = - module->FindFirstSymbolWithNameAndType(k.m_name, eSymbolTypeCode); - if (!sym) { - LLDB_LOGF(log, "%s: Unable to find symbol for %s", __FUNCTION__, - k.m_name.AsCString()); - continue; - } - - if (log) { - LLDB_LOGF(log, "%s: Found symbol name is %s", __FUNCTION__, - sym->GetName().AsCString()); - } - - auto address = sym->GetAddress(); - if (!SkipPrologue(module, address)) { - LLDB_LOGF(log, "%s: Error trying to skip prologue", __FUNCTION__); - } - - bool new_bp; - breakpoint.AddLocation(address, &new_bp); - - LLDB_LOGF(log, "%s: Placed %sbreakpoint on %s", __FUNCTION__, - new_bp ? "new " : "", k.m_name.AsCString()); - - // exit after placing the first breakpoint if we do not intend to stop on - // all kernels making up this script group - if (!m_stop_on_all) - break; - } - } - - return eCallbackReturnContinue; -} - -void RenderScriptRuntime::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - "RenderScript language support", CreateInstance, - GetCommandObject); -} - -void RenderScriptRuntime::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -RenderScriptRuntime::ModuleKind -RenderScriptRuntime::GetModuleKind(const lldb::ModuleSP &module_sp) { - if (module_sp) { - if (IsRenderScriptScriptModule(module_sp)) - return eModuleKindKernelObj; - - // Is this the main RS runtime library - const ConstString rs_lib("libRS.so"); - if (module_sp->GetFileSpec().GetFilename() == rs_lib) { - return eModuleKindLibRS; - } - - const ConstString rs_driverlib("libRSDriver.so"); - if (module_sp->GetFileSpec().GetFilename() == rs_driverlib) { - return eModuleKindDriver; - } - - const ConstString rs_cpureflib("libRSCpuRef.so"); - if (module_sp->GetFileSpec().GetFilename() == rs_cpureflib) { - return eModuleKindImpl; - } - } - return eModuleKindIgnored; -} - -bool RenderScriptRuntime::IsRenderScriptModule( - const lldb::ModuleSP &module_sp) { - return GetModuleKind(module_sp) != eModuleKindIgnored; -} - -void RenderScriptRuntime::ModulesDidLoad(const ModuleList &module_list) { - std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); - - size_t num_modules = module_list.GetSize(); - for (size_t i = 0; i < num_modules; i++) { - auto mod = module_list.GetModuleAtIndex(i); - if (IsRenderScriptModule(mod)) { - LoadModule(mod); - } - } -} - -bool RenderScriptRuntime::GetDynamicTypeAndAddress( - ValueObject &in_value, lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, Address &address, - Value::ValueType &value_type) { - return false; -} - -TypeAndOrName -RenderScriptRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, - ValueObject &static_value) { - return type_and_or_name; -} - -bool RenderScriptRuntime::CouldHaveDynamicValue(ValueObject &in_value) { - return false; -} - -lldb::BreakpointResolverSP -RenderScriptRuntime::CreateExceptionResolver(const lldb::BreakpointSP &bp, - bool catch_bp, bool throw_bp) { - BreakpointResolverSP resolver_sp; - return resolver_sp; -} - -const RenderScriptRuntime::HookDefn RenderScriptRuntime::s_runtimeHookDefns[] = - { - // rsdScript - {"rsdScriptInit", "_Z13rsdScriptInitPKN7android12renderscript7ContextEP" - "NS0_7ScriptCEPKcS7_PKhjj", - "_Z13rsdScriptInitPKN7android12renderscript7ContextEPNS0_" - "7ScriptCEPKcS7_PKhmj", - 0, RenderScriptRuntime::eModuleKindDriver, - &lldb_private::RenderScriptRuntime::CaptureScriptInit}, - {"rsdScriptInvokeForEachMulti", - "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0" - "_6ScriptEjPPKNS0_10AllocationEjPS6_PKvjPK12RsScriptCall", - "_Z27rsdScriptInvokeForEachMultiPKN7android12renderscript7ContextEPNS0" - "_6ScriptEjPPKNS0_10AllocationEmPS6_PKvmPK12RsScriptCall", - 0, RenderScriptRuntime::eModuleKindDriver, - &lldb_private::RenderScriptRuntime::CaptureScriptInvokeForEachMulti}, - {"rsdScriptSetGlobalVar", "_Z21rsdScriptSetGlobalVarPKN7android12render" - "script7ContextEPKNS0_6ScriptEjPvj", - "_Z21rsdScriptSetGlobalVarPKN7android12renderscript7ContextEPKNS0_" - "6ScriptEjPvm", - 0, RenderScriptRuntime::eModuleKindDriver, - &lldb_private::RenderScriptRuntime::CaptureSetGlobalVar}, - - // rsdAllocation - {"rsdAllocationInit", "_Z17rsdAllocationInitPKN7android12renderscript7C" - "ontextEPNS0_10AllocationEb", - "_Z17rsdAllocationInitPKN7android12renderscript7ContextEPNS0_" - "10AllocationEb", - 0, RenderScriptRuntime::eModuleKindDriver, - &lldb_private::RenderScriptRuntime::CaptureAllocationInit}, - {"rsdAllocationRead2D", - "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_" - "10AllocationEjjj23RsAllocationCubemapFacejjPvjj", - "_Z19rsdAllocationRead2DPKN7android12renderscript7ContextEPKNS0_" - "10AllocationEjjj23RsAllocationCubemapFacejjPvmm", - 0, RenderScriptRuntime::eModuleKindDriver, nullptr}, - {"rsdAllocationDestroy", "_Z20rsdAllocationDestroyPKN7android12rendersc" - "ript7ContextEPNS0_10AllocationE", - "_Z20rsdAllocationDestroyPKN7android12renderscript7ContextEPNS0_" - "10AllocationE", - 0, RenderScriptRuntime::eModuleKindDriver, - &lldb_private::RenderScriptRuntime::CaptureAllocationDestroy}, - - // renderscript script groups - {"rsdDebugHintScriptGroup2", "_ZN7android12renderscript21debugHintScrip" - "tGroup2EPKcjPKPFvPK24RsExpandKernelDriver" - "InfojjjEj", - "_ZN7android12renderscript21debugHintScriptGroup2EPKcjPKPFvPK24RsExpan" - "dKernelDriverInfojjjEj", - 0, RenderScriptRuntime::eModuleKindImpl, - &lldb_private::RenderScriptRuntime::CaptureDebugHintScriptGroup2}}; - -const size_t RenderScriptRuntime::s_runtimeHookCount = - sizeof(s_runtimeHookDefns) / sizeof(s_runtimeHookDefns[0]); - -bool RenderScriptRuntime::HookCallback(void *baton, - StoppointCallbackContext *ctx, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id) { - RuntimeHook *hook = (RuntimeHook *)baton; - ExecutionContext exe_ctx(ctx->exe_ctx_ref); - - RenderScriptRuntime *lang_rt = llvm::cast<RenderScriptRuntime>( - exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - - lang_rt->HookCallback(hook, exe_ctx); - - return false; -} - -void RenderScriptRuntime::HookCallback(RuntimeHook *hook, - ExecutionContext &exe_ctx) { - Log *log = GetLog(LLDBLog::Language); - - LLDB_LOGF(log, "%s - '%s'", __FUNCTION__, hook->defn->name); - - if (hook->defn->grabber) { - (this->*(hook->defn->grabber))(hook, exe_ctx); - } -} - -void RenderScriptRuntime::CaptureDebugHintScriptGroup2( - RuntimeHook *hook_info, ExecutionContext &context) { - Log *log = GetLog(LLDBLog::Language); - - enum { - eGroupName = 0, - eGroupNameSize, - eKernel, - eKernelCount, - }; - - std::array<ArgItem, 4> args{{ - {ArgItem::ePointer, 0}, // const char *groupName - {ArgItem::eInt32, 0}, // const uint32_t groupNameSize - {ArgItem::ePointer, 0}, // const ExpandFuncTy *kernel - {ArgItem::eInt32, 0}, // const uint32_t kernelCount - }}; - - if (!GetArgs(context, args.data(), args.size())) { - LLDB_LOGF(log, "%s - Error while reading the function parameters", - __FUNCTION__); - return; - } else if (log) { - LLDB_LOGF(log, "%s - groupName : 0x%" PRIx64, __FUNCTION__, - addr_t(args[eGroupName])); - LLDB_LOGF(log, "%s - groupNameSize: %" PRIu64, __FUNCTION__, - uint64_t(args[eGroupNameSize])); - LLDB_LOGF(log, "%s - kernel : 0x%" PRIx64, __FUNCTION__, - addr_t(args[eKernel])); - LLDB_LOGF(log, "%s - kernelCount : %" PRIu64, __FUNCTION__, - uint64_t(args[eKernelCount])); - } - - // parse script group name - ConstString group_name; - { - Status err; - const uint64_t len = uint64_t(args[eGroupNameSize]); - std::unique_ptr<char[]> buffer(new char[uint32_t(len + 1)]); - m_process->ReadMemory(addr_t(args[eGroupName]), buffer.get(), len, err); - buffer.get()[len] = '\0'; - if (!err.Success()) { - LLDB_LOGF(log, "Error reading scriptgroup name from target"); - return; - } else { - LLDB_LOGF(log, "Extracted scriptgroup name %s", buffer.get()); - } - // write back the script group name - group_name.SetCString(buffer.get()); - } - - // create or access existing script group - RSScriptGroupDescriptorSP group; - { - // search for existing script group - for (auto sg : m_scriptGroups) { - if (sg->m_name == group_name) { - group = sg; - break; - } - } - if (!group) { - group = std::make_shared<RSScriptGroupDescriptor>(); - group->m_name = group_name; - m_scriptGroups.push_back(group); - } else { - // already have this script group - LLDB_LOGF(log, "Attempt to add duplicate script group %s", - group_name.AsCString()); - return; - } - } - assert(group); - - const uint32_t target_ptr_size = m_process->GetAddressByteSize(); - std::vector<addr_t> kernels; - // parse kernel addresses in script group - for (uint64_t i = 0; i < uint64_t(args[eKernelCount]); ++i) { - RSScriptGroupDescriptor::Kernel kernel; - // extract script group kernel addresses from the target - const addr_t ptr_addr = addr_t(args[eKernel]) + i * target_ptr_size; - uint64_t kernel_addr = 0; - Status err; - size_t read = - m_process->ReadMemory(ptr_addr, &kernel_addr, target_ptr_size, err); - if (!err.Success() || read != target_ptr_size) { - LLDB_LOGF(log, "Error parsing kernel address %" PRIu64 " in script group", - i); - return; - } - LLDB_LOGF(log, "Extracted scriptgroup kernel address - 0x%" PRIx64, - kernel_addr); - kernel.m_addr = kernel_addr; - - // try to resolve the associated kernel name - if (!ResolveKernelName(kernel.m_addr, kernel.m_name)) { - LLDB_LOGF(log, "Parsed scriptgroup kernel %" PRIu64 " - 0x%" PRIx64, i, - kernel_addr); - return; - } - - // try to find the non '.expand' function - { - const llvm::StringRef expand(".expand"); - const llvm::StringRef name_ref = kernel.m_name.GetStringRef(); - if (name_ref.endswith(expand)) { - const ConstString base_kernel(name_ref.drop_back(expand.size())); - // verify this function is a valid kernel - if (IsKnownKernel(base_kernel)) { - kernel.m_name = base_kernel; - LLDB_LOGF(log, "%s - found non expand version '%s'", __FUNCTION__, - base_kernel.GetCString()); - } - } - } - // add to a list of script group kernels we know about - group->m_kernels.push_back(kernel); - } - - // Resolve any pending scriptgroup breakpoints - { - Target &target = m_process->GetTarget(); - const BreakpointList &list = target.GetBreakpointList(); - const size_t num_breakpoints = list.GetSize(); - LLDB_LOGF(log, "Resolving %zu breakpoints", num_breakpoints); - for (size_t i = 0; i < num_breakpoints; ++i) { - const BreakpointSP bp = list.GetBreakpointAtIndex(i); - if (bp) { - if (bp->MatchesName(group_name.AsCString())) { - LLDB_LOGF(log, "Found breakpoint with name %s", - group_name.AsCString()); - bp->ResolveBreakpoint(); - } - } - } - } -} - -void RenderScriptRuntime::CaptureScriptInvokeForEachMulti( - RuntimeHook *hook, ExecutionContext &exe_ctx) { - Log *log = GetLog(LLDBLog::Language); - - enum { - eRsContext = 0, - eRsScript, - eRsSlot, - eRsAIns, - eRsInLen, - eRsAOut, - eRsUsr, - eRsUsrLen, - eRsSc, - }; - - std::array<ArgItem, 9> args{{ - ArgItem{ArgItem::ePointer, 0}, // const Context *rsc - ArgItem{ArgItem::ePointer, 0}, // Script *s - ArgItem{ArgItem::eInt32, 0}, // uint32_t slot - ArgItem{ArgItem::ePointer, 0}, // const Allocation **aIns - ArgItem{ArgItem::eInt32, 0}, // size_t inLen - ArgItem{ArgItem::ePointer, 0}, // Allocation *aout - ArgItem{ArgItem::ePointer, 0}, // const void *usr - ArgItem{ArgItem::eInt32, 0}, // size_t usrLen - ArgItem{ArgItem::ePointer, 0}, // const RsScriptCall *sc - }}; - - bool success = GetArgs(exe_ctx, &args[0], args.size()); - if (!success) { - LLDB_LOGF(log, "%s - Error while reading the function parameters", - __FUNCTION__); - return; - } - - const uint32_t target_ptr_size = m_process->GetAddressByteSize(); - Status err; - std::vector<uint64_t> allocs; - - // traverse allocation list - for (uint64_t i = 0; i < uint64_t(args[eRsInLen]); ++i) { - // calculate offest to allocation pointer - const addr_t addr = addr_t(args[eRsAIns]) + i * target_ptr_size; - - // Note: due to little endian layout, reading 32bits or 64bits into res - // will give the correct results. - uint64_t result = 0; - size_t read = m_process->ReadMemory(addr, &result, target_ptr_size, err); - if (read != target_ptr_size || !err.Success()) { - LLDB_LOGF(log, - "%s - Error while reading allocation list argument %" PRIu64, - __FUNCTION__, i); - } else { - allocs.push_back(result); - } - } - - // if there is an output allocation track it - if (uint64_t alloc_out = uint64_t(args[eRsAOut])) { - allocs.push_back(alloc_out); - } - - // for all allocations we have found - for (const uint64_t alloc_addr : allocs) { - AllocationDetails *alloc = LookUpAllocation(alloc_addr); - if (!alloc) - alloc = CreateAllocation(alloc_addr); - - if (alloc) { - // save the allocation address - if (alloc->address.isValid()) { - // check the allocation address we already have matches - assert(*alloc->address.get() == alloc_addr); - } else { - alloc->address = alloc_addr; - } - - // save the context - if (log) { - if (alloc->context.isValid() && - *alloc->context.get() != addr_t(args[eRsContext])) - LLDB_LOGF(log, "%s - Allocation used by multiple contexts", - __FUNCTION__); - } - alloc->context = addr_t(args[eRsContext]); - } - } - - // make sure we track this script object - if (lldb_private::RenderScriptRuntime::ScriptDetails *script = - LookUpScript(addr_t(args[eRsScript]), true)) { - if (log) { - if (script->context.isValid() && - *script->context.get() != addr_t(args[eRsContext])) - LLDB_LOGF(log, "%s - Script used by multiple contexts", __FUNCTION__); - } - script->context = addr_t(args[eRsContext]); - } -} - -void RenderScriptRuntime::CaptureSetGlobalVar(RuntimeHook *hook, - ExecutionContext &context) { - Log *log = GetLog(LLDBLog::Language); - - enum { - eRsContext, - eRsScript, - eRsId, - eRsData, - eRsLength, - }; - - std::array<ArgItem, 5> args{{ - ArgItem{ArgItem::ePointer, 0}, // eRsContext - ArgItem{ArgItem::ePointer, 0}, // eRsScript - ArgItem{ArgItem::eInt32, 0}, // eRsId - ArgItem{ArgItem::ePointer, 0}, // eRsData - ArgItem{ArgItem::eInt32, 0}, // eRsLength - }}; - - bool success = GetArgs(context, &args[0], args.size()); - if (!success) { - LLDB_LOGF(log, "%s - error reading the function parameters.", __FUNCTION__); - return; - } - - if (log) { - LLDB_LOGF(log, - "%s - 0x%" PRIx64 ",0x%" PRIx64 " slot %" PRIu64 " = 0x%" PRIx64 - ":%" PRIu64 "bytes.", - __FUNCTION__, uint64_t(args[eRsContext]), - uint64_t(args[eRsScript]), uint64_t(args[eRsId]), - uint64_t(args[eRsData]), uint64_t(args[eRsLength])); - - addr_t script_addr = addr_t(args[eRsScript]); - if (m_scriptMappings.find(script_addr) != m_scriptMappings.end()) { - auto rsm = m_scriptMappings[script_addr]; - if (uint64_t(args[eRsId]) < rsm->m_globals.size()) { - auto rsg = rsm->m_globals[uint64_t(args[eRsId])]; - LLDB_LOGF(log, "%s - Setting of '%s' within '%s' inferred", - __FUNCTION__, rsg.m_name.AsCString(), - rsm->m_module->GetFileSpec().GetFilename().AsCString()); - } - } - } -} - -void RenderScriptRuntime::CaptureAllocationInit(RuntimeHook *hook, - ExecutionContext &exe_ctx) { - Log *log = GetLog(LLDBLog::Language); - - enum { eRsContext, eRsAlloc, eRsForceZero }; - - std::array<ArgItem, 3> args{{ - ArgItem{ArgItem::ePointer, 0}, // eRsContext - ArgItem{ArgItem::ePointer, 0}, // eRsAlloc - ArgItem{ArgItem::eBool, 0}, // eRsForceZero - }}; - - bool success = GetArgs(exe_ctx, &args[0], args.size()); - if (!success) { - LLDB_LOGF(log, "%s - error while reading the function parameters", - __FUNCTION__); - return; - } - - LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 ",0x%" PRIx64 " .", - __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc]), - uint64_t(args[eRsForceZero])); - - AllocationDetails *alloc = CreateAllocation(uint64_t(args[eRsAlloc])); - if (alloc) - alloc->context = uint64_t(args[eRsContext]); -} - -void RenderScriptRuntime::CaptureAllocationDestroy(RuntimeHook *hook, - ExecutionContext &exe_ctx) { - Log *log = GetLog(LLDBLog::Language); - - enum { - eRsContext, - eRsAlloc, - }; - - std::array<ArgItem, 2> args{{ - ArgItem{ArgItem::ePointer, 0}, // eRsContext - ArgItem{ArgItem::ePointer, 0}, // eRsAlloc - }}; - - bool success = GetArgs(exe_ctx, &args[0], args.size()); - if (!success) { - LLDB_LOGF(log, "%s - error while reading the function parameters.", - __FUNCTION__); - return; - } - - LLDB_LOGF(log, "%s - 0x%" PRIx64 ", 0x%" PRIx64 ".", __FUNCTION__, - uint64_t(args[eRsContext]), uint64_t(args[eRsAlloc])); - - for (auto iter = m_allocations.begin(); iter != m_allocations.end(); ++iter) { - auto &allocation_up = *iter; // get the unique pointer - if (allocation_up->address.isValid() && - *allocation_up->address.get() == addr_t(args[eRsAlloc])) { - m_allocations.erase(iter); - LLDB_LOGF(log, "%s - deleted allocation entry.", __FUNCTION__); - return; - } - } - - LLDB_LOGF(log, "%s - couldn't find destroyed allocation.", __FUNCTION__); -} - -void RenderScriptRuntime::CaptureScriptInit(RuntimeHook *hook, - ExecutionContext &exe_ctx) { - Log *log = GetLog(LLDBLog::Language); - - Status err; - Process *process = exe_ctx.GetProcessPtr(); - - enum { eRsContext, eRsScript, eRsResNamePtr, eRsCachedDirPtr }; - - std::array<ArgItem, 4> args{ - {ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}, - ArgItem{ArgItem::ePointer, 0}, ArgItem{ArgItem::ePointer, 0}}}; - bool success = GetArgs(exe_ctx, &args[0], args.size()); - if (!success) { - LLDB_LOGF(log, "%s - error while reading the function parameters.", - __FUNCTION__); - return; - } - - std::string res_name; - process->ReadCStringFromMemory(addr_t(args[eRsResNamePtr]), res_name, err); - if (err.Fail()) { - LLDB_LOGF(log, "%s - error reading res_name: %s.", __FUNCTION__, - err.AsCString()); - } - - std::string cache_dir; - process->ReadCStringFromMemory(addr_t(args[eRsCachedDirPtr]), cache_dir, err); - if (err.Fail()) { - LLDB_LOGF(log, "%s - error reading cache_dir: %s.", __FUNCTION__, - err.AsCString()); - } - - LLDB_LOGF(log, "%s - 0x%" PRIx64 ",0x%" PRIx64 " => '%s' at '%s' .", - __FUNCTION__, uint64_t(args[eRsContext]), uint64_t(args[eRsScript]), - res_name.c_str(), cache_dir.c_str()); - - if (res_name.size() > 0) { - StreamString strm; - strm.Printf("librs.%s.so", res_name.c_str()); - - ScriptDetails *script = LookUpScript(addr_t(args[eRsScript]), true); - if (script) { - script->type = ScriptDetails::eScriptC; - script->cache_dir = cache_dir; - script->res_name = res_name; - script->shared_lib = std::string(strm.GetString()); - script->context = addr_t(args[eRsContext]); - } - - LLDB_LOGF(log, - "%s - '%s' tagged with context 0x%" PRIx64 - " and script 0x%" PRIx64 ".", - __FUNCTION__, strm.GetData(), uint64_t(args[eRsContext]), - uint64_t(args[eRsScript])); - } else if (log) { - LLDB_LOGF(log, "%s - resource name invalid, Script not tagged.", - __FUNCTION__); - } -} - -void RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, - ModuleKind kind) { - Log *log = GetLog(LLDBLog::Language); - - if (!module) { - return; - } - - Target &target = GetProcess()->GetTarget(); - const llvm::Triple::ArchType machine = target.GetArchitecture().GetMachine(); - - if (machine != llvm::Triple::ArchType::x86 && - machine != llvm::Triple::ArchType::arm && - machine != llvm::Triple::ArchType::aarch64 && - machine != llvm::Triple::ArchType::mipsel && - machine != llvm::Triple::ArchType::mips64el && - machine != llvm::Triple::ArchType::x86_64) { - LLDB_LOGF(log, "%s - unable to hook runtime functions.", __FUNCTION__); - return; - } - - const uint32_t target_ptr_size = - target.GetArchitecture().GetAddressByteSize(); - - std::array<bool, s_runtimeHookCount> hook_placed; - hook_placed.fill(false); - - for (size_t idx = 0; idx < s_runtimeHookCount; idx++) { - const HookDefn *hook_defn = &s_runtimeHookDefns[idx]; - if (hook_defn->kind != kind) { - continue; - } - - const char *symbol_name = (target_ptr_size == 4) - ? hook_defn->symbol_name_m32 - : hook_defn->symbol_name_m64; - - const Symbol *sym = module->FindFirstSymbolWithNameAndType( - ConstString(symbol_name), eSymbolTypeCode); - if (!sym) { - if (log) { - LLDB_LOGF(log, "%s - symbol '%s' related to the function %s not found", - __FUNCTION__, symbol_name, hook_defn->name); - } - continue; - } - - addr_t addr = sym->GetLoadAddress(&target); - if (addr == LLDB_INVALID_ADDRESS) { - LLDB_LOGF(log, - "%s - unable to resolve the address of hook function '%s' " - "with symbol '%s'.", - __FUNCTION__, hook_defn->name, symbol_name); - continue; - } else { - LLDB_LOGF(log, "%s - function %s, address resolved at 0x%" PRIx64, - __FUNCTION__, hook_defn->name, addr); - } - - RuntimeHookSP hook(new RuntimeHook()); - hook->address = addr; - hook->defn = hook_defn; - hook->bp_sp = target.CreateBreakpoint(addr, true, false); - hook->bp_sp->SetCallback(HookCallback, hook.get(), true); - m_runtimeHooks[addr] = hook; - if (log) { - LLDB_LOGF(log, - "%s - successfully hooked '%s' in '%s' version %" PRIu64 - " at 0x%" PRIx64 ".", - __FUNCTION__, hook_defn->name, - module->GetFileSpec().GetFilename().AsCString(), - (uint64_t)hook_defn->version, (uint64_t)addr); - } - hook_placed[idx] = true; - } - - // log any unhooked function - if (log) { - for (size_t i = 0; i < hook_placed.size(); ++i) { - if (hook_placed[i]) - continue; - const HookDefn &hook_defn = s_runtimeHookDefns[i]; - if (hook_defn.kind != kind) - continue; - LLDB_LOGF(log, "%s - function %s was not hooked", __FUNCTION__, - hook_defn.name); - } - } -} - -void RenderScriptRuntime::FixupScriptDetails(RSModuleDescriptorSP rsmodule_sp) { - if (!rsmodule_sp) - return; - - Log *log = GetLog(LLDBLog::Language); - - const ModuleSP module = rsmodule_sp->m_module; - const FileSpec &file = module->GetPlatformFileSpec(); - - // Iterate over all of the scripts that we currently know of. Note: We cant - // push or pop to m_scripts here or it may invalidate rs_script. - for (const auto &rs_script : m_scripts) { - // Extract the expected .so file path for this script. - std::string shared_lib; - if (!rs_script->shared_lib.get(shared_lib)) - continue; - - // Only proceed if the module that has loaded corresponds to this script. - if (file.GetFilename() != ConstString(shared_lib.c_str())) - continue; - - // Obtain the script address which we use as a key. - lldb::addr_t script; - if (!rs_script->script.get(script)) - continue; - - // If we have a script mapping for the current script. - if (m_scriptMappings.find(script) != m_scriptMappings.end()) { - // if the module we have stored is different to the one we just received. - if (m_scriptMappings[script] != rsmodule_sp) { - LLDB_LOGF( - log, - "%s - script %" PRIx64 " wants reassigned to new rsmodule '%s'.", - __FUNCTION__, (uint64_t)script, - rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); - } - } - // We don't have a script mapping for the current script. - else { - // Obtain the script resource name. - std::string res_name; - if (rs_script->res_name.get(res_name)) - // Set the modules resource name. - rsmodule_sp->m_resname = res_name; - // Add Script/Module pair to map. - m_scriptMappings[script] = rsmodule_sp; - LLDB_LOGF(log, "%s - script %" PRIx64 " associated with rsmodule '%s'.", - __FUNCTION__, (uint64_t)script, - rsmodule_sp->m_module->GetFileSpec().GetFilename().AsCString()); - } - } -} - -// Uses the Target API to evaluate the expression passed as a parameter to the -// function The result of that expression is returned an unsigned 64 bit int, -// via the result* parameter. Function returns true on success, and false on -// failure -bool RenderScriptRuntime::EvalRSExpression(const char *expr, - StackFrame *frame_ptr, - uint64_t *result) { - Log *log = GetLog(LLDBLog::Language); - LLDB_LOGF(log, "%s(%s)", __FUNCTION__, expr); - - ValueObjectSP expr_result; - EvaluateExpressionOptions options; - options.SetLanguage(lldb::eLanguageTypeC_plus_plus); - // Perform the actual expression evaluation - auto &target = GetProcess()->GetTarget(); - target.EvaluateExpression(expr, frame_ptr, expr_result, options); - - if (!expr_result) { - LLDB_LOGF(log, "%s: couldn't evaluate expression.", __FUNCTION__); - return false; - } - - // The result of the expression is invalid - if (!expr_result->GetError().Success()) { - Status err = expr_result->GetError(); - // Expression returned is void, so this is actually a success - if (err.GetError() == UserExpression::kNoResult) { - LLDB_LOGF(log, "%s - expression returned void.", __FUNCTION__); - - result = nullptr; - return true; - } - - LLDB_LOGF(log, "%s - error evaluating expression result: %s", __FUNCTION__, - err.AsCString()); - return false; - } - - bool success = false; - // We only read the result as an uint32_t. - *result = expr_result->GetValueAsUnsigned(0, &success); - - if (!success) { - LLDB_LOGF(log, "%s - couldn't convert expression result to uint32_t", - __FUNCTION__); - return false; - } - - return true; -} - -namespace { -// Used to index expression format strings -enum ExpressionStrings { - eExprGetOffsetPtr = 0, - eExprAllocGetType, - eExprTypeDimX, - eExprTypeDimY, - eExprTypeDimZ, - eExprTypeElemPtr, - eExprElementType, - eExprElementKind, - eExprElementVec, - eExprElementFieldCount, - eExprSubelementsId, - eExprSubelementsName, - eExprSubelementsArrSize, - - _eExprLast // keep at the end, implicit size of the array runtime_expressions -}; - -// max length of an expanded expression -const int jit_max_expr_size = 512; - -// Retrieve the string to JIT for the given expression -#define JIT_TEMPLATE_CONTEXT "void* ctxt = (void*)rsDebugGetContextWrapper(0x%" PRIx64 "); " -const char *JITTemplate(ExpressionStrings e) { - // Format strings containing the expressions we may need to evaluate. - static std::array<const char *, _eExprLast> runtime_expressions = { - {// Mangled GetOffsetPointer(Allocation*, xoff, yoff, zoff, lod, cubemap) - "(int*)_" - "Z12GetOffsetPtrPKN7android12renderscript10AllocationEjjjj23RsAllocation" - "CubemapFace" - "(0x%" PRIx64 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 ", 0, 0)", // eExprGetOffsetPtr - - // Type* rsaAllocationGetType(Context*, Allocation*) - JIT_TEMPLATE_CONTEXT "(void*)rsaAllocationGetType(ctxt, 0x%" PRIx64 ")", // eExprAllocGetType - - // rsaTypeGetNativeData(Context*, Type*, void* typeData, size) Pack the - // data in the following way mHal.state.dimX; mHal.state.dimY; - // mHal.state.dimZ; mHal.state.lodCount; mHal.state.faces; mElement; - // into typeData Need to specify 32 or 64 bit for uint_t since this - // differs between devices - JIT_TEMPLATE_CONTEXT - "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt" - ", 0x%" PRIx64 ", data, 6); data[0]", // eExprTypeDimX - JIT_TEMPLATE_CONTEXT - "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt" - ", 0x%" PRIx64 ", data, 6); data[1]", // eExprTypeDimY - JIT_TEMPLATE_CONTEXT - "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt" - ", 0x%" PRIx64 ", data, 6); data[2]", // eExprTypeDimZ - JIT_TEMPLATE_CONTEXT - "uint%" PRIu32 "_t data[6]; (void*)rsaTypeGetNativeData(ctxt" - ", 0x%" PRIx64 ", data, 6); data[5]", // eExprTypeElemPtr - - // rsaElementGetNativeData(Context*, Element*, uint32_t* elemData,size) - // Pack mType; mKind; mNormalized; mVectorSize; NumSubElements into - // elemData - JIT_TEMPLATE_CONTEXT - "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt" - ", 0x%" PRIx64 ", data, 5); data[0]", // eExprElementType - JIT_TEMPLATE_CONTEXT - "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt" - ", 0x%" PRIx64 ", data, 5); data[1]", // eExprElementKind - JIT_TEMPLATE_CONTEXT - "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt" - ", 0x%" PRIx64 ", data, 5); data[3]", // eExprElementVec - JIT_TEMPLATE_CONTEXT - "uint32_t data[5]; (void*)rsaElementGetNativeData(ctxt" - ", 0x%" PRIx64 ", data, 5); data[4]", // eExprElementFieldCount - - // rsaElementGetSubElements(RsContext con, RsElement elem, uintptr_t - // *ids, const char **names, size_t *arraySizes, uint32_t dataSize) - // Needed for Allocations of structs to gather details about - // fields/Subelements Element* of field - JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 - "]; size_t arr_size[%" PRIu32 "];" - "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64 - ", ids, names, arr_size, %" PRIu32 "); ids[%" PRIu32 "]", // eExprSubelementsId - - // Name of field - JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 - "]; size_t arr_size[%" PRIu32 "];" - "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64 - ", ids, names, arr_size, %" PRIu32 "); names[%" PRIu32 "]", // eExprSubelementsName - - // Array size of field - JIT_TEMPLATE_CONTEXT "void* ids[%" PRIu32 "]; const char* names[%" PRIu32 - "]; size_t arr_size[%" PRIu32 "];" - "(void*)rsaElementGetSubElements(ctxt, 0x%" PRIx64 - ", ids, names, arr_size, %" PRIu32 "); arr_size[%" PRIu32 "]"}}; // eExprSubelementsArrSize - - return runtime_expressions[e]; -} -} // end of the anonymous namespace - -// JITs the RS runtime for the internal data pointer of an allocation. Is -// passed x,y,z coordinates for the pointer to a specific element. Then sets -// the data_ptr member in Allocation with the result. Returns true on success, -// false otherwise -bool RenderScriptRuntime::JITDataPointer(AllocationDetails *alloc, - StackFrame *frame_ptr, uint32_t x, - uint32_t y, uint32_t z) { - Log *log = GetLog(LLDBLog::Language); - - if (!alloc->address.isValid()) { - LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); - return false; - } - - const char *fmt_str = JITTemplate(eExprGetOffsetPtr); - char expr_buf[jit_max_expr_size]; - - int written = snprintf(expr_buf, jit_max_expr_size, fmt_str, - *alloc->address.get(), x, y, z); - if (written < 0) { - LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); - return false; - } else if (written >= jit_max_expr_size) { - LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); - return false; - } - - uint64_t result = 0; - if (!EvalRSExpression(expr_buf, frame_ptr, &result)) - return false; - - addr_t data_ptr = static_cast<lldb::addr_t>(result); - alloc->data_ptr = data_ptr; - - return true; -} - -// JITs the RS runtime for the internal pointer to the RS Type of an allocation -// Then sets the type_ptr member in Allocation with the result. Returns true on -// success, false otherwise -bool RenderScriptRuntime::JITTypePointer(AllocationDetails *alloc, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - if (!alloc->address.isValid() || !alloc->context.isValid()) { - LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); - return false; - } - - const char *fmt_str = JITTemplate(eExprAllocGetType); - char expr_buf[jit_max_expr_size]; - - int written = snprintf(expr_buf, jit_max_expr_size, fmt_str, - *alloc->context.get(), *alloc->address.get()); - if (written < 0) { - LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); - return false; - } else if (written >= jit_max_expr_size) { - LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); - return false; - } - - uint64_t result = 0; - if (!EvalRSExpression(expr_buf, frame_ptr, &result)) - return false; - - addr_t type_ptr = static_cast<lldb::addr_t>(result); - alloc->type_ptr = type_ptr; - - return true; -} - -// JITs the RS runtime for information about the dimensions and type of an -// allocation Then sets dimension and element_ptr members in Allocation with -// the result. Returns true on success, false otherwise -bool RenderScriptRuntime::JITTypePacked(AllocationDetails *alloc, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - if (!alloc->type_ptr.isValid() || !alloc->context.isValid()) { - LLDB_LOGF(log, "%s - Failed to find allocation details.", __FUNCTION__); - return false; - } - - // Expression is different depending on if device is 32 or 64 bit - uint32_t target_ptr_size = - GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize(); - const uint32_t bits = target_ptr_size == 4 ? 32 : 64; - - // We want 4 elements from packed data - const uint32_t num_exprs = 4; - static_assert(num_exprs == (eExprTypeElemPtr - eExprTypeDimX + 1), - "Invalid number of expressions"); - - char expr_bufs[num_exprs][jit_max_expr_size]; - uint64_t results[num_exprs]; - - for (uint32_t i = 0; i < num_exprs; ++i) { - const char *fmt_str = JITTemplate(ExpressionStrings(eExprTypeDimX + i)); - int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, - *alloc->context.get(), bits, *alloc->type_ptr.get()); - if (written < 0) { - LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); - return false; - } else if (written >= jit_max_expr_size) { - LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); - return false; - } - - // Perform expression evaluation - if (!EvalRSExpression(expr_bufs[i], frame_ptr, &results[i])) - return false; - } - - // Assign results to allocation members - AllocationDetails::Dimension dims; - dims.dim_1 = static_cast<uint32_t>(results[0]); - dims.dim_2 = static_cast<uint32_t>(results[1]); - dims.dim_3 = static_cast<uint32_t>(results[2]); - alloc->dimension = dims; - - addr_t element_ptr = static_cast<lldb::addr_t>(results[3]); - alloc->element.element_ptr = element_ptr; - - LLDB_LOGF(log, - "%s - dims (%" PRIu32 ", %" PRIu32 ", %" PRIu32 - ") Element*: 0x%" PRIx64 ".", - __FUNCTION__, dims.dim_1, dims.dim_2, dims.dim_3, element_ptr); - - return true; -} - -// JITs the RS runtime for information about the Element of an allocation Then -// sets type, type_vec_size, field_count and type_kind members in Element with -// the result. Returns true on success, false otherwise -bool RenderScriptRuntime::JITElementPacked(Element &elem, - const lldb::addr_t context, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - if (!elem.element_ptr.isValid()) { - LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); - return false; - } - - // We want 4 elements from packed data - const uint32_t num_exprs = 4; - static_assert(num_exprs == (eExprElementFieldCount - eExprElementType + 1), - "Invalid number of expressions"); - - char expr_bufs[num_exprs][jit_max_expr_size]; - uint64_t results[num_exprs]; - - for (uint32_t i = 0; i < num_exprs; i++) { - const char *fmt_str = JITTemplate(ExpressionStrings(eExprElementType + i)); - int written = snprintf(expr_bufs[i], jit_max_expr_size, fmt_str, context, - *elem.element_ptr.get()); - if (written < 0) { - LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); - return false; - } else if (written >= jit_max_expr_size) { - LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); - return false; - } - - // Perform expression evaluation - if (!EvalRSExpression(expr_bufs[i], frame_ptr, &results[i])) - return false; - } - - // Assign results to allocation members - elem.type = static_cast<RenderScriptRuntime::Element::DataType>(results[0]); - elem.type_kind = - static_cast<RenderScriptRuntime::Element::DataKind>(results[1]); - elem.type_vec_size = static_cast<uint32_t>(results[2]); - elem.field_count = static_cast<uint32_t>(results[3]); - - LLDB_LOGF(log, - "%s - data type %" PRIu32 ", pixel type %" PRIu32 - ", vector size %" PRIu32 ", field count %" PRIu32, - __FUNCTION__, *elem.type.get(), *elem.type_kind.get(), - *elem.type_vec_size.get(), *elem.field_count.get()); - - // If this Element has subelements then JIT rsaElementGetSubElements() for - // details about its fields - return !(*elem.field_count.get() > 0 && - !JITSubelements(elem, context, frame_ptr)); -} - -// JITs the RS runtime for information about the subelements/fields of a struct -// allocation This is necessary for infering the struct type so we can pretty -// print the allocation's contents. Returns true on success, false otherwise -bool RenderScriptRuntime::JITSubelements(Element &elem, - const lldb::addr_t context, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - if (!elem.element_ptr.isValid() || !elem.field_count.isValid()) { - LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); - return false; - } - - const short num_exprs = 3; - static_assert(num_exprs == (eExprSubelementsArrSize - eExprSubelementsId + 1), - "Invalid number of expressions"); - - char expr_buffer[jit_max_expr_size]; - uint64_t results; - - // Iterate over struct fields. - const uint32_t field_count = *elem.field_count.get(); - for (uint32_t field_index = 0; field_index < field_count; ++field_index) { - Element child; - for (uint32_t expr_index = 0; expr_index < num_exprs; ++expr_index) { - const char *fmt_str = - JITTemplate(ExpressionStrings(eExprSubelementsId + expr_index)); - int written = snprintf(expr_buffer, jit_max_expr_size, fmt_str, - context, field_count, field_count, field_count, - *elem.element_ptr.get(), field_count, field_index); - if (written < 0) { - LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); - return false; - } else if (written >= jit_max_expr_size) { - LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); - return false; - } - - // Perform expression evaluation - if (!EvalRSExpression(expr_buffer, frame_ptr, &results)) - return false; - - LLDB_LOGF(log, "%s - expr result 0x%" PRIx64 ".", __FUNCTION__, results); - - switch (expr_index) { - case 0: // Element* of child - child.element_ptr = static_cast<addr_t>(results); - break; - case 1: // Name of child - { - lldb::addr_t address = static_cast<addr_t>(results); - Status err; - std::string name; - GetProcess()->ReadCStringFromMemory(address, name, err); - if (!err.Fail()) - child.type_name = ConstString(name); - else { - LLDB_LOGF(log, "%s - warning: Couldn't read field name.", - __FUNCTION__); - } - break; - } - case 2: // Array size of child - child.array_size = static_cast<uint32_t>(results); - break; - } - } - - // We need to recursively JIT each Element field of the struct since - // structs can be nested inside structs. - if (!JITElementPacked(child, context, frame_ptr)) - return false; - elem.children.push_back(child); - } - - // Try to infer the name of the struct type so we can pretty print the - // allocation contents. - FindStructTypeName(elem, frame_ptr); - - return true; -} - -// JITs the RS runtime for the address of the last element in the allocation. -// The `elem_size` parameter represents the size of a single element, including -// padding. Which is needed as an offset from the last element pointer. Using -// this offset minus the starting address we can calculate the size of the -// allocation. Returns true on success, false otherwise -bool RenderScriptRuntime::JITAllocationSize(AllocationDetails *alloc, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - if (!alloc->address.isValid() || !alloc->dimension.isValid() || - !alloc->data_ptr.isValid() || !alloc->element.datum_size.isValid()) { - LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); - return false; - } - - // Find dimensions - uint32_t dim_x = alloc->dimension.get()->dim_1; - uint32_t dim_y = alloc->dimension.get()->dim_2; - uint32_t dim_z = alloc->dimension.get()->dim_3; - - // Our plan of jitting the last element address doesn't seem to work for - // struct Allocations` Instead try to infer the size ourselves without any - // inter element padding. - if (alloc->element.children.size() > 0) { - if (dim_x == 0) - dim_x = 1; - if (dim_y == 0) - dim_y = 1; - if (dim_z == 0) - dim_z = 1; - - alloc->size = dim_x * dim_y * dim_z * *alloc->element.datum_size.get(); - - LLDB_LOGF(log, "%s - inferred size of struct allocation %" PRIu32 ".", - __FUNCTION__, *alloc->size.get()); - return true; - } - - const char *fmt_str = JITTemplate(eExprGetOffsetPtr); - char expr_buf[jit_max_expr_size]; - - // Calculate last element - dim_x = dim_x == 0 ? 0 : dim_x - 1; - dim_y = dim_y == 0 ? 0 : dim_y - 1; - dim_z = dim_z == 0 ? 0 : dim_z - 1; - - int written = snprintf(expr_buf, jit_max_expr_size, fmt_str, - *alloc->address.get(), dim_x, dim_y, dim_z); - if (written < 0) { - LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); - return false; - } else if (written >= jit_max_expr_size) { - LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); - return false; - } - - uint64_t result = 0; - if (!EvalRSExpression(expr_buf, frame_ptr, &result)) - return false; - - addr_t mem_ptr = static_cast<lldb::addr_t>(result); - // Find pointer to last element and add on size of an element - alloc->size = static_cast<uint32_t>(mem_ptr - *alloc->data_ptr.get()) + - *alloc->element.datum_size.get(); - - return true; -} - -// JITs the RS runtime for information about the stride between rows in the -// allocation. This is done to detect padding, since allocated memory is -// 16-byte aligned. Returns true on success, false otherwise -bool RenderScriptRuntime::JITAllocationStride(AllocationDetails *alloc, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - if (!alloc->address.isValid() || !alloc->data_ptr.isValid()) { - LLDB_LOGF(log, "%s - failed to find allocation details.", __FUNCTION__); - return false; - } - - const char *fmt_str = JITTemplate(eExprGetOffsetPtr); - char expr_buf[jit_max_expr_size]; - - int written = snprintf(expr_buf, jit_max_expr_size, fmt_str, - *alloc->address.get(), 0, 1, 0); - if (written < 0) { - LLDB_LOGF(log, "%s - encoding error in snprintf().", __FUNCTION__); - return false; - } else if (written >= jit_max_expr_size) { - LLDB_LOGF(log, "%s - expression too long.", __FUNCTION__); - return false; - } - - uint64_t result = 0; - if (!EvalRSExpression(expr_buf, frame_ptr, &result)) - return false; - - addr_t mem_ptr = static_cast<lldb::addr_t>(result); - alloc->stride = static_cast<uint32_t>(mem_ptr - *alloc->data_ptr.get()); - - return true; -} - -// JIT all the current runtime info regarding an allocation -bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc, - StackFrame *frame_ptr) { - // GetOffsetPointer() - if (!JITDataPointer(alloc, frame_ptr)) - return false; - - // rsaAllocationGetType() - if (!JITTypePointer(alloc, frame_ptr)) - return false; - - // rsaTypeGetNativeData() - if (!JITTypePacked(alloc, frame_ptr)) - return false; - - // rsaElementGetNativeData() - if (!JITElementPacked(alloc->element, *alloc->context.get(), frame_ptr)) - return false; - - // Sets the datum_size member in Element - SetElementSize(alloc->element); - - // Use GetOffsetPointer() to infer size of the allocation - return JITAllocationSize(alloc, frame_ptr); -} - -// Function attempts to set the type_name member of the parameterised Element -// object. This string should be the name of the struct type the Element -// represents. We need this string for pretty printing the Element to users. -void RenderScriptRuntime::FindStructTypeName(Element &elem, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - if (!elem.type_name.IsEmpty()) // Name already set - return; - else - elem.type_name = Element::GetFallbackStructName(); // Default type name if - // we don't succeed - - // Find all the global variables from the script rs modules - VariableList var_list; - for (auto module_sp : m_rsmodules) - module_sp->m_module->FindGlobalVariables( - RegularExpression(llvm::StringRef(".")), UINT32_MAX, var_list); - - // Iterate over all the global variables looking for one with a matching type - // to the Element. We make the assumption a match exists since there needs to - // be a global variable to reflect the struct type back into java host code. - for (const VariableSP &var_sp : var_list) { - if (!var_sp) - continue; - - ValueObjectSP valobj_sp = ValueObjectVariable::Create(frame_ptr, var_sp); - if (!valobj_sp) - continue; - - // Find the number of variable fields. - // If it has no fields, or more fields than our Element, then it can't be - // the struct we're looking for. Don't check for equality since RS can add - // extra struct members for padding. - size_t num_children = valobj_sp->GetNumChildren(); - if (num_children > elem.children.size() || num_children == 0) - continue; - - // Iterate over children looking for members with matching field names. If - // all the field names match, this is likely the struct we want. - // TODO: This could be made more robust by also checking children data - // sizes, or array size - bool found = true; - for (size_t i = 0; i < num_children; ++i) { - ValueObjectSP child = valobj_sp->GetChildAtIndex(i, true); - if (!child || (child->GetName() != elem.children[i].type_name)) { - found = false; - break; - } - } - - // RS can add extra struct members for padding in the format - // '#rs_padding_[0-9]+' - if (found && num_children < elem.children.size()) { - const uint32_t size_diff = elem.children.size() - num_children; - LLDB_LOGF(log, "%s - %" PRIu32 " padding struct entries", __FUNCTION__, - size_diff); - - for (uint32_t i = 0; i < size_diff; ++i) { - ConstString name = elem.children[num_children + i].type_name; - if (strcmp(name.AsCString(), "#rs_padding") < 0) - found = false; - } - } - - // We've found a global variable with matching type - if (found) { - // Dereference since our Element type isn't a pointer. - if (valobj_sp->IsPointerType()) { - Status err; - ValueObjectSP deref_valobj = valobj_sp->Dereference(err); - if (!err.Fail()) - valobj_sp = deref_valobj; - } - - // Save name of variable in Element. - elem.type_name = valobj_sp->GetTypeName(); - LLDB_LOGF(log, "%s - element name set to %s", __FUNCTION__, - elem.type_name.AsCString()); - - return; - } - } -} - -// Function sets the datum_size member of Element. Representing the size of a -// single instance including padding. Assumes the relevant allocation -// information has already been jitted. -void RenderScriptRuntime::SetElementSize(Element &elem) { - 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"); - - const uint32_t vec_size = *elem.type_vec_size.get(); - uint32_t data_size = 0; - uint32_t padding = 0; - - // Element is of a struct type, calculate size recursively. - if ((type == Element::RS_TYPE_NONE) && (elem.children.size() > 0)) { - for (Element &child : elem.children) { - SetElementSize(child); - const uint32_t array_size = - child.array_size.isValid() ? *child.array_size.get() : 1; - data_size += *child.datum_size.get() * array_size; - } - } - // These have been packed already - else if (type == Element::RS_TYPE_UNSIGNED_5_6_5 || - type == Element::RS_TYPE_UNSIGNED_5_5_5_1 || - type == Element::RS_TYPE_UNSIGNED_4_4_4_4) { - data_size = AllocationDetails::RSTypeToFormat[type][eElementSize]; - } else if (type < Element::RS_TYPE_ELEMENT) { - data_size = - vec_size * AllocationDetails::RSTypeToFormat[type][eElementSize]; - if (vec_size == 3) - padding = AllocationDetails::RSTypeToFormat[type][eElementSize]; - } else - data_size = - GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize(); - - elem.padding = padding; - elem.datum_size = data_size + padding; - LLDB_LOGF(log, "%s - element size set to %" PRIu32, __FUNCTION__, - data_size + padding); -} - -// Given an allocation, this function copies the allocation contents from -// device into a buffer on the heap. Returning a shared pointer to the buffer -// containing the data. -std::shared_ptr<uint8_t> -RenderScriptRuntime::GetAllocationData(AllocationDetails *alloc, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - // JIT all the allocation details - if (alloc->ShouldRefresh()) { - LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info", - __FUNCTION__); - - if (!RefreshAllocation(alloc, frame_ptr)) { - LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__); - return nullptr; - } - } - - assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && - alloc->element.type_vec_size.isValid() && alloc->size.isValid() && - "Allocation information not available"); - - // Allocate a buffer to copy data into - const uint32_t size = *alloc->size.get(); - std::shared_ptr<uint8_t> buffer(new uint8_t[size]); - if (!buffer) { - LLDB_LOGF(log, "%s - couldn't allocate a %" PRIu32 " byte buffer", - __FUNCTION__, size); - return nullptr; - } - - // Read the inferior memory - Status err; - lldb::addr_t data_ptr = *alloc->data_ptr.get(); - GetProcess()->ReadMemory(data_ptr, buffer.get(), size, err); - if (err.Fail()) { - LLDB_LOGF(log, - "%s - '%s' Couldn't read %" PRIu32 - " bytes of allocation data from 0x%" PRIx64, - __FUNCTION__, err.AsCString(), size, data_ptr); - return nullptr; - } - - return buffer; -} - -// Function copies data from a binary file into an allocation. There is a -// header at the start of the file, FileHeader, before the data content itself. -// Information from this header is used to display warnings to the user about -// incompatibilities -bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, - const char *path, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - // Find allocation with the given id - AllocationDetails *alloc = FindAllocByID(strm, alloc_id); - if (!alloc) - return false; - - LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__, - *alloc->address.get()); - - // JIT all the allocation details - if (alloc->ShouldRefresh()) { - LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.", - __FUNCTION__); - - if (!RefreshAllocation(alloc, frame_ptr)) { - LLDB_LOGF(log, "%s - couldn't JIT allocation details", __FUNCTION__); - return false; - } - } - - assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && - alloc->element.type_vec_size.isValid() && alloc->size.isValid() && - alloc->element.datum_size.isValid() && - "Allocation information not available"); - - // Check we can read from file - FileSpec file(path); - FileSystem::Instance().Resolve(file); - if (!FileSystem::Instance().Exists(file)) { - strm.Printf("Error: File %s does not exist", path); - strm.EOL(); - return false; - } - - if (!FileSystem::Instance().Readable(file)) { - strm.Printf("Error: File %s does not have readable permissions", path); - strm.EOL(); - return false; - } - - // Read file into data buffer - auto data_sp = FileSystem::Instance().CreateDataBuffer(file.GetPath()); - - // Cast start of buffer to FileHeader and use pointer to read metadata - const void *file_buf = data_sp->GetBytes(); - if (file_buf == nullptr || - data_sp->GetByteSize() < (sizeof(AllocationDetails::FileHeader) + - sizeof(AllocationDetails::ElementHeader))) { - strm.Printf("Error: File %s does not contain enough data for header", path); - strm.EOL(); - return false; - } - const AllocationDetails::FileHeader *file_header = - static_cast<const AllocationDetails::FileHeader *>(file_buf); - - // Check file starts with ascii characters "RSAD" - if (memcmp(file_header->ident, "RSAD", 4)) { - strm.Printf("Error: File doesn't contain identifier for an RS allocation " - "dump. Are you sure this is the correct file?"); - strm.EOL(); - return false; - } - - // Look at the type of the root element in the header - AllocationDetails::ElementHeader root_el_hdr; - 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, - __FUNCTION__, root_el_hdr.type, root_el_hdr.element_size); - - // Check if the target allocation and file both have the same number of bytes - // for an Element - if (*alloc->element.datum_size.get() != root_el_hdr.element_size) { - strm.Printf("Warning: Mismatched Element sizes - file %" PRIu32 - " bytes, allocation %" PRIu32 " bytes", - root_el_hdr.element_size, *alloc->element.datum_size.get()); - strm.EOL(); - } - - // Check if the target allocation and file both have the same type - const uint32_t alloc_type = static_cast<uint32_t>(*alloc->element.type.get()); - const uint32_t file_type = root_el_hdr.type; - - if (file_type > Element::RS_TYPE_FONT) { - strm.Printf("Warning: File has unknown allocation type"); - strm.EOL(); - } else if (alloc_type != file_type) { - // Enum value isn't monotonous, so doesn't always index RsDataTypeToString - // array - uint32_t target_type_name_idx = alloc_type; - uint32_t head_type_name_idx = file_type; - if (alloc_type >= Element::RS_TYPE_ELEMENT && - alloc_type <= Element::RS_TYPE_FONT) - target_type_name_idx = static_cast<Element::DataType>( - (alloc_type - Element::RS_TYPE_ELEMENT) + - Element::RS_TYPE_MATRIX_2X2 + 1); - - if (file_type >= Element::RS_TYPE_ELEMENT && - file_type <= Element::RS_TYPE_FONT) - head_type_name_idx = static_cast<Element::DataType>( - (file_type - Element::RS_TYPE_ELEMENT) + Element::RS_TYPE_MATRIX_2X2 + - 1); - - const char *head_type_name = - AllocationDetails::RsDataTypeToString[head_type_name_idx][0]; - const char *target_type_name = - AllocationDetails::RsDataTypeToString[target_type_name_idx][0]; - - strm.Printf( - "Warning: Mismatched Types - file '%s' type, allocation '%s' type", - head_type_name, target_type_name); - strm.EOL(); - } - - // Advance buffer past header - 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; - - // Check if the target allocation and file both have the same total data - // size. - const uint32_t alloc_size = *alloc->size.get(); - if (alloc_size != size) { - strm.Printf("Warning: Mismatched allocation sizes - file 0x%" PRIx64 - " bytes, allocation 0x%" PRIx32 " bytes", - (uint64_t)size, alloc_size); - strm.EOL(); - // Set length to copy to minimum - size = alloc_size < size ? alloc_size : size; - } - - // Copy file data from our buffer into the target allocation. - lldb::addr_t alloc_data = *alloc->data_ptr.get(); - Status err; - size_t written = GetProcess()->WriteMemory(alloc_data, file_buf, size, err); - if (!err.Success() || written != size) { - strm.Printf("Error: Couldn't write data to allocation %s", err.AsCString()); - strm.EOL(); - return false; - } - - strm.Printf("Contents of file '%s' read into allocation %" PRIu32, path, - alloc->id); - strm.EOL(); - - return true; -} - -// Function takes as parameters a byte buffer, which will eventually be written -// to file as the element header, an offset into that buffer, and an Element -// that will be saved into the buffer at the parametrised offset. Return value -// is the new offset after writing the element into the buffer. Elements are -// saved to the file as the ElementHeader struct followed by offsets to the -// structs of all the element's children. -size_t RenderScriptRuntime::PopulateElementHeaders( - const std::shared_ptr<uint8_t> header_buffer, size_t offset, - const Element &elem) { - // File struct for an element header with all the relevant details copied - // from elem. We assume members are valid already. - AllocationDetails::ElementHeader elem_header; - elem_header.type = *elem.type.get(); - elem_header.kind = *elem.type_kind.get(); - elem_header.element_size = *elem.datum_size.get(); - elem_header.vector_size = *elem.type_vec_size.get(); - elem_header.array_size = - elem.array_size.isValid() ? *elem.array_size.get() : 0; - const size_t elem_header_size = sizeof(AllocationDetails::ElementHeader); - - // Copy struct into buffer and advance offset We assume that header_buffer - // has been checked for nullptr before this method is called - memcpy(header_buffer.get() + offset, &elem_header, elem_header_size); - offset += elem_header_size; - - // Starting offset of child ElementHeader struct - size_t child_offset = - offset + ((elem.children.size() + 1) * sizeof(uint32_t)); - for (const RenderScriptRuntime::Element &child : elem.children) { - // Recursively populate the buffer with the element header structs of - // children. Then save the offsets where they were set after the parent - // element header. - memcpy(header_buffer.get() + offset, &child_offset, sizeof(uint32_t)); - offset += sizeof(uint32_t); - - child_offset = PopulateElementHeaders(header_buffer, child_offset, child); - } - - // Zero indicates no more children - memset(header_buffer.get() + offset, 0, sizeof(uint32_t)); - - return child_offset; -} - -// Given an Element object this function returns the total size needed in the -// file header to store the element's details. Taking into account the size of -// the element header struct, plus the offsets to all the element's children. -// Function is recursive so that the size of all ancestors is taken into -// account. -size_t RenderScriptRuntime::CalculateElementHeaderSize(const Element &elem) { - // Offsets to children plus zero terminator - size_t size = (elem.children.size() + 1) * sizeof(uint32_t); - // Size of header struct with type details - size += sizeof(AllocationDetails::ElementHeader); - - // Calculate recursively for all descendants - for (const Element &child : elem.children) - size += CalculateElementHeaderSize(child); - - return size; -} - -// Function copies allocation contents into a binary file. This file can then -// be loaded later into a different allocation. There is a header, FileHeader, -// before the allocation data containing meta-data. -bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, - const char *path, - StackFrame *frame_ptr) { - Log *log = GetLog(LLDBLog::Language); - - // Find allocation with the given id - AllocationDetails *alloc = FindAllocByID(strm, alloc_id); - if (!alloc) - return false; - - LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64 ".", __FUNCTION__, - *alloc->address.get()); - - // JIT all the allocation details - if (alloc->ShouldRefresh()) { - LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.", - __FUNCTION__); - - if (!RefreshAllocation(alloc, frame_ptr)) { - LLDB_LOGF(log, "%s - couldn't JIT allocation details.", __FUNCTION__); - return false; - } - } - - assert(alloc->data_ptr.isValid() && alloc->element.type.isValid() && - alloc->element.type_vec_size.isValid() && - alloc->element.datum_size.get() && - alloc->element.type_kind.isValid() && alloc->dimension.isValid() && - "Allocation information not available"); - - // Check we can create writable file - FileSpec file_spec(path); - FileSystem::Instance().Resolve(file_spec); - auto file = FileSystem::Instance().Open( - file_spec, File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate | - File::eOpenOptionTruncate); - - if (!file) { - std::string error = llvm::toString(file.takeError()); - strm.Printf("Error: Failed to open '%s' for writing: %s", path, - error.c_str()); - strm.EOL(); - return false; - } - - // Read allocation into buffer of heap memory - const std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr); - if (!buffer) { - strm.Printf("Error: Couldn't read allocation data into buffer"); - strm.EOL(); - return false; - } - - // Create the file header - AllocationDetails::FileHeader head; - memcpy(head.ident, "RSAD", 4); - head.dims[0] = static_cast<uint32_t>(alloc->dimension.get()->dim_1); - head.dims[1] = static_cast<uint32_t>(alloc->dimension.get()->dim_2); - head.dims[2] = static_cast<uint32_t>(alloc->dimension.get()->dim_3); - - const size_t element_header_size = CalculateElementHeaderSize(alloc->element); - assert((sizeof(AllocationDetails::FileHeader) + element_header_size) < - UINT16_MAX && - "Element header too large"); - head.hdr_size = static_cast<uint16_t>(sizeof(AllocationDetails::FileHeader) + - element_header_size); - - // Write the file header - size_t num_bytes = sizeof(AllocationDetails::FileHeader); - LLDB_LOGF(log, "%s - writing File Header, 0x%" PRIx64 " bytes", __FUNCTION__, - (uint64_t)num_bytes); - - Status err = file.get()->Write(&head, num_bytes); - if (!err.Success()) { - strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); - strm.EOL(); - return false; - } - - // Create the headers describing the element type of the allocation. - std::shared_ptr<uint8_t> element_header_buffer( - new uint8_t[element_header_size]); - if (element_header_buffer == nullptr) { - strm.Printf("Internal Error: Couldn't allocate %" PRIu64 - " bytes on the heap", - (uint64_t)element_header_size); - strm.EOL(); - return false; - } - - PopulateElementHeaders(element_header_buffer, 0, alloc->element); - - // Write headers for allocation element type to file - num_bytes = element_header_size; - LLDB_LOGF(log, "%s - writing element headers, 0x%" PRIx64 " bytes.", - __FUNCTION__, (uint64_t)num_bytes); - - err = file.get()->Write(element_header_buffer.get(), num_bytes); - if (!err.Success()) { - strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); - strm.EOL(); - return false; - } - - // Write allocation data to file - num_bytes = static_cast<size_t>(*alloc->size.get()); - LLDB_LOGF(log, "%s - writing 0x%" PRIx64 " bytes", __FUNCTION__, - (uint64_t)num_bytes); - - err = file.get()->Write(buffer.get(), num_bytes); - if (!err.Success()) { - strm.Printf("Error: '%s' when writing to file '%s'", err.AsCString(), path); - strm.EOL(); - return false; - } - - strm.Printf("Allocation written to file '%s'", path); - strm.EOL(); - return true; -} - -bool RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp) { - Log *log = GetLog(LLDBLog::Language); - - if (module_sp) { - for (const auto &rs_module : m_rsmodules) { - if (rs_module->m_module == module_sp) { - // Check if the user has enabled automatically breaking on all RS - // kernels. - if (m_breakAllKernels) - BreakOnModuleKernels(rs_module); - - return false; - } - } - bool module_loaded = false; - switch (GetModuleKind(module_sp)) { - case eModuleKindKernelObj: { - RSModuleDescriptorSP module_desc; - module_desc = std::make_shared<RSModuleDescriptor>(module_sp); - if (module_desc->ParseRSInfo()) { - m_rsmodules.push_back(module_desc); - module_desc->WarnIfVersionMismatch(GetProcess() - ->GetTarget() - .GetDebugger() - .GetAsyncOutputStream() - .get()); - module_loaded = true; - } - if (module_loaded) { - FixupScriptDetails(module_desc); - } - break; - } - case eModuleKindDriver: { - if (!m_libRSDriver) { - m_libRSDriver = module_sp; - LoadRuntimeHooks(m_libRSDriver, RenderScriptRuntime::eModuleKindDriver); - } - break; - } - case eModuleKindImpl: { - if (!m_libRSCpuRef) { - m_libRSCpuRef = module_sp; - LoadRuntimeHooks(m_libRSCpuRef, RenderScriptRuntime::eModuleKindImpl); - } - break; - } - case eModuleKindLibRS: { - if (!m_libRS) { - m_libRS = module_sp; - static ConstString gDbgPresentStr("gDebuggerPresent"); - const Symbol *debug_present = m_libRS->FindFirstSymbolWithNameAndType( - gDbgPresentStr, eSymbolTypeData); - if (debug_present) { - Status err; - uint32_t flag = 0x00000001U; - Target &target = GetProcess()->GetTarget(); - addr_t addr = debug_present->GetLoadAddress(&target); - GetProcess()->WriteMemory(addr, &flag, sizeof(flag), err); - if (err.Success()) { - LLDB_LOGF(log, "%s - debugger present flag set on debugee.", - __FUNCTION__); - - m_debuggerPresentFlagged = true; - } else if (log) { - LLDB_LOGF(log, "%s - error writing debugger present flags '%s' ", - __FUNCTION__, err.AsCString()); - } - } else if (log) { - LLDB_LOGF( - log, - "%s - error writing debugger present flags - symbol not found", - __FUNCTION__); - } - } - break; - } - default: - break; - } - if (module_loaded) - Update(); - return module_loaded; - } - return false; -} - -void RenderScriptRuntime::Update() { - if (m_rsmodules.size() > 0) { - if (!m_initiated) { - Initiate(); - } - } -} - -void RSModuleDescriptor::WarnIfVersionMismatch(lldb_private::Stream *s) const { - if (!s) - return; - - if (m_slang_version.empty() || m_bcc_version.empty()) { - s->PutCString("WARNING: Unknown bcc or slang (llvm-rs-cc) version; debug " - "experience may be unreliable"); - s->EOL(); - } else if (m_slang_version != m_bcc_version) { - s->Printf("WARNING: The debug info emitted by the slang frontend " - "(llvm-rs-cc) used to build this module (%s) does not match the " - "version of bcc used to generate the debug information (%s). " - "This is an unsupported configuration and may result in a poor " - "debugging experience; proceed with caution", - m_slang_version.c_str(), m_bcc_version.c_str()); - s->EOL(); - } -} - -bool RSModuleDescriptor::ParsePragmaCount(llvm::StringRef *lines, - size_t n_lines) { - // Skip the pragma prototype line - ++lines; - for (; n_lines--; ++lines) { - const auto kv_pair = lines->split(" - "); - m_pragmas[kv_pair.first.trim().str()] = kv_pair.second.trim().str(); - } - return true; -} - -bool RSModuleDescriptor::ParseExportReduceCount(llvm::StringRef *lines, - size_t n_lines) { - // The list of reduction kernels in the `.rs.info` symbol is of the form - // "signature - accumulatordatasize - reduction_name - initializer_name - - // accumulator_name - combiner_name - outconverter_name - halter_name" Where - // 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 = GetLog(LLDBLog::Language); - // Skip the exportReduceCount line - ++lines; - for (; n_lines--; ++lines) { - llvm::SmallVector<llvm::StringRef, 8> spec; - lines->split(spec, " - "); - if (spec.size() != 8) { - if (spec.size() < 8) { - if (log) - log->Error("Error parsing RenderScript reduction spec. wrong number " - "of fields"); - return false; - } else if (log) - log->Warning("Extraneous members in reduction spec: '%s'", - lines->str().c_str()); - } - - const auto sig_s = spec[0]; - uint32_t sig; - if (sig_s.getAsInteger(10, sig)) { - if (log) - log->Error("Error parsing Renderscript reduction spec: invalid kernel " - "signature: '%s'", - sig_s.str().c_str()); - return false; - } - - const auto accum_data_size_s = spec[1]; - uint32_t accum_data_size; - if (accum_data_size_s.getAsInteger(10, accum_data_size)) { - if (log) - log->Error("Error parsing Renderscript reduction spec: invalid " - "accumulator data size %s", - accum_data_size_s.str().c_str()); - return false; - } - - LLDB_LOGF(log, "Found RenderScript reduction '%s'", spec[2].str().c_str()); - - m_reductions.push_back(RSReductionDescriptor(this, sig, accum_data_size, - spec[2], spec[3], spec[4], - spec[5], spec[6], spec[7])); - } - return true; -} - -bool RSModuleDescriptor::ParseVersionInfo(llvm::StringRef *lines, - size_t n_lines) { - // Skip the versionInfo line - ++lines; - for (; n_lines--; ++lines) { - // We're only interested in bcc and slang versions, and ignore all other - // versionInfo lines - const auto kv_pair = lines->split(" - "); - if (kv_pair.first == "slang") - m_slang_version = kv_pair.second.str(); - else if (kv_pair.first == "bcc") - m_bcc_version = kv_pair.second.str(); - } - return true; -} - -bool RSModuleDescriptor::ParseExportForeachCount(llvm::StringRef *lines, - size_t n_lines) { - // Skip the exportForeachCount line - ++lines; - for (; n_lines--; ++lines) { - uint32_t slot; - // `forEach` kernels are listed in the `.rs.info` packet as a "slot - name" - // pair per line - const auto kv_pair = lines->split(" - "); - if (kv_pair.first.getAsInteger(10, slot)) - return false; - m_kernels.push_back(RSKernelDescriptor(this, kv_pair.second, slot)); - } - return true; -} - -bool RSModuleDescriptor::ParseExportVarCount(llvm::StringRef *lines, - size_t n_lines) { - // Skip the ExportVarCount line - ++lines; - for (; n_lines--; ++lines) - m_globals.push_back(RSGlobalDescriptor(this, *lines)); - return true; -} - -// The .rs.info symbol in renderscript modules contains a string which needs to -// be parsed. The string is basic and is parsed on a line by line basis. -bool RSModuleDescriptor::ParseRSInfo() { - assert(m_module); - Log *log = GetLog(LLDBLog::Language); - const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType( - ConstString(".rs.info"), eSymbolTypeData); - if (!info_sym) - return false; - - const addr_t addr = info_sym->GetAddressRef().GetFileAddress(); - if (addr == LLDB_INVALID_ADDRESS) - return false; - - const addr_t size = info_sym->GetByteSize(); - const FileSpec fs = m_module->GetFileSpec(); - - auto buffer = - FileSystem::Instance().CreateDataBuffer(fs.GetPath(), size, addr); - if (!buffer) - return false; - - // split rs.info. contents into lines - llvm::SmallVector<llvm::StringRef, 128> info_lines; - { - const llvm::StringRef raw_rs_info((const char *)buffer->GetBytes()); - raw_rs_info.split(info_lines, '\n'); - LLDB_LOGF(log, "'.rs.info symbol for '%s':\n%s", - m_module->GetFileSpec().GetPath().c_str(), - raw_rs_info.str().c_str()); - } - - enum { - eExportVar, - eExportForEach, - eExportReduce, - ePragma, - eBuildChecksum, - eObjectSlot, - eVersionInfo, - }; - - const auto rs_info_handler = [](llvm::StringRef name) -> int { - return llvm::StringSwitch<int>(name) - // The number of visible global variables in the script - .Case("exportVarCount", eExportVar) - // The number of RenderScrip `forEach` kernels __attribute__((kernel)) - .Case("exportForEachCount", eExportForEach) - // The number of generalreductions: This marked in the script by - // `#pragma reduce()` - .Case("exportReduceCount", eExportReduce) - // Total count of all RenderScript specific `#pragmas` used in the - // script - .Case("pragmaCount", ePragma) - .Case("objectSlotCount", eObjectSlot) - .Case("versionInfo", eVersionInfo) - .Default(-1); - }; - - // parse all text lines of .rs.info - for (auto line = info_lines.begin(); line != info_lines.end(); ++line) { - const auto kv_pair = line->split(": "); - const auto key = kv_pair.first; - const auto val = kv_pair.second.trim(); - - const auto handler = rs_info_handler(key); - if (handler == -1) - continue; - // getAsInteger returns `true` on an error condition - we're only - // interested in numeric fields at the moment - uint64_t n_lines; - if (val.getAsInteger(10, n_lines)) { - LLDB_LOGV(log, "Failed to parse non-numeric '.rs.info' section {0}", - line->str()); - continue; - } - if (info_lines.end() - (line + 1) < (ptrdiff_t)n_lines) - return false; - - bool success = false; - switch (handler) { - case eExportVar: - success = ParseExportVarCount(line, n_lines); - break; - case eExportForEach: - success = ParseExportForeachCount(line, n_lines); - break; - case eExportReduce: - success = ParseExportReduceCount(line, n_lines); - break; - case ePragma: - success = ParsePragmaCount(line, n_lines); - break; - case eVersionInfo: - success = ParseVersionInfo(line, n_lines); - break; - default: { - LLDB_LOGF(log, "%s - skipping .rs.info field '%s'", __FUNCTION__, - line->str().c_str()); - continue; - } - } - if (!success) - return false; - line += n_lines; - } - return info_lines.size() > 0; -} - -void RenderScriptRuntime::DumpStatus(Stream &strm) const { - if (m_libRS) { - strm.Printf("Runtime Library discovered."); - strm.EOL(); - } - if (m_libRSDriver) { - strm.Printf("Runtime Driver discovered."); - strm.EOL(); - } - if (m_libRSCpuRef) { - strm.Printf("CPU Reference Implementation discovered."); - strm.EOL(); - } - - if (m_runtimeHooks.size()) { - strm.Printf("Runtime functions hooked:"); - strm.EOL(); - for (auto b : m_runtimeHooks) { - strm.Indent(b.second->defn->name); - strm.EOL(); - } - } else { - strm.Printf("Runtime is not hooked."); - strm.EOL(); - } -} - -void RenderScriptRuntime::DumpContexts(Stream &strm) const { - strm.Printf("Inferred RenderScript Contexts:"); - strm.EOL(); - strm.IndentMore(); - - std::map<addr_t, uint64_t> contextReferences; - - // Iterate over all of the currently discovered scripts. Note: We cant push - // or pop from m_scripts inside this loop or it may invalidate script. - for (const auto &script : m_scripts) { - if (!script->context.isValid()) - continue; - lldb::addr_t context = *script->context; - - if (contextReferences.find(context) != contextReferences.end()) { - contextReferences[context]++; - } else { - contextReferences[context] = 1; - } - } - - for (const auto &cRef : contextReferences) { - strm.Printf("Context 0x%" PRIx64 ": %" PRIu64 " script instances", - cRef.first, cRef.second); - strm.EOL(); - } - strm.IndentLess(); -} - -void RenderScriptRuntime::DumpKernels(Stream &strm) const { - strm.Printf("RenderScript Kernels:"); - strm.EOL(); - strm.IndentMore(); - for (const auto &module : m_rsmodules) { - strm.Printf("Resource '%s':", module->m_resname.c_str()); - strm.EOL(); - for (const auto &kernel : module->m_kernels) { - strm.Indent(kernel.m_name.GetStringRef()); - strm.EOL(); - } - } - strm.IndentLess(); -} - -RenderScriptRuntime::AllocationDetails * -RenderScriptRuntime::FindAllocByID(Stream &strm, const uint32_t alloc_id) { - AllocationDetails *alloc = nullptr; - - // See if we can find allocation using id as an index; - if (alloc_id <= m_allocations.size() && alloc_id != 0 && - m_allocations[alloc_id - 1]->id == alloc_id) { - alloc = m_allocations[alloc_id - 1].get(); - return alloc; - } - - // Fallback to searching - for (const auto &a : m_allocations) { - if (a->id == alloc_id) { - alloc = a.get(); - break; - } - } - - if (alloc == nullptr) { - strm.Printf("Error: Couldn't find allocation with id matching %" PRIu32, - alloc_id); - strm.EOL(); - } - - return alloc; -} - -// Prints the contents of an allocation to the output stream, which may be a -// file -bool RenderScriptRuntime::DumpAllocation(Stream &strm, StackFrame *frame_ptr, - const uint32_t id) { - Log *log = GetLog(LLDBLog::Language); - - // Check we can find the desired allocation - AllocationDetails *alloc = FindAllocByID(strm, id); - if (!alloc) - return false; // FindAllocByID() will print error message for us here - - LLDB_LOGF(log, "%s - found allocation 0x%" PRIx64, __FUNCTION__, - *alloc->address.get()); - - // Check we have information about the allocation, if not calculate it - if (alloc->ShouldRefresh()) { - LLDB_LOGF(log, "%s - allocation details not calculated yet, jitting info.", - __FUNCTION__); - - // JIT all the allocation information - if (!RefreshAllocation(alloc, frame_ptr)) { - strm.Printf("Error: Couldn't JIT allocation details"); - strm.EOL(); - return false; - } - } - - // Establish format and size of each data element - const uint32_t vec_size = *alloc->element.type_vec_size.get(); - const Element::DataType type = *alloc->element.type.get(); - - assert(type >= Element::RS_TYPE_NONE && type <= Element::RS_TYPE_FONT && - "Invalid allocation type"); - - lldb::Format format; - if (type >= Element::RS_TYPE_ELEMENT) - format = eFormatHex; - else - format = vec_size == 1 - ? static_cast<lldb::Format>( - AllocationDetails::RSTypeToFormat[type][eFormatSingle]) - : static_cast<lldb::Format>( - AllocationDetails::RSTypeToFormat[type][eFormatVector]); - - const uint32_t data_size = *alloc->element.datum_size.get(); - - LLDB_LOGF(log, "%s - element size %" PRIu32 " bytes, including padding", - __FUNCTION__, data_size); - - // Allocate a buffer to copy data into - std::shared_ptr<uint8_t> buffer = GetAllocationData(alloc, frame_ptr); - if (!buffer) { - strm.Printf("Error: Couldn't read allocation data"); - strm.EOL(); - return false; - } - - // Calculate stride between rows as there may be padding at end of rows since - // allocated memory is 16-byte aligned - if (!alloc->stride.isValid()) { - if (alloc->dimension.get()->dim_2 == 0) // We only have one dimension - alloc->stride = 0; - else if (!JITAllocationStride(alloc, frame_ptr)) { - strm.Printf("Error: Couldn't calculate allocation row stride"); - strm.EOL(); - return false; - } - } - const uint32_t stride = *alloc->stride.get(); - const uint32_t size = *alloc->size.get(); // Size of whole allocation - const uint32_t padding = - alloc->element.padding.isValid() ? *alloc->element.padding.get() : 0; - LLDB_LOGF(log, - "%s - stride %" PRIu32 " bytes, size %" PRIu32 - " bytes, padding %" PRIu32, - __FUNCTION__, stride, size, padding); - - // Find dimensions used to index loops, so need to be non-zero - uint32_t dim_x = alloc->dimension.get()->dim_1; - dim_x = dim_x == 0 ? 1 : dim_x; - - uint32_t dim_y = alloc->dimension.get()->dim_2; - dim_y = dim_y == 0 ? 1 : dim_y; - - uint32_t dim_z = alloc->dimension.get()->dim_3; - dim_z = dim_z == 0 ? 1 : dim_z; - - // Use data extractor to format output - const uint32_t target_ptr_size = - GetProcess()->GetTarget().GetArchitecture().GetAddressByteSize(); - DataExtractor alloc_data(buffer.get(), size, GetProcess()->GetByteOrder(), - target_ptr_size); - - uint32_t offset = 0; // Offset in buffer to next element to be printed - uint32_t prev_row = 0; // Offset to the start of the previous row - - // Iterate over allocation dimensions, printing results to user - strm.Printf("Data (X, Y, Z):"); - for (uint32_t z = 0; z < dim_z; ++z) { - for (uint32_t y = 0; y < dim_y; ++y) { - // Use stride to index start of next row. - if (!(y == 0 && z == 0)) - offset = prev_row + stride; - prev_row = offset; - - // Print each element in the row individually - for (uint32_t x = 0; x < dim_x; ++x) { - strm.Printf("\n(%" PRIu32 ", %" PRIu32 ", %" PRIu32 ") = ", x, y, z); - if ((type == Element::RS_TYPE_NONE) && - (alloc->element.children.size() > 0) && - (alloc->element.type_name != Element::GetFallbackStructName())) { - // Here we are dumping an Element of struct type. This is done using - // expression evaluation with the name of the struct type and pointer - // to element. Don't print the name of the resulting expression, - // since this will be '$[0-9]+' - DumpValueObjectOptions expr_options; - expr_options.SetHideName(true); - - // Setup expression as dereferencing a pointer cast to element - // address. - char expr_char_buffer[jit_max_expr_size]; - int written = - snprintf(expr_char_buffer, jit_max_expr_size, "*(%s*) 0x%" PRIx64, - alloc->element.type_name.AsCString(), - *alloc->data_ptr.get() + offset); - - if (written < 0 || written >= jit_max_expr_size) { - LLDB_LOGF(log, "%s - error in snprintf().", __FUNCTION__); - continue; - } - - // Evaluate expression - ValueObjectSP expr_result; - GetProcess()->GetTarget().EvaluateExpression(expr_char_buffer, - frame_ptr, expr_result); - - // Print the results to our stream. - expr_result->Dump(strm, expr_options); - } else { - DumpDataExtractor(alloc_data, &strm, offset, format, - data_size - padding, 1, 1, LLDB_INVALID_ADDRESS, 0, - 0); - } - offset += data_size; - } - } - } - strm.EOL(); - - return true; -} - -// Function recalculates all our cached information about allocations by -// jitting the RS runtime regarding each allocation we know about. Returns true -// if all allocations could be recomputed, false otherwise. -bool RenderScriptRuntime::RecomputeAllAllocations(Stream &strm, - StackFrame *frame_ptr) { - bool success = true; - for (auto &alloc : m_allocations) { - // JIT current allocation information - if (!RefreshAllocation(alloc.get(), frame_ptr)) { - strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32 - "\n", - alloc->id); - success = false; - } - } - - if (success) - strm.Printf("All allocations successfully recomputed"); - strm.EOL(); - - return success; -} - -// Prints information regarding currently loaded allocations. These details are -// gathered by jitting the runtime, which has as latency. Index parameter -// specifies a single allocation ID to print, or a zero value to print them all -void RenderScriptRuntime::ListAllocations(Stream &strm, StackFrame *frame_ptr, - const uint32_t index) { - strm.Printf("RenderScript Allocations:"); - strm.EOL(); - strm.IndentMore(); - - for (auto &alloc : m_allocations) { - // index will only be zero if we want to print all allocations - if (index != 0 && index != alloc->id) - continue; - - // JIT current allocation information - if (alloc->ShouldRefresh() && !RefreshAllocation(alloc.get(), frame_ptr)) { - strm.Printf("Error: Couldn't evaluate details for allocation %" PRIu32, - alloc->id); - strm.EOL(); - continue; - } - - strm.Printf("%" PRIu32 ":", alloc->id); - strm.EOL(); - strm.IndentMore(); - - strm.Indent("Context: "); - if (!alloc->context.isValid()) - strm.Printf("unknown\n"); - else - strm.Printf("0x%" PRIx64 "\n", *alloc->context.get()); - - strm.Indent("Address: "); - if (!alloc->address.isValid()) - strm.Printf("unknown\n"); - else - strm.Printf("0x%" PRIx64 "\n", *alloc->address.get()); - - strm.Indent("Data pointer: "); - if (!alloc->data_ptr.isValid()) - strm.Printf("unknown\n"); - else - strm.Printf("0x%" PRIx64 "\n", *alloc->data_ptr.get()); - - strm.Indent("Dimensions: "); - if (!alloc->dimension.isValid()) - strm.Printf("unknown\n"); - else - strm.Printf("(%" PRId32 ", %" PRId32 ", %" PRId32 ")\n", - alloc->dimension.get()->dim_1, alloc->dimension.get()->dim_2, - alloc->dimension.get()->dim_3); - - strm.Indent("Data Type: "); - if (!alloc->element.type.isValid() || - !alloc->element.type_vec_size.isValid()) - strm.Printf("unknown\n"); - else { - const int vector_size = *alloc->element.type_vec_size.get(); - Element::DataType type = *alloc->element.type.get(); - - if (!alloc->element.type_name.IsEmpty()) - strm.Printf("%s\n", alloc->element.type_name.AsCString()); - else { - // Enum value isn't monotonous, so doesn't always index - // RsDataTypeToString array - if (type >= Element::RS_TYPE_ELEMENT && type <= Element::RS_TYPE_FONT) - type = - static_cast<Element::DataType>((type - Element::RS_TYPE_ELEMENT) + - Element::RS_TYPE_MATRIX_2X2 + 1); - - if (type >= (sizeof(AllocationDetails::RsDataTypeToString) / - sizeof(AllocationDetails::RsDataTypeToString[0])) || - vector_size > 4 || vector_size < 1) - strm.Printf("invalid type\n"); - else - strm.Printf( - "%s\n", - AllocationDetails::RsDataTypeToString[static_cast<uint32_t>(type)] - [vector_size - 1]); - } - } - - strm.Indent("Data Kind: "); - if (!alloc->element.type_kind.isValid()) - strm.Printf("unknown\n"); - else { - const Element::DataKind kind = *alloc->element.type_kind.get(); - if (kind < Element::RS_KIND_USER || kind > Element::RS_KIND_PIXEL_YUV) - strm.Printf("invalid kind\n"); - else - strm.Printf( - "%s\n", - AllocationDetails::RsDataKindToString[static_cast<uint32_t>(kind)]); - } - - strm.EOL(); - strm.IndentLess(); - } - strm.IndentLess(); -} - -// Set breakpoints on every kernel found in RS module -void RenderScriptRuntime::BreakOnModuleKernels( - const RSModuleDescriptorSP rsmodule_sp) { - for (const auto &kernel : rsmodule_sp->m_kernels) { - // Don't set breakpoint on 'root' kernel - if (strcmp(kernel.m_name.AsCString(), "root") == 0) - continue; - - CreateKernelBreakpoint(kernel.m_name); - } -} - -// Method is internally called by the 'kernel breakpoint all' command to enable -// 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 = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); - - InitSearchFilter(target); - - // Set breakpoints on all the kernels - if (do_break && !m_breakAllKernels) { - m_breakAllKernels = true; - - for (const auto &module : m_rsmodules) - BreakOnModuleKernels(module); - - LLDB_LOGF(log, - "%s(True) - breakpoints set on all currently loaded kernels.", - __FUNCTION__); - } else if (!do_break && - m_breakAllKernels) // Breakpoints won't be set on any new kernels. - { - m_breakAllKernels = false; - - LLDB_LOGF(log, "%s(False) - breakpoints no longer automatically set.", - __FUNCTION__); - } -} - -// Given the name of a kernel this function creates a breakpoint using our own -// breakpoint resolver, and returns the Breakpoint shared pointer. -BreakpointSP -RenderScriptRuntime::CreateKernelBreakpoint(ConstString name) { - Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); - - if (!m_filtersp) { - LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", - __FUNCTION__); - return nullptr; - } - - BreakpointResolverSP resolver_sp(new RSBreakpointResolver(nullptr, name)); - Target &target = GetProcess()->GetTarget(); - BreakpointSP bp = target.CreateBreakpoint( - m_filtersp, resolver_sp, false, false, false); - - // Give RS breakpoints a specific name, so the user can manipulate them as a - // group. - Status err; - target.AddNameToBreakpoint(bp, "RenderScriptKernel", err); - if (err.Fail() && log) - LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__, - err.AsCString()); - - return bp; -} - -BreakpointSP -RenderScriptRuntime::CreateReductionBreakpoint(ConstString name, - int kernel_types) { - Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); - - if (!m_filtersp) { - LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", - __FUNCTION__); - return nullptr; - } - - BreakpointResolverSP resolver_sp(new RSReduceBreakpointResolver( - nullptr, name, &m_rsmodules, kernel_types)); - Target &target = GetProcess()->GetTarget(); - BreakpointSP bp = target.CreateBreakpoint( - m_filtersp, resolver_sp, false, false, false); - - // Give RS breakpoints a specific name, so the user can manipulate them as a - // group. - Status err; - target.AddNameToBreakpoint(bp, "RenderScriptReduction", err); - if (err.Fail() && log) - LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__, - err.AsCString()); - - return bp; -} - -// Given an expression for a variable this function tries to calculate the -// variable's value. If this is possible it returns true and sets the uint64_t -// parameter to the variables unsigned value. Otherwise function returns false. -bool RenderScriptRuntime::GetFrameVarAsUnsigned(const StackFrameSP frame_sp, - const char *var_name, - uint64_t &val) { - Log *log = GetLog(LLDBLog::Language); - Status err; - VariableSP var_sp; - - // Find variable in stack frame - ValueObjectSP value_sp(frame_sp->GetValueForVariableExpressionPath( - var_name, eNoDynamicValues, - StackFrame::eExpressionPathOptionCheckPtrVsMember | - StackFrame::eExpressionPathOptionsAllowDirectIVarAccess, - var_sp, err)); - if (!err.Success()) { - LLDB_LOGF(log, "%s - error, couldn't find '%s' in frame", __FUNCTION__, - var_name); - return false; - } - - // Find the uint32_t value for the variable - bool success = false; - val = value_sp->GetValueAsUnsigned(0, &success); - if (!success) { - LLDB_LOGF(log, "%s - error, couldn't parse '%s' as an uint32_t.", - __FUNCTION__, var_name); - return false; - } - - return true; -} - -// Function attempts to find the current coordinate of a kernel invocation by -// investigating the values of frame variables in the .expand function. These -// coordinates are returned via the coord array reference parameter. Returns -// true if the coordinates could be found, and false otherwise. -bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, - Thread *thread_ptr) { - static const char *const x_expr = "rsIndex"; - static const char *const y_expr = "p->current.y"; - static const char *const z_expr = "p->current.z"; - - Log *log = GetLog(LLDBLog::Language); - - if (!thread_ptr) { - LLDB_LOGF(log, "%s - Error, No thread pointer", __FUNCTION__); - - return false; - } - - // Walk the call stack looking for a function whose name has the suffix - // '.expand' and contains the variables we're looking for. - for (uint32_t i = 0; i < thread_ptr->GetStackFrameCount(); ++i) { - if (!thread_ptr->SetSelectedFrameByIndex(i)) - continue; - - StackFrameSP frame_sp = thread_ptr->GetSelectedFrame(); - if (!frame_sp) - continue; - - // Find the function name - const SymbolContext sym_ctx = - frame_sp->GetSymbolContext(eSymbolContextFunction); - const ConstString func_name = sym_ctx.GetFunctionName(); - if (!func_name) - continue; - - LLDB_LOGF(log, "%s - Inspecting function '%s'", __FUNCTION__, - func_name.GetCString()); - - // Check if function name has .expand suffix - if (!func_name.GetStringRef().endswith(".expand")) - continue; - - LLDB_LOGF(log, "%s - Found .expand function '%s'", __FUNCTION__, - func_name.GetCString()); - - // Get values for variables in .expand frame that tell us the current - // kernel invocation - uint64_t x, y, z; - bool found = GetFrameVarAsUnsigned(frame_sp, x_expr, x) && - GetFrameVarAsUnsigned(frame_sp, y_expr, y) && - GetFrameVarAsUnsigned(frame_sp, z_expr, z); - - if (found) { - // The RenderScript runtime uses uint32_t for these vars. If they're not - // within bounds, our frame parsing is garbage - assert(x <= UINT32_MAX && y <= UINT32_MAX && z <= UINT32_MAX); - coord.x = (uint32_t)x; - coord.y = (uint32_t)y; - coord.z = (uint32_t)z; - return true; - } - } - return false; -} - -// Callback when a kernel breakpoint hits and we're looking for a specific -// coordinate. Baton parameter contains a pointer to the target coordinate we -// want to break on. Function then checks the .expand frame for the current -// coordinate and breaks to user if it matches. Parameter 'break_id' is the id -// of the Breakpoint which made the callback. Parameter 'break_loc_id' is the -// id for the BreakpointLocation which was hit, a single logical breakpoint can -// have multiple addresses. -bool RenderScriptRuntime::KernelBreakpointHit(void *baton, - StoppointCallbackContext *ctx, - user_id_t break_id, - user_id_t break_loc_id) { - Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); - - assert(baton && - "Error: null baton in conditional kernel breakpoint callback"); - - // Coordinate we want to stop on - RSCoordinate target_coord = *static_cast<RSCoordinate *>(baton); - - LLDB_LOGF(log, "%s - Break ID %" PRIu64 ", " FMT_COORD, __FUNCTION__, - break_id, target_coord.x, target_coord.y, target_coord.z); - - // Select current thread - ExecutionContext context(ctx->exe_ctx_ref); - Thread *thread_ptr = context.GetThreadPtr(); - assert(thread_ptr && "Null thread pointer"); - - // Find current kernel invocation from .expand frame variables - RSCoordinate current_coord{}; - if (!GetKernelCoordinate(current_coord, thread_ptr)) { - LLDB_LOGF(log, "%s - Error, couldn't select .expand stack frame", - __FUNCTION__); - return false; - } - - LLDB_LOGF(log, "%s - " FMT_COORD, __FUNCTION__, current_coord.x, - current_coord.y, current_coord.z); - - // Check if the current kernel invocation coordinate matches our target - // coordinate - if (target_coord == current_coord) { - LLDB_LOGF(log, "%s, BREAKING " FMT_COORD, __FUNCTION__, current_coord.x, - current_coord.y, current_coord.z); - - BreakpointSP breakpoint_sp = - context.GetTargetPtr()->GetBreakpointByID(break_id); - assert(breakpoint_sp != nullptr && - "Error: Couldn't find breakpoint matching break id for callback"); - breakpoint_sp->SetEnabled(false); // Optimise since conditional breakpoint - // should only be hit once. - return true; - } - - // No match on coordinate - return false; -} - -void RenderScriptRuntime::SetConditional(BreakpointSP bp, Stream &messages, - const RSCoordinate &coord) { - messages.Printf("Conditional kernel breakpoint on coordinate " FMT_COORD, - coord.x, coord.y, coord.z); - messages.EOL(); - - // Allocate memory for the baton, and copy over coordinate - RSCoordinate *baton = new RSCoordinate(coord); - - // Create a callback that will be invoked every time the breakpoint is hit. - // The baton object passed to the handler is the target coordinate we want to - // break on. - bp->SetCallback(KernelBreakpointHit, baton, true); - - // Store a shared pointer to the baton, so the memory will eventually be - // cleaned up after destruction - m_conditional_breaks[bp->GetID()] = std::unique_ptr<RSCoordinate>(baton); -} - -// Tries to set a breakpoint on the start of a kernel, resolved using the -// kernel name. Argument 'coords', represents a three dimensional coordinate -// which can be used to specify a single kernel instance to break on. If this -// is set then we add a callback to the breakpoint. -bool RenderScriptRuntime::PlaceBreakpointOnKernel(TargetSP target, - Stream &messages, - const char *name, - const RSCoordinate *coord) { - if (!name) - return false; - - InitSearchFilter(target); - - ConstString kernel_name(name); - BreakpointSP bp = CreateKernelBreakpoint(kernel_name); - if (!bp) - return false; - - // We have a conditional breakpoint on a specific coordinate - if (coord) - SetConditional(bp, messages, *coord); - - bp->GetDescription(&messages, lldb::eDescriptionLevelInitial, false); - - return true; -} - -BreakpointSP -RenderScriptRuntime::CreateScriptGroupBreakpoint(ConstString name, - bool stop_on_all) { - Log *log = GetLog(LLDBLog::Language | LLDBLog::Breakpoints); - - if (!m_filtersp) { - LLDB_LOGF(log, "%s - error, no breakpoint search filter set.", - __FUNCTION__); - return nullptr; - } - - BreakpointResolverSP resolver_sp(new RSScriptGroupBreakpointResolver( - nullptr, name, m_scriptGroups, stop_on_all)); - Target &target = GetProcess()->GetTarget(); - BreakpointSP bp = target.CreateBreakpoint( - m_filtersp, resolver_sp, false, false, false); - // Give RS breakpoints a specific name, so the user can manipulate them as a - // group. - Status err; - target.AddNameToBreakpoint(bp, name.GetCString(), err); - if (err.Fail() && log) - LLDB_LOGF(log, "%s - error setting break name, '%s'.", __FUNCTION__, - err.AsCString()); - // ask the breakpoint to resolve itself - bp->ResolveBreakpoint(); - return bp; -} - -bool RenderScriptRuntime::PlaceBreakpointOnScriptGroup(TargetSP target, - Stream &strm, - ConstString name, - bool multi) { - InitSearchFilter(target); - BreakpointSP bp = CreateScriptGroupBreakpoint(name, multi); - if (bp) - bp->GetDescription(&strm, lldb::eDescriptionLevelInitial, false); - return bool(bp); -} - -bool RenderScriptRuntime::PlaceBreakpointOnReduction(TargetSP target, - Stream &messages, - const char *reduce_name, - const RSCoordinate *coord, - int kernel_types) { - if (!reduce_name) - return false; - - InitSearchFilter(target); - BreakpointSP bp = - CreateReductionBreakpoint(ConstString(reduce_name), kernel_types); - if (!bp) - return false; - - if (coord) - SetConditional(bp, messages, *coord); - - bp->GetDescription(&messages, lldb::eDescriptionLevelInitial, false); - - return true; -} - -void RenderScriptRuntime::DumpModules(Stream &strm) const { - strm.Printf("RenderScript Modules:"); - strm.EOL(); - strm.IndentMore(); - for (const auto &module : m_rsmodules) { - module->Dump(strm); - } - strm.IndentLess(); -} - -RenderScriptRuntime::ScriptDetails * -RenderScriptRuntime::LookUpScript(addr_t address, bool create) { - for (const auto &s : m_scripts) { - if (s->script.isValid()) - if (*s->script == address) - return s.get(); - } - if (create) { - std::unique_ptr<ScriptDetails> s(new ScriptDetails); - s->script = address; - m_scripts.push_back(std::move(s)); - return m_scripts.back().get(); - } - return nullptr; -} - -RenderScriptRuntime::AllocationDetails * -RenderScriptRuntime::LookUpAllocation(addr_t address) { - for (const auto &a : m_allocations) { - if (a->address.isValid()) - if (*a->address == address) - return a.get(); - } - return nullptr; -} - -RenderScriptRuntime::AllocationDetails * -RenderScriptRuntime::CreateAllocation(addr_t address) { - Log *log = GetLog(LLDBLog::Language); - - // Remove any previous allocation which contains the same address - auto it = m_allocations.begin(); - while (it != m_allocations.end()) { - if (*((*it)->address) == address) { - LLDB_LOGF(log, "%s - Removing allocation id: %d, address: 0x%" PRIx64, - __FUNCTION__, (*it)->id, address); - - it = m_allocations.erase(it); - } else { - it++; - } - } - - std::unique_ptr<AllocationDetails> a(new AllocationDetails); - a->address = address; - m_allocations.push_back(std::move(a)); - return m_allocations.back().get(); -} - -bool RenderScriptRuntime::ResolveKernelName(lldb::addr_t kernel_addr, - ConstString &name) { - Log *log = GetLog(LLDBLog::Symbols); - - Target &target = GetProcess()->GetTarget(); - Address resolved; - // RenderScript module - if (!target.GetSectionLoadList().ResolveLoadAddress(kernel_addr, resolved)) { - LLDB_LOGF(log, "%s: unable to resolve 0x%" PRIx64 " to a loaded symbol", - __FUNCTION__, kernel_addr); - return false; - } - - Symbol *sym = resolved.CalculateSymbolContextSymbol(); - if (!sym) - return false; - - name = sym->GetName(); - assert(IsRenderScriptModule(resolved.CalculateSymbolContextModule())); - LLDB_LOGF(log, "%s: 0x%" PRIx64 " resolved to the symbol '%s'", __FUNCTION__, - kernel_addr, name.GetCString()); - return true; -} - -void RSModuleDescriptor::Dump(Stream &strm) const { - int indent = strm.GetIndentLevel(); - - strm.Indent(); - m_module->GetFileSpec().Dump(strm.AsRawOstream()); - strm.Indent(m_module->GetNumCompileUnits() ? "Debug info loaded." - : "Debug info does not exist."); - strm.EOL(); - strm.IndentMore(); - - strm.Indent(); - strm.Printf("Globals: %" PRIu64, static_cast<uint64_t>(m_globals.size())); - strm.EOL(); - strm.IndentMore(); - for (const auto &global : m_globals) { - global.Dump(strm); - } - strm.IndentLess(); - - strm.Indent(); - strm.Printf("Kernels: %" PRIu64, static_cast<uint64_t>(m_kernels.size())); - strm.EOL(); - strm.IndentMore(); - for (const auto &kernel : m_kernels) { - kernel.Dump(strm); - } - strm.IndentLess(); - - strm.Indent(); - strm.Printf("Pragmas: %" PRIu64, static_cast<uint64_t>(m_pragmas.size())); - strm.EOL(); - strm.IndentMore(); - for (const auto &key_val : m_pragmas) { - strm.Indent(); - strm.Printf("%s: %s", key_val.first.c_str(), key_val.second.c_str()); - strm.EOL(); - } - strm.IndentLess(); - - strm.Indent(); - strm.Printf("Reductions: %" PRIu64, - static_cast<uint64_t>(m_reductions.size())); - strm.EOL(); - strm.IndentMore(); - for (const auto &reduction : m_reductions) { - reduction.Dump(strm); - } - - strm.SetIndentLevel(indent); -} - -void RSGlobalDescriptor::Dump(Stream &strm) const { - strm.Indent(m_name.GetStringRef()); - VariableList var_list; - m_module->m_module->FindGlobalVariables(m_name, CompilerDeclContext(), 1U, - var_list); - if (var_list.GetSize() == 1) { - auto var = var_list.GetVariableAtIndex(0); - auto type = var->GetType(); - if (type) { - strm.Printf(" - "); - type->DumpTypeName(&strm); - } else { - strm.Printf(" - Unknown Type"); - } - } else { - strm.Printf(" - variable identified, but not found in binary"); - const Symbol *s = m_module->m_module->FindFirstSymbolWithNameAndType( - m_name, eSymbolTypeData); - if (s) { - strm.Printf(" (symbol exists) "); - } - } - - strm.EOL(); -} - -void RSKernelDescriptor::Dump(Stream &strm) const { - strm.Indent(m_name.GetStringRef()); - strm.EOL(); -} - -void RSReductionDescriptor::Dump(lldb_private::Stream &stream) const { - stream.Indent(m_reduce_name.GetStringRef()); - stream.IndentMore(); - stream.EOL(); - stream.Indent(); - stream.Printf("accumulator: %s", m_accum_name.AsCString()); - stream.EOL(); - stream.Indent(); - stream.Printf("initializer: %s", m_init_name.AsCString()); - stream.EOL(); - stream.Indent(); - stream.Printf("combiner: %s", m_comb_name.AsCString()); - stream.EOL(); - stream.Indent(); - stream.Printf("outconverter: %s", m_outc_name.AsCString()); - stream.EOL(); - // XXX This is currently unspecified by RenderScript, and unused - // stream.Indent(); - // stream.Printf("halter: '%s'", m_init_name.AsCString()); - // stream.EOL(); - stream.IndentLess(); -} - -class CommandObjectRenderScriptRuntimeModuleDump : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeModuleDump(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript module dump", - "Dumps renderscript specific information for all modules.", - "renderscript module dump", - eCommandRequiresProcess | eCommandProcessMustBeLaunched) {} - - ~CommandObjectRenderScriptRuntimeModuleDump() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - runtime->DumpModules(result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } -}; - -class CommandObjectRenderScriptRuntimeModule : public CommandObjectMultiword { -public: - CommandObjectRenderScriptRuntimeModule(CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "renderscript module", - "Commands that deal with RenderScript modules.", - nullptr) { - LoadSubCommand( - "dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeModuleDump( - interpreter))); - } - - ~CommandObjectRenderScriptRuntimeModule() override = default; -}; - -class CommandObjectRenderScriptRuntimeKernelList : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeKernelList(CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript kernel list", - "Lists renderscript kernel names and associated script resources.", - "renderscript kernel list", - eCommandRequiresProcess | eCommandProcessMustBeLaunched) {} - - ~CommandObjectRenderScriptRuntimeKernelList() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - runtime->DumpKernels(result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } -}; - -static constexpr OptionDefinition g_renderscript_reduction_bp_set_options[] = { - {LLDB_OPT_SET_1, false, "function-role", 't', - OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, - "Break on a comma separated set of reduction kernel types " - "(accumulator,outcoverter,combiner,initializer"}, - {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, - nullptr, {}, 0, eArgTypeValue, - "Set a breakpoint on a single invocation of the kernel with specified " - "coordinate.\n" - "Coordinate takes the form 'x[,y][,z] where x,y,z are positive " - "integers representing kernel dimensions. " - "Any unset dimensions will be defaulted to zero."}}; - -class CommandObjectRenderScriptRuntimeReductionBreakpointSet - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeReductionBreakpointSet( - CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript reduction breakpoint set", - "Set a breakpoint on named RenderScript general reductions", - "renderscript reduction breakpoint set <kernel_name> [-t " - "<reduction_kernel_type,...>]", - eCommandRequiresProcess | eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused), - m_options() { - CommandArgumentData name_arg{eArgTypeName, eArgRepeatPlain}; - m_arguments.push_back({name_arg}); - }; - - class CommandOptions : public Options { - public: - CommandOptions() : Options() {} - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *exe_ctx) override { - Status err; - StreamString err_str; - const int short_option = m_getopt_table[option_idx].val; - switch (short_option) { - case 't': - if (!ParseReductionTypes(option_arg, err_str)) - err.SetErrorStringWithFormat( - "Unable to deduce reduction types for %s: %s", - option_arg.str().c_str(), err_str.GetData()); - break; - case 'c': { - auto coord = RSCoordinate{}; - if (!ParseCoordinate(option_arg, coord)) - err.SetErrorStringWithFormat("unable to parse coordinate for %s", - option_arg.str().c_str()); - else { - m_have_coord = true; - m_coord = coord; - } - break; - } - default: - err.SetErrorStringWithFormat("Invalid option '-%c'", short_option); - } - return err; - } - - void OptionParsingStarting(ExecutionContext *exe_ctx) override { - m_have_coord = false; - } - - llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::ArrayRef(g_renderscript_reduction_bp_set_options); - } - - bool ParseReductionTypes(llvm::StringRef option_val, - StreamString &err_str) { - m_kernel_types = RSReduceBreakpointResolver::eKernelTypeNone; - const auto reduce_name_to_type = [](llvm::StringRef name) -> int { - return llvm::StringSwitch<int>(name) - .Case("accumulator", RSReduceBreakpointResolver::eKernelTypeAccum) - .Case("initializer", RSReduceBreakpointResolver::eKernelTypeInit) - .Case("outconverter", RSReduceBreakpointResolver::eKernelTypeOutC) - .Case("combiner", RSReduceBreakpointResolver::eKernelTypeComb) - .Case("all", RSReduceBreakpointResolver::eKernelTypeAll) - // Currently not exposed by the runtime - // .Case("halter", RSReduceBreakpointResolver::eKernelTypeHalter) - .Default(0); - }; - - // Matching a comma separated list of known words is fairly - // straightforward with PCRE, but we're using ERE, so we end up with a - // little ugliness... - RegularExpression match_type_list( - llvm::StringRef("^([[:alpha:]]+)(,[[:alpha:]]+){0,4}$")); - - assert(match_type_list.IsValid()); - - if (!match_type_list.Execute(option_val)) { - err_str.PutCString( - "a comma-separated list of kernel types is required"); - return false; - } - - // splitting on commas is much easier with llvm::StringRef than regex - llvm::SmallVector<llvm::StringRef, 5> type_names; - llvm::StringRef(option_val).split(type_names, ','); - - for (const auto &name : type_names) { - const int type = reduce_name_to_type(name); - if (!type) { - err_str.Printf("unknown kernel type name %s", name.str().c_str()); - return false; - } - m_kernel_types |= type; - } - - return true; - } - - int m_kernel_types = RSReduceBreakpointResolver::eKernelTypeAll; - llvm::StringRef m_reduce_name; - RSCoordinate m_coord; - bool m_have_coord = false; - }; - - Options *GetOptions() override { return &m_options; } - - bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - if (argc < 1) { - result.AppendErrorWithFormat("'%s' takes 1 argument of reduction name, " - "and an optional kernel type list", - m_cmd_name.c_str()); - return false; - } - - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - - auto &outstream = result.GetOutputStream(); - auto name = command.GetArgumentAtIndex(0); - auto &target = m_exe_ctx.GetTargetSP(); - auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr; - if (!runtime->PlaceBreakpointOnReduction(target, outstream, name, coord, - m_options.m_kernel_types)) { - result.AppendError("Error: unable to place breakpoint on reduction"); - return false; - } - result.AppendMessage("Breakpoint(s) created"); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - -private: - CommandOptions m_options; -}; - -static constexpr OptionDefinition g_renderscript_kernel_bp_set_options[] = { - {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, - nullptr, {}, 0, eArgTypeValue, - "Set a breakpoint on a single invocation of the kernel with specified " - "coordinate.\n" - "Coordinate takes the form 'x[,y][,z] where x,y,z are positive " - "integers representing kernel dimensions. " - "Any unset dimensions will be defaulted to zero."}}; - -class CommandObjectRenderScriptRuntimeKernelBreakpointSet - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeKernelBreakpointSet( - CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript kernel breakpoint set", - "Sets a breakpoint on a renderscript kernel.", - "renderscript kernel breakpoint set <kernel_name> [-c x,y,z]", - eCommandRequiresProcess | eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused), - m_options() { - CommandArgumentData name_arg{eArgTypeName, eArgRepeatPlain}; - m_arguments.push_back({name_arg}); - } - - ~CommandObjectRenderScriptRuntimeKernelBreakpointSet() override = default; - - Options *GetOptions() override { return &m_options; } - - class CommandOptions : public Options { - public: - CommandOptions() : Options() {} - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *exe_ctx) override { - Status err; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 'c': { - auto coord = RSCoordinate{}; - if (!ParseCoordinate(option_arg, coord)) - err.SetErrorStringWithFormat( - "Couldn't parse coordinate '%s', should be in format 'x,y,z'.", - option_arg.str().c_str()); - else { - m_have_coord = true; - m_coord = coord; - } - break; - } - default: - err.SetErrorStringWithFormat("unrecognized option '%c'", short_option); - break; - } - return err; - } - - void OptionParsingStarting(ExecutionContext *exe_ctx) override { - m_have_coord = false; - } - - llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::ArrayRef(g_renderscript_kernel_bp_set_options); - } - - RSCoordinate m_coord; - bool m_have_coord = false; - }; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - if (argc < 1) { - result.AppendErrorWithFormat( - "'%s' takes 1 argument of kernel name, and an optional coordinate.", - m_cmd_name.c_str()); - return false; - } - - RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - - auto &outstream = result.GetOutputStream(); - auto &target = m_exe_ctx.GetTargetSP(); - auto name = command.GetArgumentAtIndex(0); - auto coord = m_options.m_have_coord ? &m_options.m_coord : nullptr; - if (!runtime->PlaceBreakpointOnKernel(target, outstream, name, coord)) { - result.AppendErrorWithFormat( - "Error: unable to set breakpoint on kernel '%s'", name); - return false; - } - - result.AppendMessage("Breakpoint(s) created"); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - -private: - CommandOptions m_options; -}; - -class CommandObjectRenderScriptRuntimeKernelBreakpointAll - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeKernelBreakpointAll( - CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript kernel breakpoint all", - "Automatically sets a breakpoint on all renderscript kernels that " - "are or will be loaded.\n" - "Disabling option means breakpoints will no longer be set on any " - "kernels loaded in the future, " - "but does not remove currently set breakpoints.", - "renderscript kernel breakpoint all <enable/disable>", - eCommandRequiresProcess | eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused) { - CommandArgumentData enable_arg{eArgTypeNone, eArgRepeatPlain}; - m_arguments.push_back({enable_arg}); - } - - ~CommandObjectRenderScriptRuntimeKernelBreakpointAll() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - if (argc != 1) { - result.AppendErrorWithFormat( - "'%s' takes 1 argument of 'enable' or 'disable'", m_cmd_name.c_str()); - return false; - } - - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - - bool do_break = false; - const char *argument = command.GetArgumentAtIndex(0); - if (strcmp(argument, "enable") == 0) { - do_break = true; - result.AppendMessage("Breakpoints will be set on all kernels."); - } else if (strcmp(argument, "disable") == 0) { - do_break = false; - result.AppendMessage("Breakpoints will not be set on any new kernels."); - } else { - result.AppendErrorWithFormat( - "Argument must be either 'enable' or 'disable'"); - return false; - } - - runtime->SetBreakAllKernels(do_break, m_exe_ctx.GetTargetSP()); - - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } -}; - -class CommandObjectRenderScriptRuntimeReductionBreakpoint - : public CommandObjectMultiword { -public: - CommandObjectRenderScriptRuntimeReductionBreakpoint( - CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "renderscript reduction breakpoint", - "Commands that manipulate breakpoints on " - "renderscript general reductions.", - nullptr) { - LoadSubCommand( - "set", CommandObjectSP( - new CommandObjectRenderScriptRuntimeReductionBreakpointSet( - interpreter))); - } - - ~CommandObjectRenderScriptRuntimeReductionBreakpoint() override = default; -}; - -class CommandObjectRenderScriptRuntimeKernelCoordinate - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeKernelCoordinate( - CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript kernel coordinate", - "Shows the (x,y,z) coordinate of the current kernel invocation.", - "renderscript kernel coordinate", - eCommandRequiresProcess | eCommandProcessMustBeLaunched | - eCommandProcessMustBePaused) {} - - ~CommandObjectRenderScriptRuntimeKernelCoordinate() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - RSCoordinate coord{}; - bool success = RenderScriptRuntime::GetKernelCoordinate( - coord, m_exe_ctx.GetThreadPtr()); - Stream &stream = result.GetOutputStream(); - - if (success) { - stream.Printf("Coordinate: " FMT_COORD, coord.x, coord.y, coord.z); - stream.EOL(); - result.SetStatus(eReturnStatusSuccessFinishResult); - } else { - stream.Printf("Error: Coordinate could not be found."); - stream.EOL(); - result.SetStatus(eReturnStatusFailed); - } - return true; - } -}; - -class CommandObjectRenderScriptRuntimeKernelBreakpoint - : public CommandObjectMultiword { -public: - CommandObjectRenderScriptRuntimeKernelBreakpoint( - CommandInterpreter &interpreter) - : CommandObjectMultiword( - interpreter, "renderscript kernel", - "Commands that generate breakpoints on renderscript kernels.", - nullptr) { - LoadSubCommand( - "set", - CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointSet( - interpreter))); - LoadSubCommand( - "all", - CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelBreakpointAll( - interpreter))); - } - - ~CommandObjectRenderScriptRuntimeKernelBreakpoint() override = default; -}; - -class CommandObjectRenderScriptRuntimeKernel : public CommandObjectMultiword { -public: - CommandObjectRenderScriptRuntimeKernel(CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "renderscript kernel", - "Commands that deal with RenderScript kernels.", - nullptr) { - LoadSubCommand( - "list", CommandObjectSP(new CommandObjectRenderScriptRuntimeKernelList( - interpreter))); - LoadSubCommand( - "coordinate", - CommandObjectSP( - new CommandObjectRenderScriptRuntimeKernelCoordinate(interpreter))); - LoadSubCommand( - "breakpoint", - CommandObjectSP( - new CommandObjectRenderScriptRuntimeKernelBreakpoint(interpreter))); - } - - ~CommandObjectRenderScriptRuntimeKernel() override = default; -}; - -class CommandObjectRenderScriptRuntimeContextDump : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeContextDump(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "renderscript context dump", - "Dumps renderscript context information.", - "renderscript context dump", - eCommandRequiresProcess | - eCommandProcessMustBeLaunched) {} - - ~CommandObjectRenderScriptRuntimeContextDump() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - runtime->DumpContexts(result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } -}; - -static constexpr OptionDefinition g_renderscript_runtime_alloc_dump_options[] = { - {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, - nullptr, {}, 0, eArgTypeFilename, - "Print results to specified file instead of command line."}}; - -class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword { -public: - CommandObjectRenderScriptRuntimeContext(CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "renderscript context", - "Commands that deal with RenderScript contexts.", - nullptr) { - LoadSubCommand( - "dump", CommandObjectSP(new CommandObjectRenderScriptRuntimeContextDump( - interpreter))); - } - - ~CommandObjectRenderScriptRuntimeContext() override = default; -}; - -class CommandObjectRenderScriptRuntimeAllocationDump - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeAllocationDump( - CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "renderscript allocation dump", - "Displays the contents of a particular allocation", - "renderscript allocation dump <ID>", - eCommandRequiresProcess | - eCommandProcessMustBeLaunched), - m_options() { - CommandArgumentData id_arg{eArgTypeUnsignedInteger, eArgRepeatPlain}; - m_arguments.push_back({id_arg}); - } - - ~CommandObjectRenderScriptRuntimeAllocationDump() override = default; - - Options *GetOptions() override { return &m_options; } - - class CommandOptions : public Options { - public: - CommandOptions() : Options() {} - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *exe_ctx) override { - Status err; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 'f': - m_outfile.SetFile(option_arg, FileSpec::Style::native); - FileSystem::Instance().Resolve(m_outfile); - if (FileSystem::Instance().Exists(m_outfile)) { - m_outfile.Clear(); - err.SetErrorStringWithFormat("file already exists: '%s'", - option_arg.str().c_str()); - } - break; - default: - err.SetErrorStringWithFormat("unrecognized option '%c'", short_option); - break; - } - return err; - } - - void OptionParsingStarting(ExecutionContext *exe_ctx) override { - m_outfile.Clear(); - } - - llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::ArrayRef(g_renderscript_runtime_alloc_dump_options); - } - - FileSpec m_outfile; - }; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - if (argc < 1) { - result.AppendErrorWithFormat("'%s' takes 1 argument, an allocation ID. " - "As well as an optional -f argument", - m_cmd_name.c_str()); - return false; - } - - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - - const char *id_cstr = command.GetArgumentAtIndex(0); - uint32_t id; - if (!llvm::to_integer(id_cstr, id)) { - result.AppendErrorWithFormat("invalid allocation id argument '%s'", - id_cstr); - return false; - } - - Stream *output_stream_p = nullptr; - std::unique_ptr<Stream> output_stream_storage; - - const FileSpec &outfile_spec = - m_options.m_outfile; // Dump allocation to file instead - if (outfile_spec) { - // Open output file - std::string path = outfile_spec.GetPath(); - auto file = FileSystem::Instance().Open(outfile_spec, - File::eOpenOptionWriteOnly | - File::eOpenOptionCanCreate); - if (file) { - output_stream_storage = - std::make_unique<StreamFile>(std::move(file.get())); - output_stream_p = output_stream_storage.get(); - result.GetOutputStream().Printf("Results written to '%s'", - path.c_str()); - result.GetOutputStream().EOL(); - } else { - std::string error = llvm::toString(file.takeError()); - result.AppendErrorWithFormat("Couldn't open file '%s': %s", - path.c_str(), error.c_str()); - return false; - } - } else - output_stream_p = &result.GetOutputStream(); - - assert(output_stream_p != nullptr); - bool dumped = - runtime->DumpAllocation(*output_stream_p, m_exe_ctx.GetFramePtr(), id); - - if (dumped) - result.SetStatus(eReturnStatusSuccessFinishResult); - else - result.SetStatus(eReturnStatusFailed); - - return true; - } - -private: - CommandOptions m_options; -}; - -static constexpr OptionDefinition g_renderscript_runtime_alloc_list_options[] = { - {LLDB_OPT_SET_1, false, "id", 'i', OptionParser::eRequiredArgument, nullptr, - {}, 0, eArgTypeIndex, - "Only show details of a single allocation with specified id."}}; - -class CommandObjectRenderScriptRuntimeAllocationList - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeAllocationList( - CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript allocation list", - "List renderscript allocations and their information.", - "renderscript allocation list", - eCommandRequiresProcess | eCommandProcessMustBeLaunched), - m_options() {} - - ~CommandObjectRenderScriptRuntimeAllocationList() override = default; - - Options *GetOptions() override { return &m_options; } - - class CommandOptions : public Options { - public: - CommandOptions() : Options() {} - - ~CommandOptions() override = default; - - Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, - ExecutionContext *exe_ctx) override { - Status err; - const int short_option = m_getopt_table[option_idx].val; - - switch (short_option) { - case 'i': - if (option_arg.getAsInteger(0, m_id)) - err.SetErrorStringWithFormat("invalid integer value for option '%c'", - short_option); - break; - default: - err.SetErrorStringWithFormat("unrecognized option '%c'", short_option); - break; - } - return err; - } - - void OptionParsingStarting(ExecutionContext *exe_ctx) override { m_id = 0; } - - llvm::ArrayRef<OptionDefinition> GetDefinitions() override { - return llvm::ArrayRef(g_renderscript_runtime_alloc_list_options); - } - - uint32_t m_id = 0; - }; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - runtime->ListAllocations(result.GetOutputStream(), m_exe_ctx.GetFramePtr(), - m_options.m_id); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } - -private: - CommandOptions m_options; -}; - -class CommandObjectRenderScriptRuntimeAllocationLoad - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeAllocationLoad( - CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript allocation load", - "Loads renderscript allocation contents from a file.", - "renderscript allocation load <ID> <filename>", - 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; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - if (argc != 2) { - result.AppendErrorWithFormat( - "'%s' takes 2 arguments, an allocation ID and filename to read from.", - m_cmd_name.c_str()); - return false; - } - - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - - const char *id_cstr = command.GetArgumentAtIndex(0); - uint32_t id; - if (!llvm::to_integer(id_cstr, id)) { - result.AppendErrorWithFormat("invalid allocation id argument '%s'", - id_cstr); - return false; - } - - const char *path = command.GetArgumentAtIndex(1); - bool loaded = runtime->LoadAllocation(result.GetOutputStream(), id, path, - m_exe_ctx.GetFramePtr()); - - if (loaded) - result.SetStatus(eReturnStatusSuccessFinishResult); - else - result.SetStatus(eReturnStatusFailed); - - return true; - } -}; - -class CommandObjectRenderScriptRuntimeAllocationSave - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeAllocationSave( - CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "renderscript allocation save", - "Write renderscript allocation contents to a file.", - "renderscript allocation save <ID> <filename>", - eCommandRequiresProcess | - 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; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - const size_t argc = command.GetArgumentCount(); - if (argc != 2) { - result.AppendErrorWithFormat( - "'%s' takes 2 arguments, an allocation ID and filename to read from.", - m_cmd_name.c_str()); - return false; - } - - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - - const char *id_cstr = command.GetArgumentAtIndex(0); - uint32_t id; - if (!llvm::to_integer(id_cstr, id)) { - result.AppendErrorWithFormat("invalid allocation id argument '%s'", - id_cstr); - return false; - } - - const char *path = command.GetArgumentAtIndex(1); - bool saved = runtime->SaveAllocation(result.GetOutputStream(), id, path, - m_exe_ctx.GetFramePtr()); - - if (saved) - result.SetStatus(eReturnStatusSuccessFinishResult); - else - result.SetStatus(eReturnStatusFailed); - - return true; - } -}; - -class CommandObjectRenderScriptRuntimeAllocationRefresh - : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeAllocationRefresh( - CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "renderscript allocation refresh", - "Recomputes the details of all allocations.", - "renderscript allocation refresh", - eCommandRequiresProcess | - eCommandProcessMustBeLaunched) {} - - ~CommandObjectRenderScriptRuntimeAllocationRefresh() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - - bool success = runtime->RecomputeAllAllocations(result.GetOutputStream(), - m_exe_ctx.GetFramePtr()); - - if (success) { - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } else { - result.SetStatus(eReturnStatusFailed); - return false; - } - } -}; - -class CommandObjectRenderScriptRuntimeAllocation - : public CommandObjectMultiword { -public: - CommandObjectRenderScriptRuntimeAllocation(CommandInterpreter &interpreter) - : CommandObjectMultiword( - interpreter, "renderscript allocation", - "Commands that deal with RenderScript allocations.", nullptr) { - LoadSubCommand( - "list", - CommandObjectSP( - new CommandObjectRenderScriptRuntimeAllocationList(interpreter))); - LoadSubCommand( - "dump", - CommandObjectSP( - new CommandObjectRenderScriptRuntimeAllocationDump(interpreter))); - LoadSubCommand( - "save", - CommandObjectSP( - new CommandObjectRenderScriptRuntimeAllocationSave(interpreter))); - LoadSubCommand( - "load", - CommandObjectSP( - new CommandObjectRenderScriptRuntimeAllocationLoad(interpreter))); - LoadSubCommand( - "refresh", - CommandObjectSP(new CommandObjectRenderScriptRuntimeAllocationRefresh( - interpreter))); - } - - ~CommandObjectRenderScriptRuntimeAllocation() override = default; -}; - -class CommandObjectRenderScriptRuntimeStatus : public CommandObjectParsed { -public: - CommandObjectRenderScriptRuntimeStatus(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "renderscript status", - "Displays current RenderScript runtime status.", - "renderscript status", - eCommandRequiresProcess | - eCommandProcessMustBeLaunched) {} - - ~CommandObjectRenderScriptRuntimeStatus() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - RenderScriptRuntime *runtime = llvm::cast<RenderScriptRuntime>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - runtime->DumpStatus(result.GetOutputStream()); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } -}; - -class CommandObjectRenderScriptRuntimeReduction - : public CommandObjectMultiword { -public: - CommandObjectRenderScriptRuntimeReduction(CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "renderscript reduction", - "Commands that handle general reduction kernels", - nullptr) { - LoadSubCommand( - "breakpoint", - CommandObjectSP(new CommandObjectRenderScriptRuntimeReductionBreakpoint( - interpreter))); - } - ~CommandObjectRenderScriptRuntimeReduction() override = default; -}; - -class CommandObjectRenderScriptRuntime : public CommandObjectMultiword { -public: - CommandObjectRenderScriptRuntime(CommandInterpreter &interpreter) - : CommandObjectMultiword( - interpreter, "renderscript", - "Commands for operating on the RenderScript runtime.", - "renderscript <subcommand> [<subcommand-options>]") { - LoadSubCommand( - "module", CommandObjectSP( - new CommandObjectRenderScriptRuntimeModule(interpreter))); - LoadSubCommand( - "status", CommandObjectSP( - new CommandObjectRenderScriptRuntimeStatus(interpreter))); - LoadSubCommand( - "kernel", CommandObjectSP( - new CommandObjectRenderScriptRuntimeKernel(interpreter))); - LoadSubCommand("context", - CommandObjectSP(new CommandObjectRenderScriptRuntimeContext( - interpreter))); - LoadSubCommand( - "allocation", - CommandObjectSP( - new CommandObjectRenderScriptRuntimeAllocation(interpreter))); - LoadSubCommand("scriptgroup", - NewCommandObjectRenderScriptScriptGroup(interpreter)); - LoadSubCommand( - "reduction", - CommandObjectSP( - new CommandObjectRenderScriptRuntimeReduction(interpreter))); - } - - ~CommandObjectRenderScriptRuntime() override = default; -}; - -void RenderScriptRuntime::Initiate() { assert(!m_initiated); } - -RenderScriptRuntime::RenderScriptRuntime(Process *process) - : lldb_private::CPPLanguageRuntime(process), m_initiated(false), - m_debuggerPresentFlagged(false), m_breakAllKernels(false), - m_ir_passes(nullptr) { - ModulesDidLoad(process->GetTarget().GetImages()); -} - -lldb::CommandObjectSP RenderScriptRuntime::GetCommandObject( - lldb_private::CommandInterpreter &interpreter) { - return CommandObjectSP(new CommandObjectRenderScriptRuntime(interpreter)); -} - -RenderScriptRuntime::~RenderScriptRuntime() = default; diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h deleted file mode 100644 index bc460706fd29..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h +++ /dev/null @@ -1,592 +0,0 @@ -//===-- RenderScriptRuntime.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_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H -#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H - -#include <array> -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" -#include "lldb/Core/Module.h" -#include "lldb/Expression/LLVMUserExpression.h" -#include "lldb/Target/LanguageRuntime.h" -#include "lldb/lldb-private.h" - -#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" - -namespace clang { -class TargetOptions; -} - -namespace lldb_private { -namespace lldb_renderscript { - -typedef uint32_t RSSlot; -class RSModuleDescriptor; -struct RSGlobalDescriptor; -struct RSKernelDescriptor; -struct RSReductionDescriptor; -struct RSScriptGroupDescriptor; - -typedef std::shared_ptr<RSModuleDescriptor> RSModuleDescriptorSP; -typedef std::shared_ptr<RSGlobalDescriptor> RSGlobalDescriptorSP; -typedef std::shared_ptr<RSKernelDescriptor> RSKernelDescriptorSP; -typedef std::shared_ptr<RSScriptGroupDescriptor> RSScriptGroupDescriptorSP; - -struct RSCoordinate { - uint32_t x = 0, y = 0, z = 0; - - RSCoordinate() = default; - - bool operator==(const lldb_renderscript::RSCoordinate &rhs) { - return x == rhs.x && y == rhs.y && z == rhs.z; - } -}; - -// Breakpoint Resolvers decide where a breakpoint is placed, so having our own -// allows us to limit the search scope to RS kernel modules. As well as check -// for .expand kernels as a fallback. -class RSBreakpointResolver : public BreakpointResolver { -public: - RSBreakpointResolver(const lldb::BreakpointSP &bp, ConstString name) - : BreakpointResolver(bp, BreakpointResolver::NameResolver), - m_kernel_name(name) {} - - void GetDescription(Stream *strm) override { - if (strm) - strm->Printf("RenderScript kernel breakpoint for '%s'", - m_kernel_name.AsCString()); - } - - void Dump(Stream *s) const override {} - - Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) override; - - lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } - - lldb::BreakpointResolverSP - CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { - lldb::BreakpointResolverSP ret_sp( - new RSBreakpointResolver(breakpoint, m_kernel_name)); - return ret_sp; - } - -protected: - ConstString m_kernel_name; -}; - -class RSReduceBreakpointResolver : public BreakpointResolver { -public: - enum ReduceKernelTypeFlags { - eKernelTypeAll = ~(0), - eKernelTypeNone = 0, - eKernelTypeAccum = (1 << 0), - eKernelTypeInit = (1 << 1), - eKernelTypeComb = (1 << 2), - eKernelTypeOutC = (1 << 3), - eKernelTypeHalter = (1 << 4) - }; - - RSReduceBreakpointResolver( - const lldb::BreakpointSP &breakpoint, ConstString reduce_name, - std::vector<lldb_renderscript::RSModuleDescriptorSP> *rs_modules, - int kernel_types = eKernelTypeAll) - : BreakpointResolver(breakpoint, BreakpointResolver::NameResolver), - m_reduce_name(reduce_name), m_rsmodules(rs_modules), - m_kernel_types(kernel_types) { - // The reduce breakpoint resolver handles adding breakpoints for named - // reductions. - // Breakpoints will be resolved for all constituent kernels in the named - // reduction - } - - void GetDescription(Stream *strm) override { - if (strm) - strm->Printf("RenderScript reduce breakpoint for '%s'", - m_reduce_name.AsCString()); - } - - void Dump(Stream *s) const override {} - - Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) override; - - lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } - - lldb::BreakpointResolverSP - CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { - lldb::BreakpointResolverSP ret_sp(new RSReduceBreakpointResolver( - breakpoint, m_reduce_name, m_rsmodules, m_kernel_types)); - return ret_sp; - } - -private: - ConstString m_reduce_name; // The name of the reduction - std::vector<lldb_renderscript::RSModuleDescriptorSP> *m_rsmodules; - int m_kernel_types; -}; - -struct RSKernelDescriptor { -public: - RSKernelDescriptor(const RSModuleDescriptor *module, llvm::StringRef name, - uint32_t slot) - : m_module(module), m_name(name), m_slot(slot) {} - - void Dump(Stream &strm) const; - - const RSModuleDescriptor *m_module; - ConstString m_name; - RSSlot m_slot; -}; - -struct RSGlobalDescriptor { -public: - RSGlobalDescriptor(const RSModuleDescriptor *module, llvm::StringRef name) - : m_module(module), m_name(name) {} - - void Dump(Stream &strm) const; - - const RSModuleDescriptor *m_module; - ConstString m_name; -}; - -struct RSReductionDescriptor { - RSReductionDescriptor(const RSModuleDescriptor *module, uint32_t sig, - uint32_t accum_data_size, llvm::StringRef name, - llvm::StringRef init_name, llvm::StringRef accum_name, - llvm::StringRef comb_name, llvm::StringRef outc_name, - llvm::StringRef halter_name = ".") - : m_module(module), m_reduce_name(name), m_init_name(init_name), - m_accum_name(accum_name), m_comb_name(comb_name), - m_outc_name(outc_name), m_halter_name(halter_name), m_accum_sig(0), - m_accum_data_size(0), m_comb_name_generated(false) { - // TODO Check whether the combiner is an autogenerated name, and track - // this - } - - void Dump(Stream &strm) const; - - const RSModuleDescriptor *m_module; - ConstString m_reduce_name; // This is the name given to the general reduction - // as a group as passed to pragma - // reduce(m_reduce_name). There is no kernel function with this name - ConstString m_init_name; // The name of the initializer name. "." if no - // initializer given - ConstString m_accum_name; // The accumulator function name. "." if not given - ConstString m_comb_name; // The name of the combiner function. If this was not - // given, a name is generated by the - // compiler. TODO - ConstString m_outc_name; // The name of the outconverter - - ConstString m_halter_name; // The name of the halter function. XXX This is not - // yet specified by the RenderScript - // compiler or runtime, and its semantics and existence is still under - // discussion by the - // RenderScript Contributors - RSSlot m_accum_sig; // metatdata signature for this reduction (bitwise mask of - // type information (see - // libbcc/include/bcinfo/MetadataExtractor.h - uint32_t m_accum_data_size; // Data size of the accumulator function input - bool m_comb_name_generated; // Was the combiner name generated by the compiler -}; - -class RSModuleDescriptor { - std::string m_slang_version; - std::string m_bcc_version; - - bool ParseVersionInfo(llvm::StringRef *, size_t n_lines); - - bool ParseExportForeachCount(llvm::StringRef *, size_t n_lines); - - bool ParseExportVarCount(llvm::StringRef *, size_t n_lines); - - bool ParseExportReduceCount(llvm::StringRef *, size_t n_lines); - - bool ParseBuildChecksum(llvm::StringRef *, size_t n_lines); - - bool ParsePragmaCount(llvm::StringRef *, size_t n_lines); - -public: - RSModuleDescriptor(const lldb::ModuleSP &module) : m_module(module) {} - - ~RSModuleDescriptor() = default; - - bool ParseRSInfo(); - - void Dump(Stream &strm) const; - - void WarnIfVersionMismatch(Stream *s) const; - - const lldb::ModuleSP m_module; - std::vector<RSKernelDescriptor> m_kernels; - std::vector<RSGlobalDescriptor> m_globals; - std::vector<RSReductionDescriptor> m_reductions; - std::map<std::string, std::string> m_pragmas; - std::string m_resname; -}; - -struct RSScriptGroupDescriptor { - struct Kernel { - ConstString m_name; - lldb::addr_t m_addr; - }; - ConstString m_name; - std::vector<Kernel> m_kernels; -}; - -typedef std::vector<RSScriptGroupDescriptorSP> RSScriptGroupList; - -class RSScriptGroupBreakpointResolver : public BreakpointResolver { -public: - RSScriptGroupBreakpointResolver(const lldb::BreakpointSP &bp, - ConstString name, - const RSScriptGroupList &groups, - bool stop_on_all) - : BreakpointResolver(bp, BreakpointResolver::NameResolver), - m_group_name(name), m_script_groups(groups), - m_stop_on_all(stop_on_all) {} - - void GetDescription(Stream *strm) override { - if (strm) - strm->Printf("RenderScript ScriptGroup breakpoint for '%s'", - m_group_name.AsCString()); - } - - void Dump(Stream *s) const override {} - - Searcher::CallbackReturn SearchCallback(SearchFilter &filter, - SymbolContext &context, - Address *addr) override; - - lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } - - lldb::BreakpointResolverSP - CopyForBreakpoint(lldb::BreakpointSP &breakpoint) override { - lldb::BreakpointResolverSP ret_sp(new RSScriptGroupBreakpointResolver( - breakpoint, m_group_name, m_script_groups, m_stop_on_all)); - return ret_sp; - } - -protected: - const RSScriptGroupDescriptorSP - FindScriptGroup(ConstString name) const { - for (auto sg : m_script_groups) { - if (ConstString::Compare(sg->m_name, name) == 0) - return sg; - } - return RSScriptGroupDescriptorSP(); - } - - ConstString m_group_name; - const RSScriptGroupList &m_script_groups; - bool m_stop_on_all; -}; -} // namespace lldb_renderscript - -class RenderScriptRuntime : public lldb_private::CPPLanguageRuntime { -public: - enum ModuleKind { - eModuleKindIgnored, - eModuleKindLibRS, - eModuleKindDriver, - eModuleKindImpl, - eModuleKindKernelObj - }; - - ~RenderScriptRuntime() override; - - // Static Functions - static void Initialize(); - - static void Terminate(); - - static lldb_private::LanguageRuntime * - CreateInstance(Process *process, lldb::LanguageType language); - - static lldb::CommandObjectSP - GetCommandObject(CommandInterpreter &interpreter); - - static llvm::StringRef GetPluginNameStatic() { return "renderscript"; } - - static char ID; - - bool isA(const void *ClassID) const override { - return ClassID == &ID || CPPLanguageRuntime::isA(ClassID); - } - - static bool classof(const LanguageRuntime *runtime) { - return runtime->isA(&ID); - } - - static bool IsRenderScriptModule(const lldb::ModuleSP &module_sp); - - static ModuleKind GetModuleKind(const lldb::ModuleSP &module_sp); - - static void ModulesDidLoad(const lldb::ProcessSP &process_sp, - const ModuleList &module_list); - - bool GetDynamicTypeAndAddress(ValueObject &in_value, - lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, - Address &address, - Value::ValueType &value_type) override; - - TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, - ValueObject &static_value) override; - - bool CouldHaveDynamicValue(ValueObject &in_value) override; - - lldb::BreakpointResolverSP - CreateExceptionResolver(const lldb::BreakpointSP &bp, - bool catch_bp, bool throw_bp) override; - - bool LoadModule(const lldb::ModuleSP &module_sp); - - void DumpModules(Stream &strm) const; - - void DumpContexts(Stream &strm) const; - - void DumpKernels(Stream &strm) const; - - bool DumpAllocation(Stream &strm, StackFrame *frame_ptr, const uint32_t id); - - void ListAllocations(Stream &strm, StackFrame *frame_ptr, - const uint32_t index); - - bool RecomputeAllAllocations(Stream &strm, StackFrame *frame_ptr); - - bool PlaceBreakpointOnKernel( - lldb::TargetSP target, Stream &messages, const char *name, - const lldb_renderscript::RSCoordinate *coords = nullptr); - - bool PlaceBreakpointOnReduction( - lldb::TargetSP target, Stream &messages, const char *reduce_name, - const lldb_renderscript::RSCoordinate *coords = nullptr, - int kernel_types = ~(0)); - - bool PlaceBreakpointOnScriptGroup(lldb::TargetSP target, Stream &strm, - ConstString name, bool stop_on_all); - - void SetBreakAllKernels(bool do_break, lldb::TargetSP target); - - void DumpStatus(Stream &strm) const; - - void ModulesDidLoad(const ModuleList &module_list) override; - - bool LoadAllocation(Stream &strm, const uint32_t alloc_id, - const char *filename, StackFrame *frame_ptr); - - bool SaveAllocation(Stream &strm, const uint32_t alloc_id, - const char *filename, StackFrame *frame_ptr); - - void Update(); - - void Initiate(); - - const lldb_renderscript::RSScriptGroupList &GetScriptGroups() const { - return m_scriptGroups; - }; - - bool IsKnownKernel(ConstString name) { - for (const auto &module : m_rsmodules) - for (const auto &kernel : module->m_kernels) - if (kernel.m_name == name) - return true; - return false; - } - - bool GetOverrideExprOptions(clang::TargetOptions &prototype); - - // PluginInterface protocol - llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } - - static bool GetKernelCoordinate(lldb_renderscript::RSCoordinate &coord, - Thread *thread_ptr); - - bool ResolveKernelName(lldb::addr_t kernel_address, ConstString &name); - -protected: - struct ScriptDetails; - struct AllocationDetails; - struct Element; - - lldb_renderscript::RSScriptGroupList m_scriptGroups; - - void InitSearchFilter(lldb::TargetSP target) { - if (!m_filtersp) - m_filtersp = - std::make_shared<SearchFilterForUnconstrainedSearches>(target); - } - - void FixupScriptDetails(lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); - - void LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind); - - bool RefreshAllocation(AllocationDetails *alloc, StackFrame *frame_ptr); - - bool EvalRSExpression(const char *expression, StackFrame *frame_ptr, - uint64_t *result); - - lldb::BreakpointSP CreateScriptGroupBreakpoint(ConstString name, - bool multi); - - lldb::BreakpointSP CreateKernelBreakpoint(ConstString name); - - lldb::BreakpointSP CreateReductionBreakpoint(ConstString name, - int kernel_types); - - void BreakOnModuleKernels( - const lldb_renderscript::RSModuleDescriptorSP rsmodule_sp); - - struct RuntimeHook; - typedef void (RenderScriptRuntime::*CaptureStateFn)( - RuntimeHook *hook_info, - ExecutionContext &context); // Please do this! - - struct HookDefn { - const char *name; - const char *symbol_name_m32; // mangled name for the 32 bit architectures - const char *symbol_name_m64; // mangled name for the 64 bit archs - uint32_t version; - ModuleKind kind; - CaptureStateFn grabber; - }; - - struct RuntimeHook { - lldb::addr_t address; - const HookDefn *defn; - lldb::BreakpointSP bp_sp; - }; - - typedef std::shared_ptr<RuntimeHook> RuntimeHookSP; - - lldb::ModuleSP m_libRS; - lldb::ModuleSP m_libRSDriver; - lldb::ModuleSP m_libRSCpuRef; - std::vector<lldb_renderscript::RSModuleDescriptorSP> m_rsmodules; - - std::vector<std::unique_ptr<ScriptDetails>> m_scripts; - std::vector<std::unique_ptr<AllocationDetails>> m_allocations; - - std::map<lldb::addr_t, lldb_renderscript::RSModuleDescriptorSP> - m_scriptMappings; - std::map<lldb::addr_t, RuntimeHookSP> m_runtimeHooks; - std::map<lldb::user_id_t, std::unique_ptr<lldb_renderscript::RSCoordinate>> - m_conditional_breaks; - - lldb::SearchFilterSP - m_filtersp; // Needed to create breakpoints through Target API - - bool m_initiated; - bool m_debuggerPresentFlagged; - bool m_breakAllKernels; - static const HookDefn s_runtimeHookDefns[]; - static const size_t s_runtimeHookCount; - LLVMUserExpression::IRPasses *m_ir_passes; - -private: - RenderScriptRuntime(Process *process); // Call CreateInstance instead. - - static bool HookCallback(void *baton, StoppointCallbackContext *ctx, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id); - - static bool KernelBreakpointHit(void *baton, StoppointCallbackContext *ctx, - lldb::user_id_t break_id, - lldb::user_id_t break_loc_id); - - void HookCallback(RuntimeHook *hook_info, ExecutionContext &context); - - // Callback function when 'debugHintScriptGroup2' executes on the target. - void CaptureDebugHintScriptGroup2(RuntimeHook *hook_info, - ExecutionContext &context); - - void CaptureScriptInit(RuntimeHook *hook_info, ExecutionContext &context); - - void CaptureAllocationInit(RuntimeHook *hook_info, ExecutionContext &context); - - void CaptureAllocationDestroy(RuntimeHook *hook_info, - ExecutionContext &context); - - void CaptureSetGlobalVar(RuntimeHook *hook_info, ExecutionContext &context); - - void CaptureScriptInvokeForEachMulti(RuntimeHook *hook_info, - ExecutionContext &context); - - AllocationDetails *FindAllocByID(Stream &strm, const uint32_t alloc_id); - - std::shared_ptr<uint8_t> GetAllocationData(AllocationDetails *alloc, - StackFrame *frame_ptr); - - void SetElementSize(Element &elem); - - static bool GetFrameVarAsUnsigned(const lldb::StackFrameSP, - const char *var_name, uint64_t &val); - - void FindStructTypeName(Element &elem, StackFrame *frame_ptr); - - size_t PopulateElementHeaders(const std::shared_ptr<uint8_t> header_buffer, - size_t offset, const Element &elem); - - size_t CalculateElementHeaderSize(const Element &elem); - - void SetConditional(lldb::BreakpointSP bp, lldb_private::Stream &messages, - const lldb_renderscript::RSCoordinate &coord); - // - // Helper functions for jitting the runtime - // - - bool JITDataPointer(AllocationDetails *alloc, StackFrame *frame_ptr, - uint32_t x = 0, uint32_t y = 0, uint32_t z = 0); - - bool JITTypePointer(AllocationDetails *alloc, StackFrame *frame_ptr); - - bool JITTypePacked(AllocationDetails *alloc, StackFrame *frame_ptr); - - bool JITElementPacked(Element &elem, const lldb::addr_t context, - StackFrame *frame_ptr); - - bool JITAllocationSize(AllocationDetails *alloc, StackFrame *frame_ptr); - - bool JITSubelements(Element &elem, const lldb::addr_t context, - StackFrame *frame_ptr); - - bool JITAllocationStride(AllocationDetails *alloc, StackFrame *frame_ptr); - - // Search for a script detail object using a target address. - // If a script does not currently exist this function will return nullptr. - // If 'create' is true and there is no previous script with this address, - // then a new Script detail object will be created for this address and - // returned. - ScriptDetails *LookUpScript(lldb::addr_t address, bool create); - - // Search for a previously saved allocation detail object using a target - // address. - // If an allocation does not exist for this address then nullptr will be - // returned. - AllocationDetails *LookUpAllocation(lldb::addr_t address); - - // Creates a new allocation with the specified address assigning a new ID and - // removes - // any previous stored allocation which has the same address. - AllocationDetails *CreateAllocation(lldb::addr_t address); - - bool GetIRPasses(LLVMUserExpression::IRPasses &passes) override; -}; - -} // namespace lldb_private - -#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTRUNTIME_H 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 deleted file mode 100644 index 3eb2519dda9e..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.cpp +++ /dev/null @@ -1,163 +0,0 @@ -//===-- RenderScriptScriptGroup.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/Breakpoint/StoppointCallbackContext.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/CommandObjectMultiword.h" -#include "lldb/Interpreter/CommandReturnObject.h" -#include "lldb/Interpreter/Options.h" -#include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Symbol/VariableList.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/Target.h" -#include "lldb/Utility/Args.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Status.h" - -#include "RenderScriptRuntime.h" -#include "RenderScriptScriptGroup.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_renderscript; - -class CommandObjectRenderScriptScriptGroupBreakpointSet - : public CommandObjectParsed { -public: - CommandObjectRenderScriptScriptGroupBreakpointSet( - CommandInterpreter &interpreter) - : CommandObjectParsed( - interpreter, "renderscript scriptgroup breakpoint set", - "Place a breakpoint on all kernels forming a script group.", - "renderscript scriptgroup breakpoint set <group_name>", - eCommandRequiresProcess | eCommandProcessMustBeLaunched) { - CommandArgumentData name_arg{eArgTypeName, eArgRepeatPlus}; - m_arguments.push_back({name_arg}); - } - - ~CommandObjectRenderScriptScriptGroupBreakpointSet() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - Stream &stream = result.GetOutputStream(); - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - assert(runtime); - auto &target = m_exe_ctx.GetTargetSP(); - bool stop_on_all = false; - const llvm::StringRef long_stop_all("--stop-on-all"), short_stop_all("-a"); - std::vector<ConstString> sites; - sites.reserve(command.GetArgumentCount()); - for (size_t i = 0; i < command.GetArgumentCount(); ++i) { - const auto arg = command.GetArgumentAtIndex(i); - if (long_stop_all == arg || short_stop_all == arg) - stop_on_all = true; - else - sites.push_back(ConstString(arg)); - } - for (const auto &name : sites) { - runtime->PlaceBreakpointOnScriptGroup(target, stream, name, stop_on_all); - } - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } -}; - -class CommandObjectRenderScriptScriptGroupBreakpoint - : public CommandObjectMultiword { -public: - CommandObjectRenderScriptScriptGroupBreakpoint( - CommandInterpreter &interpreter) - : CommandObjectMultiword( - interpreter, "renderscript scriptgroup breakpoint", - "Renderscript scriptgroup breakpoint interaction.", - "renderscript scriptgroup breakpoint set [--stop-on-all/-a]" - "<scriptgroup name> ...", - eCommandRequiresProcess | eCommandProcessMustBeLaunched) { - LoadSubCommand( - "set", - CommandObjectSP(new CommandObjectRenderScriptScriptGroupBreakpointSet( - interpreter))); - } - - ~CommandObjectRenderScriptScriptGroupBreakpoint() override = default; -}; - -class CommandObjectRenderScriptScriptGroupList : public CommandObjectParsed { -public: - CommandObjectRenderScriptScriptGroupList(CommandInterpreter &interpreter) - : CommandObjectParsed(interpreter, "renderscript scriptgroup list", - "List all currently discovered script groups.", - "renderscript scriptgroup list", - eCommandRequiresProcess | - eCommandProcessMustBeLaunched) {} - - ~CommandObjectRenderScriptScriptGroupList() override = default; - - bool DoExecute(Args &command, CommandReturnObject &result) override { - Stream &stream = result.GetOutputStream(); - RenderScriptRuntime *runtime = static_cast<RenderScriptRuntime *>( - m_exe_ctx.GetProcessPtr()->GetLanguageRuntime( - eLanguageTypeExtRenderScript)); - assert(runtime); - const RSScriptGroupList &groups = runtime->GetScriptGroups(); - // print script group count - stream.Printf("%" PRIu64 " script %s", uint64_t(groups.size()), - (groups.size() == 1) ? "group" : "groups"); - stream.EOL(); - // print script group details - stream.IndentMore(); - for (const RSScriptGroupDescriptorSP &g : groups) { - if (g) { - stream.Indent(); - // script group name - stream.Printf("%s", g->m_name.AsCString()); - stream.EOL(); - // print out the kernels - stream.IndentMore(); - for (const auto &k : g->m_kernels) { - stream.Indent(); - stream.Printf(". %s", k.m_name.AsCString()); - stream.EOL(); - } - stream.IndentLess(); - } - } - stream.IndentLess(); - result.SetStatus(eReturnStatusSuccessFinishResult); - return true; - } -}; - -class CommandObjectRenderScriptScriptGroup : public CommandObjectMultiword { -public: - CommandObjectRenderScriptScriptGroup(CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "renderscript scriptgroup", - "Command set for interacting with scriptgroups.", - nullptr, eCommandRequiresProcess | - eCommandProcessMustBeLaunched) { - LoadSubCommand( - "breakpoint", - CommandObjectSP( - new CommandObjectRenderScriptScriptGroupBreakpoint(interpreter))); - LoadSubCommand( - "list", CommandObjectSP( - new CommandObjectRenderScriptScriptGroupList(interpreter))); - } - - ~CommandObjectRenderScriptScriptGroup() override = default; -}; - -lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup( - lldb_private::CommandInterpreter &interpreter) { - return CommandObjectSP(new CommandObjectRenderScriptScriptGroup(interpreter)); -} diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h deleted file mode 100644 index 03d3a7823a98..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptScriptGroup.h +++ /dev/null @@ -1,17 +0,0 @@ -//===-- RenderScriptScriptGroup.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_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H -#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H - -#include "lldb/Interpreter/CommandInterpreter.h" - -lldb::CommandObjectSP NewCommandObjectRenderScriptScriptGroup( - lldb_private::CommandInterpreter &interpreter); - -#endif // LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTSCRIPTGROUP_H 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 deleted file mode 100644 index 917242e9b287..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp +++ /dev/null @@ -1,271 +0,0 @@ -//===-- RenderScriptx86ABIFixups.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 <set> - -#include "llvm/ADT/StringRef.h" -#include "llvm/IR/BasicBlock.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/Instruction.h" -#include "llvm/IR/Instructions.h" -#include "llvm/IR/Module.h" -#include "llvm/IRReader/IRReader.h" -#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::CallInst *call_inst) { - // TODO get the list of renderscript modules from lldb and check if - // this llvm::Module calls into any of them. - const auto func_name = call_inst->getCalledFunction()->getName(); - if (func_name.startswith("llvm") || func_name.startswith("lldb")) - return false; - - if (call_inst->getCalledFunction()->isIntrinsic()) - return false; - - return true; -} - -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 - // for x86 and x86_64, (as well as the emulators) specifies there is no AVX, - // so bcc generates an sret function because we cannot natively return - // 256 bit vectors. - // This function simply checks whether a function has a > 128bit return type. - // 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. - if (!call_inst || !call_inst->getCalledFunction()) - return false; - - return call_inst->getCalledFunction() - ->getReturnType() - ->getPrimitiveSizeInBits() > 128; -} - -static bool isRSAllocationTy(const llvm::Type *type) { - return type->isStructTy() && - type->getStructName().startswith("struct.rs_allocation"); -} - -static bool isRSAllocationTyCallSite(llvm::CallInst *call_inst) { - if (!call_inst->hasByValArgument()) - return false; - 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; -} - -static llvm::FunctionType *cloneToStructRetFnTy(llvm::CallInst *call_inst) { - // on x86 StructReturn functions return a pointer to the return value, rather - // than the return value itself - // [ref](http://www.agner.org/optimize/calling_conventions.pdf section 6). We - // 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 = GetLog(LLDBLog::Language | LLDBLog::Expressions); - - assert(call_inst && "no CallInst"); - llvm::Function *orig = call_inst->getCalledFunction(); - assert(orig && "CallInst has no called function"); - llvm::FunctionType *orig_type = orig->getFunctionType(); - auto name = orig->getName(); - LLDB_LOGF(log, "%s - cloning to StructRet function for '%s'", __FUNCTION__, - name.str().c_str()); - - unsigned num_params = orig_type->getNumParams(); - std::vector<llvm::Type *> new_params{num_params + 1, nullptr}; - std::vector<llvm::Type *> params{orig_type->param_begin(), - orig_type->param_end()}; - - // This may not work if the function is somehow declared void as llvm is - // strongly typed and represents void* with i8* - assert(!orig_type->getReturnType()->isVoidTy() && - "Cannot add StructRet attribute to void function"); - llvm::PointerType *return_type_ptr_type = - llvm::PointerType::getUnqual(orig->getReturnType()); - assert(return_type_ptr_type && - "failed to get function return type PointerType"); - if (!return_type_ptr_type) - return nullptr; - - LLDB_LOGF(log, - "%s - return type pointer type for StructRet clone @ '0x%p':\n", - __FUNCTION__, (void *)return_type_ptr_type); - // put the sret pointer argument in place at the beginning of the - // argument list. - params.emplace(params.begin(), return_type_ptr_type); - assert(params.size() == num_params + 1); - return llvm::FunctionType::get(return_type_ptr_type, params, - orig->isVarArg()); -} - -static bool -findRSCallSites(llvm::Module &module, std::set<llvm::CallInst *> &rs_callsites, - bool (*predicate)(llvm::CallInst *)) { - bool found = false; - - for (auto &func : module.getFunctionList()) - for (auto &block : func) - for (auto &inst : block) { - llvm::CallInst *call_inst = - llvm::dyn_cast_or_null<llvm::CallInst>(&inst); - if (!call_inst || !call_inst->getCalledFunction()) - // This is not the call-site you are looking for... - continue; - if (isRSAPICall(call_inst) && predicate(call_inst)) { - rs_callsites.insert(call_inst); - found = true; - } - } - return found; -} - -static bool fixupX86StructRetCalls(llvm::Module &module) { - bool changed = false; - // changing a basic block while iterating over it seems to have some - // undefined behaviour going on so we find all RS callsites first, then fix - // them up after consuming the iterator. - std::set<llvm::CallInst *> rs_callsites; - if (!findRSCallSites(module, rs_callsites, isRSLargeReturnCall)) - return false; - - for (auto call_inst : rs_callsites) { - llvm::FunctionType *new_func_type = cloneToStructRetFnTy(call_inst); - assert(new_func_type && - "failed to clone functionType for Renderscript ABI fixup"); - - llvm::Function *func = call_inst->getCalledFunction(); - assert(func && "cannot resolve function in RenderScriptRuntime"); - // Copy the original call arguments - std::vector<llvm::Value *> new_call_args(call_inst->arg_begin(), - call_inst->arg_end()); - - // Allocate enough space to store the return value of the original function - // we pass a pointer to this allocation as the StructRet param, and then - // copy its value into the lldb return value - const llvm::DataLayout &DL = module.getDataLayout(); - llvm::AllocaInst *return_value_alloc = new llvm::AllocaInst( - func->getReturnType(), DL.getAllocaAddrSpace(), "var_vector_return_alloc", - call_inst); - // use the new allocation as the new first argument - new_call_args.emplace(new_call_args.begin(), - llvm::cast<llvm::Value>(return_value_alloc)); - llvm::PointerType *new_func_ptr_type = - llvm::PointerType::get(new_func_type, 0); - // Create the type cast from the old function type to the new one - llvm::Constant *new_func_cast = llvm::ConstantExpr::getCast( - llvm::Instruction::BitCast, func, new_func_ptr_type); - // create an allocation for a new function pointer - llvm::AllocaInst *new_func_ptr = - new llvm::AllocaInst(new_func_ptr_type, DL.getAllocaAddrSpace(), - "new_func_ptr", call_inst); - // store the new_func_cast to the newly allocated space - (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_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(func->getReturnType(), return_value_alloc, - "save_return_val", call_inst); - - // Now remove the old broken call - call_inst->replaceAllUsesWith(lldb_save_result_address); - call_inst->eraseFromParent(); - changed = true; - } - return changed; -} - -static bool fixupRSAllocationStructByValCalls(llvm::Module &module) { - // On x86_64, calls to functions in the RS runtime that take an - // `rs_allocation` type argument are actually handled as by-ref params by - // bcc, but appear to be passed by value by lldb (the callsite all use - // `struct byval`). On x86_64 Linux, struct arguments are transferred in - // registers if the struct size is no bigger than 128bits - // [ref](http://www.agner.org/optimize/calling_conventions.pdf) section 7.1 - // "Passing and returning objects" otherwise passed on the stack. an object - // of type `rs_allocation` is actually 256bits, so should be passed on the - // stack. However, code generated by bcc actually treats formal params of - // type `rs_allocation` as `rs_allocation *` so we need to convert the - // calling convention to pass by reference, and remove any hint of byval from - // formal parameters. - bool changed = false; - std::set<llvm::CallInst *> rs_callsites; - if (!findRSCallSites(module, rs_callsites, isRSAllocationTyCallSite)) - return false; - - std::set<llvm::Function *> rs_functions; - - // for all call instructions - for (auto call_inst : rs_callsites) { - // add the called function to a set so that we can strip its byval - // attributes in another pass - rs_functions.insert(call_inst->getCalledFunction()); - - // get the function attributes - llvm::AttributeList call_attribs = call_inst->getAttributes(); - - // iterate over the argument attributes - for (unsigned I : call_attribs.indexes()) { - // if this argument is passed by val - if (call_attribs.hasAttributeAtIndex(I, llvm::Attribute::ByVal)) { - // strip away the byval attribute - call_inst->removeAttributeAtIndex(I, llvm::Attribute::ByVal); - changed = true; - } - } - } - - // for all called function decls - for (auto func : rs_functions) { - // inspect all of the arguments in the call - for (auto &arg : func->args()) { - if (arg.hasByValAttr()) { - arg.removeAttr(llvm::Attribute::ByVal); - changed = true; - } - } - } - return changed; -} - -namespace lldb_private { -namespace lldb_renderscript { - -bool fixupX86FunctionCalls(llvm::Module &module) { - return fixupX86StructRetCalls(module); -} - -bool fixupX86_64FunctionCalls(llvm::Module &module) { - bool changed = false; - changed |= fixupX86StructRetCalls(module); - changed |= fixupRSAllocationStructByValCalls(module); - return changed; -} - -} // end namespace lldb_renderscript -} // end namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h b/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h deleted file mode 100644 index 7836fff4a3a9..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.h +++ /dev/null @@ -1,22 +0,0 @@ -//===-- RenderScriptx86ABIFixups.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_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTX86ABIFIXUPS_H -#define LLDB_SOURCE_PLUGINS_LANGUAGERUNTIME_RENDERSCRIPT_RENDERSCRIPTRUNTIME_RENDERSCRIPTX86ABIFIXUPS_H - -#include "llvm/IR/Module.h" - -namespace lldb_private { -namespace lldb_renderscript { - -bool fixupX86FunctionCalls(llvm::Module &module); - -bool fixupX86_64FunctionCalls(llvm::Module &module); -} -} -#endif 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 aaead88369b2..6efd2516578f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.cpp @@ -67,8 +67,11 @@ const char *memory_history_asan_command_prefix = R"( size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size, int *thread_id); size_t __asan_get_free_stack(void *addr, void **trace, size_t size, int *thread_id); } +)"; - struct data { +const char *memory_history_asan_command_format = + R"( + struct { void *alloc_trace[256]; size_t alloc_count; int alloc_tid; @@ -76,12 +79,7 @@ const char *memory_history_asan_command_prefix = R"( void *free_trace[256]; size_t free_count; int free_tid; - }; -)"; - -const char *memory_history_asan_command_format = - R"( - data t; + } t; t.alloc_count = __asan_get_alloc_stack((void *)0x%)" PRIx64 R"(, t.alloc_trace, 256, &t.alloc_tid); @@ -122,7 +120,7 @@ static void CreateHistoryThreadFromValueObject(ProcessSP process_sp, std::vector<lldb::addr_t> pcs; for (int i = 0; i < count; i++) { - addr_t pc = trace_sp->GetChildAtIndex(i, true)->GetValueAsUnsigned(0); + addr_t pc = trace_sp->GetChildAtIndex(i)->GetValueAsUnsigned(0); if (pc == 0 || pc == 1 || pc == LLDB_INVALID_ADDRESS) continue; pcs.push_back(pc); @@ -156,7 +154,8 @@ HistoryThreads MemoryHistoryASan::GetHistoryThreads(lldb::addr_t address) { if (!thread_sp) return result; - StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + StackFrameSP frame_sp = + thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); if (!frame_sp) return result; diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp index f26d6df1e910..b0afe0394622 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.cpp @@ -71,6 +71,7 @@ llvm::Triple::ArchType stringTo<llvm::Triple::ArchType>(llvm::StringRef Str) { .Case("arm", Triple::arm) .Cases("arm64", "arm64e", Triple::aarch64) .Case("mips", Triple::mips) + .Case("msp430", Triple::msp430) .Case("ppc", Triple::ppc) .Case("ppc64", Triple::ppc64) .Case("s390", Triple::systemz) diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h index 416f84fe2430..f10c8c41b793 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Breakpad/BreakpadRecords.h @@ -12,8 +12,8 @@ #include "lldb/Utility/UUID.h" #include "lldb/lldb-types.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/FormatProviders.h" +#include "llvm/TargetParser/Triple.h" #include <optional> namespace lldb_private { diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp new file mode 100644 index 000000000000..03c454bf3efa --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.cpp @@ -0,0 +1,311 @@ +//===-- ObjectFileCOFF.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 "ObjectFileCOFF.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Utility/LLDBLog.h" + +#include "llvm/Support/Error.h" +#include "llvm/Support/FormatAdapters.h" + +using namespace lldb; +using namespace lldb_private; + +using namespace llvm; +using namespace llvm::object; + +static bool IsCOFFObjectFile(const DataBufferSP &data) { + return identify_magic(toStringRef(data->GetData())) == + file_magic::coff_object; +} + +LLDB_PLUGIN_DEFINE(ObjectFileCOFF) + +char ObjectFileCOFF::ID; + +ObjectFileCOFF::~ObjectFileCOFF() = default; + +void ObjectFileCOFF::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + CreateMemoryInstance, GetModuleSpecifications); +} + +void ObjectFileCOFF::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +lldb_private::ObjectFile * +ObjectFileCOFF::CreateInstance(const ModuleSP &module_sp, DataBufferSP data_sp, + offset_t data_offset, const FileSpec *file, + offset_t file_offset, offset_t length) { + Log *log = GetLog(LLDBLog::Object); + + if (!data_sp) { + data_sp = MapFileData(*file, length, file_offset); + if (!data_sp) { + LLDB_LOG(log, + "Failed to create ObjectFileCOFF instance: cannot read file {0}", + file->GetPath()); + return nullptr; + } + data_offset = 0; + } + + assert(data_sp && "must have mapped file at this point"); + + if (!IsCOFFObjectFile(data_sp)) + return nullptr; + + if (data_sp->GetByteSize() < length) { + data_sp = MapFileData(*file, length, file_offset); + if (!data_sp) { + LLDB_LOG(log, + "Failed to create ObjectFileCOFF instance: cannot read file {0}", + file->GetPath()); + return nullptr; + } + data_offset = 0; + } + + + MemoryBufferRef buffer{toStringRef(data_sp->GetData()), + file->GetFilename().GetStringRef()}; + + Expected<std::unique_ptr<Binary>> binary = createBinary(buffer); + if (!binary) { + LLDB_LOG_ERROR(log, binary.takeError(), + "Failed to create binary for file ({1}): {0}", + file->GetPath()); + return nullptr; + } + + LLDB_LOG(log, "ObjectFileCOFF::ObjectFileCOFF module = {1} ({2}), file = {3}", + module_sp.get(), module_sp->GetSpecificationDescription(), + file->GetPath()); + + return new ObjectFileCOFF(unique_dyn_cast<COFFObjectFile>(std::move(*binary)), + module_sp, data_sp, data_offset, file, file_offset, + length); +} + +lldb_private::ObjectFile *ObjectFileCOFF::CreateMemoryInstance( + const ModuleSP &module_sp, WritableDataBufferSP data_sp, + const ProcessSP &process_sp, addr_t header) { + // FIXME: do we need to worry about construction from a memory region? + return nullptr; +} + +size_t ObjectFileCOFF::GetModuleSpecifications( + const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset, + offset_t file_offset, offset_t length, ModuleSpecList &specs) { + if (!IsCOFFObjectFile(data_sp)) + return 0; + + MemoryBufferRef buffer{toStringRef(data_sp->GetData()), + file.GetFilename().GetStringRef()}; + Expected<std::unique_ptr<Binary>> binary = createBinary(buffer); + if (!binary) { + Log *log = GetLog(LLDBLog::Object); + LLDB_LOG_ERROR(log, binary.takeError(), + "Failed to create binary for file ({1}): {0}", + file.GetFilename()); + return 0; + } + + std::unique_ptr<COFFObjectFile> object = + unique_dyn_cast<COFFObjectFile>(std::move(*binary)); + switch (static_cast<COFF::MachineTypes>(object->getMachine())) { + case COFF::IMAGE_FILE_MACHINE_I386: + specs.Append(ModuleSpec(file, ArchSpec("i686-unknown-windows-msvc"))); + return 1; + case COFF::IMAGE_FILE_MACHINE_AMD64: + specs.Append(ModuleSpec(file, ArchSpec("x86_64-unknown-windows-msvc"))); + return 1; + case COFF::IMAGE_FILE_MACHINE_ARMNT: + specs.Append(ModuleSpec(file, ArchSpec("armv7-unknown-windows-msvc"))); + return 1; + case COFF::IMAGE_FILE_MACHINE_ARM64: + specs.Append(ModuleSpec(file, ArchSpec("aarch64-unknown-windows-msvc"))); + return 1; + default: + return 0; + } +} + +void ObjectFileCOFF::Dump(Stream *stream) { + ModuleSP module(GetModule()); + if (!module) + return; + + std::lock_guard<std::recursive_mutex> guard(module->GetMutex()); + + stream->Printf("%p: ", static_cast<void *>(this)); + stream->Indent(); + stream->PutCString("ObjectFileCOFF"); + *stream << ", file = '" << m_file + << "', arch = " << GetArchitecture().GetArchitectureName() << '\n'; + + if (SectionList *sections = GetSectionList()) + sections->Dump(stream->AsRawOstream(), stream->GetIndentLevel(), nullptr, + true, std::numeric_limits<uint32_t>::max()); +} + +uint32_t ObjectFileCOFF::GetAddressByteSize() const { + return const_cast<ObjectFileCOFF *>(this)->GetArchitecture().GetAddressByteSize(); +} + +ArchSpec ObjectFileCOFF::GetArchitecture() { + switch (static_cast<COFF::MachineTypes>(m_object->getMachine())) { + case COFF::IMAGE_FILE_MACHINE_I386: + return ArchSpec("i686-unknown-windows-msvc"); + case COFF::IMAGE_FILE_MACHINE_AMD64: + return ArchSpec("x86_64-unknown-windows-msvc"); + case COFF::IMAGE_FILE_MACHINE_ARMNT: + return ArchSpec("armv7-unknown-windows-msvc"); + case COFF::IMAGE_FILE_MACHINE_ARM64: + return ArchSpec("aarch64-unknown-windows-msvc"); + default: + return ArchSpec(); + } +} + +void ObjectFileCOFF::CreateSections(lldb_private::SectionList §ions) { + if (m_sections_up) + return; + + m_sections_up = std::make_unique<SectionList>(); + ModuleSP module(GetModule()); + if (!module) + return; + + std::lock_guard<std::recursive_mutex> guard(module->GetMutex()); + + auto SectionType = [](StringRef Name, + const coff_section *Section) -> lldb::SectionType { + lldb::SectionType type = + StringSwitch<lldb::SectionType>(Name) + // DWARF Debug Sections + .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev) + .Case(".debug_info", eSectionTypeDWARFDebugInfo) + .Case(".debug_line", eSectionTypeDWARFDebugLine) + .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames) + .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes) + .Case(".debug_str", eSectionTypeDWARFDebugStr) + // CodeView Debug Sections: .debug$S, .debug$T + .StartsWith(".debug$", eSectionTypeDebug) + .Case("clangast", eSectionTypeOther) + .Default(eSectionTypeInvalid); + if (type != eSectionTypeInvalid) + return type; + + if (Section->Characteristics & COFF::IMAGE_SCN_CNT_CODE) + return eSectionTypeCode; + if (Section->Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) + return eSectionTypeData; + if (Section->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) + return Section->SizeOfRawData ? eSectionTypeData : eSectionTypeZeroFill; + return eSectionTypeOther; + }; + auto Permissions = [](const object::coff_section *Section) -> uint32_t { + uint32_t permissions = 0; + if (Section->Characteristics & COFF::IMAGE_SCN_MEM_EXECUTE) + permissions |= lldb::ePermissionsExecutable; + if (Section->Characteristics & COFF::IMAGE_SCN_MEM_READ) + permissions |= lldb::ePermissionsReadable; + if (Section->Characteristics & COFF::IMAGE_SCN_MEM_WRITE) + permissions |= lldb::ePermissionsWritable; + return permissions; + }; + + for (const auto &SecRef : m_object->sections()) { + const auto COFFSection = m_object->getCOFFSection(SecRef); + + llvm::Expected<StringRef> Name = SecRef.getName(); + StringRef SectionName = Name ? *Name : COFFSection->Name; + if (!Name) + consumeError(Name.takeError()); + + SectionSP section = + std::make_unique<Section>(module, this, + static_cast<user_id_t>(SecRef.getIndex()), + ConstString(SectionName), + SectionType(SectionName, COFFSection), + COFFSection->VirtualAddress, + COFFSection->VirtualSize, + COFFSection->PointerToRawData, + COFFSection->SizeOfRawData, + COFFSection->getAlignment(), + 0); + section->SetPermissions(Permissions(COFFSection)); + + m_sections_up->AddSection(section); + sections.AddSection(section); + } +} + +void ObjectFileCOFF::ParseSymtab(lldb_private::Symtab &symtab) { + Log *log = GetLog(LLDBLog::Object); + + SectionList *sections = GetSectionList(); + symtab.Reserve(symtab.GetNumSymbols() + m_object->getNumberOfSymbols()); + + auto SymbolType = [](const COFFSymbolRef &Symbol) -> lldb::SymbolType { + if (Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) + return eSymbolTypeCode; + if (Symbol.getBaseType() == COFF::IMAGE_SYM_TYPE_NULL && + Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_NULL) + return eSymbolTypeData; + return eSymbolTypeInvalid; + }; + + for (const auto &SymRef : m_object->symbols()) { + const auto COFFSymRef = m_object->getCOFFSymbol(SymRef); + + Expected<StringRef> NameOrErr = SymRef.getName(); + if (auto error = NameOrErr.takeError()) { + LLDB_LOG(log, "ObjectFileCOFF: failed to get symbol name: {0}", + llvm::fmt_consume(std::move(error))); + continue; + } + + Symbol symbol; + symbol.GetMangled().SetValue(ConstString(*NameOrErr)); + + int16_t SecIdx = static_cast<int16_t>(COFFSymRef.getSectionNumber()); + if (SecIdx == COFF::IMAGE_SYM_ABSOLUTE) { + symbol.GetAddressRef() = Address{COFFSymRef.getValue()}; + symbol.SetType(eSymbolTypeAbsolute); + } else if (SecIdx >= 1) { + symbol.GetAddressRef() = Address(sections->GetSectionAtIndex(SecIdx - 1), + COFFSymRef.getValue()); + symbol.SetType(SymbolType(COFFSymRef)); + } + + symtab.AddSymbol(symbol); + } + + LLDB_LOG(log, "ObjectFileCOFF::ParseSymtab processed {0} symbols", + m_object->getNumberOfSymbols()); +} + +bool ObjectFileCOFF::ParseHeader() { + ModuleSP module(GetModule()); + if (!module) + return false; + + std::lock_guard<std::recursive_mutex> guard(module->GetMutex()); + + m_data.SetByteOrder(eByteOrderLittle); + m_data.SetAddressByteSize(GetAddressByteSize()); + + return true; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h new file mode 100644 index 000000000000..46c43f93f7ff --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/COFF/ObjectFileCOFF.h @@ -0,0 +1,116 @@ +//===-- ObjectFileCOFF.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_OBJECTFILE_COFF_OBJECTFILECOFF_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_COFF_OBJECTFILECOFF_H + +#include "lldb/Symbol/ObjectFile.h" + +#include "llvm/Object/COFF.h" + +/// \class ObjectFileELF +/// Generic COFF object file reader. +/// +/// This class provides a generic COFF reader plugin implementing the ObjectFile +/// protocol. Assumes that the COFF object format is a Microsoft style COFF +/// rather than the full generality afforded by it. +class ObjectFileCOFF : public lldb_private::ObjectFile { + std::unique_ptr<llvm::object::COFFObjectFile> m_object; + lldb_private::UUID m_uuid; + + ObjectFileCOFF(std::unique_ptr<llvm::object::COFFObjectFile> object, + 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) + : ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset), + m_object(std::move(object)) {} + +public: + ~ObjectFileCOFF() override; + + static void Initialize(); + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "COFF"; } + static llvm::StringRef GetPluginDescriptionStatic() { + return "COFF Object File Reader"; + } + + static lldb_private::ObjectFile * + 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::WritableDataBufferSP data_sp, + const lldb::ProcessSP &process_sp, lldb::addr_t header); + + static size_t 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); + + // LLVM RTTI support + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || ObjectFile::isA(ClassID); + } + static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } + + // PluginInterface protocol + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + // ObjectFile protocol + void Dump(lldb_private::Stream *stream) override; + + uint32_t GetAddressByteSize() const override; + + uint32_t GetDependentModules(lldb_private::FileSpecList &specs) override { + return 0; + } + + bool IsExecutable() const override { + // COFF is an object file format only, it cannot host an executable. + return false; + } + + lldb_private::ArchSpec GetArchitecture() override; + + void CreateSections(lldb_private::SectionList &) override; + + void ParseSymtab(lldb_private::Symtab &) override; + + bool IsStripped() override { + // FIXME see if there is a good way to identify a /Z7 v /Zi or /ZI build. + return false; + } + + lldb_private::UUID GetUUID() override { return m_uuid; } + + lldb::ByteOrder GetByteOrder() const override { + // Microsoft always uses little endian. + return lldb::ByteOrder::eByteOrderLittle; + } + + bool ParseHeader() override; + + lldb_private::ObjectFile::Type CalculateType() override { + // COFF is an object file format only, it cannot host an executable. + return lldb_private::ObjectFile::eTypeObjectFile; + } + + lldb_private::ObjectFile::Strata CalculateStrata() override { + // FIXME the object file may correspond to a kernel image. + return lldb_private::ObjectFile::eStrataUser; + } +}; + +#endif 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 5b75738e070c..700af84a14c0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -13,7 +13,6 @@ #include <optional> #include <unordered_map> -#include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" @@ -27,6 +26,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RangeMap.h" @@ -555,6 +555,14 @@ size_t ObjectFileELF::GetModuleSpecifications( if (header.Parse(data, &header_offset)) { if (data_sp) { ModuleSpec spec(file); + // In Android API level 23 and above, bionic dynamic linker is able to + // load .so file directly from zip file. In that case, .so file is + // page aligned and uncompressed, and this module spec should retain the + // .so file offset and file size to pass through the information from + // lldb-server to LLDB. For normal file, file_offset should be 0, + // length should be the size of the file. + spec.SetObjectOffset(file_offset); + spec.SetObjectSize(length); const uint32_t sub_type = subTypeFromElfHeader(header); spec.GetArchitecture().SetArchitecture( @@ -586,8 +594,12 @@ size_t ObjectFileELF::GetModuleSpecifications( __FUNCTION__, file.GetPath().c_str()); } + // When ELF file does not contain GNU build ID, the later code will + // calculate CRC32 with this data_sp file_offset and length. It is + // important for Android zip .so file, which is a slice of a file, + // to not access the outside of the file slice range. if (data_sp->GetByteSize() < length) - data_sp = MapFileData(file, -1, file_offset); + data_sp = MapFileData(file, length, file_offset); if (data_sp) data.SetData(data_sp); // In case there is header extension in the section #0, the header we @@ -623,7 +635,7 @@ size_t ObjectFileELF::GetModuleSpecifications( if (!gnu_debuglink_crc) { LLDB_SCOPED_TIMERF( "Calculating module crc32 %s with size %" PRIu64 " KiB", - file.GetLastPathComponent().AsCString(), + file.GetFilename().AsCString(), (length - file_offset) / 1024); // For core files - which usually don't happen to have a @@ -1661,6 +1673,7 @@ static SectionType GetSectionTypeFromName(llvm::StringRef Name) { .Case(".ARM.exidx", eSectionTypeARMexidx) .Case(".ARM.extab", eSectionTypeARMextab) .Cases(".bss", ".tbss", eSectionTypeZeroFill) + .Case(".ctf", eSectionTypeDebug) .Cases(".data", ".tdata", eSectionTypeData) .Case(".eh_frame", eSectionTypeEHFrame) .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink) @@ -2029,7 +2042,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, // contain the note section specifying the environment to Android but the // custom extension and file name makes it highly unlikely that this will // collide with anything else. - ConstString file_extension = m_file.GetFileNameExtension(); + llvm::StringRef file_extension = m_file.GetFileNameExtension(); bool skip_oatdata_oatexec = file_extension == ".oat" || file_extension == ".odex"; @@ -2637,6 +2650,44 @@ static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel, } } +static void ApplyELF32ABS32RelRelocation(Symtab *symtab, ELFRelocation &rel, + DataExtractor &debug_data, + Section *rel_section) { + Log *log = GetLog(LLDBLog::Modules); + Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol32(rel)); + if (symbol) { + addr_t value = symbol->GetAddressRef().GetFileAddress(); + if (value == LLDB_INVALID_ADDRESS) { + const char *name = symbol->GetName().GetCString(); + LLDB_LOGF(log, "Debug info symbol invalid: %s", name); + return; + } + assert(llvm::isUInt<32>(value) && "Valid addresses are 32-bit"); + DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); + // ObjectFileELF creates a WritableDataBuffer in CreateInstance. + WritableDataBuffer *data_buffer = + llvm::cast<WritableDataBuffer>(data_buffer_sp.get()); + uint8_t *dst = data_buffer->GetBytes() + rel_section->GetFileOffset() + + ELFRelocation::RelocOffset32(rel); + // Implicit addend is stored inline as a signed value. + int32_t addend; + memcpy(&addend, dst, sizeof(int32_t)); + // The sum must be positive. This extra check prevents UB from overflow in + // the actual range check below. + if (addend < 0 && static_cast<uint32_t>(-addend) > value) { + LLDB_LOGF(log, "Debug info relocation overflow: 0x%" PRIx64, + static_cast<int64_t>(value) + addend); + return; + } + if (!llvm::isUInt<32>(value + addend)) { + LLDB_LOGF(log, "Debug info relocation out of range: 0x%" PRIx64, value); + return; + } + uint32_t addr = value + addend; + memcpy(dst, &addr, sizeof(uint32_t)); + } +} + unsigned ObjectFileELF::ApplyRelocations( Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr, const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr, @@ -2666,38 +2717,64 @@ unsigned ObjectFileELF::ApplyRelocations( Symbol *symbol = nullptr; if (hdr->Is32Bit()) { - switch (reloc_type(rel)) { - case R_386_32: - symbol = symtab->FindSymbolByID(reloc_symbol(rel)); - if (symbol) { - addr_t f_offset = - rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel); - 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->GetBytes() + f_offset); - - addr_t value = symbol->GetAddressRef().GetFileAddress(); - if (rel.IsRela()) { - value += ELFRelocation::RelocAddend32(rel); + switch (hdr->e_machine) { + case llvm::ELF::EM_ARM: + switch (reloc_type(rel)) { + case R_ARM_ABS32: + ApplyELF32ABS32RelRelocation(symtab, rel, debug_data, rel_section); + break; + case R_ARM_REL32: + GetModule()->ReportError("unsupported AArch32 relocation:" + " .rel{0}[{1}], type {2}", + rel_section->GetName().AsCString(), i, + reloc_type(rel)); + break; + default: + assert(false && "unexpected relocation type"); + } + break; + case llvm::ELF::EM_386: + switch (reloc_type(rel)) { + case R_386_32: + symbol = symtab->FindSymbolByID(reloc_symbol(rel)); + if (symbol) { + addr_t f_offset = + rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel); + 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->GetBytes() + f_offset); + + addr_t value = symbol->GetAddressRef().GetFileAddress(); + if (rel.IsRela()) { + value += ELFRelocation::RelocAddend32(rel); + } else { + value += *dst; + } + *dst = value; } else { - value += *dst; + GetModule()->ReportError(".rel{0}[{1}] unknown symbol id: {2:d}", + rel_section->GetName().AsCString(), i, + reloc_symbol(rel)); } - *dst = value; - } else { - GetModule()->ReportError(".rel{0}[{1}] unknown symbol id: {2:d}", + break; + case R_386_NONE: + case R_386_PC32: + GetModule()->ReportError("unsupported i386 relocation:" + " .rel{0}[{1}], type {2}", rel_section->GetName().AsCString(), i, - reloc_symbol(rel)); + reloc_type(rel)); + break; + default: + assert(false && "unexpected relocation type"); + break; } break; - case R_386_PC32: default: - GetModule()->ReportError("unsupported 32-bit relocation:" - " .rel{0}[{1}], type {2}", - rel_section->GetName().AsCString(), i, - reloc_type(rel)); + GetModule()->ReportError("unsupported 32-bit ELF machine arch: {0}", hdr->e_machine); + break; } } else { switch (hdr->e_machine) { @@ -2743,7 +2820,8 @@ unsigned ObjectFileELF::ApplyRelocations( } break; default: - assert(false && "unsupported machine"); + GetModule()->ReportError("unsupported 64-bit ELF machine arch: {0}", hdr->e_machine); + break; } } } diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h deleted file mode 100644 index 91fdd205eb20..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ /dev/null @@ -1,107 +0,0 @@ -//===-- ObjectFileJIT.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_OBJECTFILE_JIT_OBJECTFILEJIT_H -#define LLDB_SOURCE_PLUGINS_OBJECTFILE_JIT_OBJECTFILEJIT_H - -#include "lldb/Core/Address.h" -#include "lldb/Symbol/ObjectFile.h" - -// This class needs to be hidden as eventually belongs in a plugin that -// will export the ObjectFile protocol -class ObjectFileJIT : public lldb_private::ObjectFile { -public: - ObjectFileJIT(const lldb::ModuleSP &module_sp, - const lldb::ObjectFileJITDelegateSP &delegate_sp); - - ~ObjectFileJIT() override; - - // Static Functions - static void Initialize(); - - static void Terminate(); - - static llvm::StringRef GetPluginNameStatic() { return "jit"; } - - static llvm::StringRef GetPluginDescriptionStatic() { - return "JIT code object file"; - } - - static lldb_private::ObjectFile * - 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::WritableDataBufferSP data_sp, - const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); - - static size_t 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); - - // LLVM RTTI support - static char ID; - bool isA(const void *ClassID) const override { - return ClassID == &ID || ObjectFile::isA(ClassID); - } - static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } - - // Member Functions - bool ParseHeader() override; - - bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, - bool value_is_offset) override; - - lldb::ByteOrder GetByteOrder() const override; - - bool IsExecutable() const override; - - uint32_t GetAddressByteSize() const override; - - void ParseSymtab(lldb_private::Symtab &symtab) override; - - bool IsStripped() override; - - void CreateSections(lldb_private::SectionList &unified_section_list) override; - - void Dump(lldb_private::Stream *s) override; - - lldb_private::ArchSpec GetArchitecture() override; - - lldb_private::UUID GetUUID() override; - - uint32_t GetDependentModules(lldb_private::FileSpecList &files) override; - - size_t ReadSectionData(lldb_private::Section *section, - lldb::offset_t section_offset, void *dst, - size_t dst_len) override; - - size_t - ReadSectionData(lldb_private::Section *section, - lldb_private::DataExtractor §ion_data) override; - - lldb_private::Address GetEntryPointAddress() override; - - lldb_private::Address GetBaseAddress() override; - - ObjectFile::Type CalculateType() override; - - ObjectFile::Strata CalculateStrata() override; - - // PluginInterface protocol - llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } - -protected: - lldb::ObjectFileJITDelegateWP m_delegate_wp; -}; - -#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_JIT_OBJECTFILEJIT_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp new file mode 100644 index 000000000000..ffbd87714242 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.cpp @@ -0,0 +1,219 @@ +//===-- ObjectFileJSON.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ObjectFile/JSON/ObjectFileJSON.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "llvm/ADT/DenseSet.h" +#include <optional> + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ObjectFileJSON) + +char ObjectFileJSON::ID; + +void ObjectFileJSON::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + CreateMemoryInstance, GetModuleSpecifications); +} + +void ObjectFileJSON::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ObjectFile * +ObjectFileJSON::CreateInstance(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); + if (!data_sp) + return nullptr; + data_offset = 0; + } + + if (!MagicBytesMatch(data_sp, 0, data_sp->GetByteSize())) + return nullptr; + + // 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); + if (!data_sp) + return nullptr; + data_offset = 0; + } + + Log *log = GetLog(LLDBLog::Symbols); + + auto text = + llvm::StringRef(reinterpret_cast<const char *>(data_sp->GetBytes())); + + Expected<json::Value> json = json::parse(text); + if (!json) { + LLDB_LOG_ERROR(log, json.takeError(), + "failed to parse JSON object file: {0}"); + return nullptr; + } + + json::Path::Root root; + Header header; + if (!fromJSON(*json, header, root)) { + LLDB_LOG_ERROR(log, root.getError(), + "failed to parse JSON object file header: {0}"); + return nullptr; + } + + ArchSpec arch(header.triple); + UUID uuid; + uuid.SetFromStringRef(header.uuid); + Type type = header.type.value_or(eTypeDebugInfo); + + Body body; + if (!fromJSON(*json, body, root)) { + LLDB_LOG_ERROR(log, root.getError(), + "failed to parse JSON object file body: {0}"); + return nullptr; + } + + return new ObjectFileJSON(module_sp, data_sp, data_offset, file, file_offset, + length, std::move(arch), std::move(uuid), type, + std::move(body.symbols), std::move(body.sections)); +} + +ObjectFile *ObjectFileJSON::CreateMemoryInstance(const ModuleSP &module_sp, + WritableDataBufferSP data_sp, + const ProcessSP &process_sp, + addr_t header_addr) { + return nullptr; +} + +size_t ObjectFileJSON::GetModuleSpecifications( + const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset, + offset_t file_offset, offset_t length, ModuleSpecList &specs) { + if (!MagicBytesMatch(data_sp, data_offset, data_sp->GetByteSize())) + return 0; + + // 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); + if (!data_sp) + return 0; + data_offset = 0; + } + + Log *log = GetLog(LLDBLog::Symbols); + + auto text = + llvm::StringRef(reinterpret_cast<const char *>(data_sp->GetBytes())); + + Expected<json::Value> json = json::parse(text); + if (!json) { + LLDB_LOG_ERROR(log, json.takeError(), + "failed to parse JSON object file: {0}"); + return 0; + } + + json::Path::Root root; + Header header; + if (!fromJSON(*json, header, root)) { + LLDB_LOG_ERROR(log, root.getError(), + "failed to parse JSON object file header: {0}"); + return 0; + } + + ArchSpec arch(header.triple); + UUID uuid; + uuid.SetFromStringRef(header.uuid); + + ModuleSpec spec(file, std::move(arch)); + spec.GetUUID() = std::move(uuid); + specs.Append(spec); + return 1; +} + +ObjectFileJSON::ObjectFileJSON(const ModuleSP &module_sp, DataBufferSP &data_sp, + offset_t data_offset, const FileSpec *file, + offset_t offset, offset_t length, ArchSpec arch, + UUID uuid, Type type, + std::vector<JSONSymbol> symbols, + std::vector<JSONSection> sections) + : ObjectFile(module_sp, file, offset, length, data_sp, data_offset), + m_arch(std::move(arch)), m_uuid(std::move(uuid)), m_type(type), + m_symbols(std::move(symbols)), m_sections(std::move(sections)) {} + +bool ObjectFileJSON::ParseHeader() { + // We already parsed the header during initialization. + return true; +} + +void ObjectFileJSON::ParseSymtab(Symtab &symtab) { + Log *log = GetLog(LLDBLog::Symbols); + SectionList *section_list = GetModule()->GetSectionList(); + for (JSONSymbol json_symbol : m_symbols) { + llvm::Expected<Symbol> symbol = Symbol::FromJSON(json_symbol, section_list); + if (!symbol) { + LLDB_LOG_ERROR(log, symbol.takeError(), "invalid symbol: {0}"); + continue; + } + symtab.AddSymbol(*symbol); + } + symtab.Finalize(); +} + +void ObjectFileJSON::CreateSections(SectionList &unified_section_list) { + if (m_sections_up) + return; + m_sections_up = std::make_unique<SectionList>(); + + lldb::user_id_t id = 1; + for (const auto §ion : m_sections) { + auto section_sp = std::make_shared<Section>( + GetModule(), this, id++, ConstString(section.name), + section.type.value_or(eSectionTypeCode), 0, section.size.value_or(0), 0, + section.size.value_or(0), /*log2align*/ 0, /*flags*/ 0); + m_sections_up->AddSection(section_sp); + unified_section_list.AddSection(section_sp); + } +} + +bool ObjectFileJSON::MagicBytesMatch(DataBufferSP data_sp, + lldb::addr_t data_offset, + lldb::addr_t data_length) { + DataExtractor data; + data.SetData(data_sp, data_offset, data_length); + lldb::offset_t offset = 0; + uint32_t magic = data.GetU8(&offset); + return magic == '{'; +} + +namespace lldb_private { + +bool fromJSON(const json::Value &value, ObjectFileJSON::Header &header, + json::Path path) { + json::ObjectMapper o(value, path); + return o && o.map("triple", header.triple) && o.map("uuid", header.uuid) && + o.map("type", header.type); +} + +bool fromJSON(const json::Value &value, ObjectFileJSON::Body &body, + json::Path path) { + json::ObjectMapper o(value, path); + return o && o.mapOptional("symbols", body.symbols) && + o.mapOptional("sections", body.sections); +} + +} // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.h new file mode 100644 index 000000000000..b72565f46886 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/JSON/ObjectFileJSON.h @@ -0,0 +1,125 @@ +//===-- ObjectFileJSON.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_OBJECTFILE_JSON_OBJECTFILEJSON_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_JSON_OBJECTFILEJSON_H + +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/ArchSpec.h" +#include "llvm/Support/JSON.h" + +namespace lldb_private { + +class ObjectFileJSON : public ObjectFile { +public: + static void Initialize(); + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "JSON"; } + + static const char *GetPluginDescriptionStatic() { + return "JSON object file reader."; + } + + static ObjectFile * + 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::WritableDataBufferSP data_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr); + + static size_t GetModuleSpecifications(const FileSpec &file, + lldb::DataBufferSP &data_sp, + lldb::offset_t data_offset, + lldb::offset_t file_offset, + lldb::offset_t length, + ModuleSpecList &specs); + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + // LLVM RTTI support + static char ID; + bool isA(const void *ClassID) const override { + return ClassID == &ID || ObjectFile::isA(ClassID); + } + static bool classof(const ObjectFile *obj) { return obj->isA(&ID); } + + bool ParseHeader() override; + + lldb::ByteOrder GetByteOrder() const override { + return m_arch.GetByteOrder(); + } + + bool IsExecutable() const override { return false; } + + uint32_t GetAddressByteSize() const override { + return m_arch.GetAddressByteSize(); + } + + AddressClass GetAddressClass(lldb::addr_t file_addr) override { + return AddressClass::eInvalid; + } + + void ParseSymtab(lldb_private::Symtab &symtab) override; + + bool IsStripped() override { return false; } + + void CreateSections(SectionList &unified_section_list) override; + + void Dump(Stream *s) override {} + + ArchSpec GetArchitecture() override { return m_arch; } + + UUID GetUUID() override { return m_uuid; } + + uint32_t GetDependentModules(FileSpecList &files) override { return 0; } + + Type CalculateType() override { return m_type; } + + Strata CalculateStrata() override { return eStrataUser; } + + static bool MagicBytesMatch(lldb::DataBufferSP data_sp, lldb::addr_t offset, + lldb::addr_t length); + + struct Header { + std::string triple; + std::string uuid; + std::optional<ObjectFile::Type> type; + }; + + struct Body { + std::vector<JSONSection> sections; + std::vector<JSONSymbol> symbols; + }; + +private: + ArchSpec m_arch; + UUID m_uuid; + ObjectFile::Type m_type; + std::optional<uint64_t> m_size; + std::vector<JSONSymbol> m_symbols; + std::vector<JSONSection> m_sections; + + ObjectFileJSON(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, ArchSpec arch, + UUID uuid, Type type, std::vector<JSONSymbol> symbols, + std::vector<JSONSection> sections); +}; + +bool fromJSON(const llvm::json::Value &value, ObjectFileJSON::Header &header, + llvm::json::Path path); + +bool fromJSON(const llvm::json::Value &value, ObjectFileJSON::Body &body, + llvm::json::Path path); + +} // namespace lldb_private +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_JSON_OBJECTFILEJSON_H 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 c62a67fa29f9..a3b91fc37dac 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/PDB/ObjectFilePDB.cpp @@ -27,10 +27,10 @@ using namespace llvm::codeview; LLDB_PLUGIN_DEFINE(ObjectFilePDB) -static UUID GetPDBUUID(InfoStream &IS) { +static UUID GetPDBUUID(InfoStream &IS, DbiStream &DS) { UUID::CvRecordPdb70 debug_info; memcpy(&debug_info.Uuid, IS.getGuid().Guid, sizeof(debug_info.Uuid)); - debug_info.Age = IS.getAge(); + debug_info.Age = DS.getAge(); return UUID(debug_info); } @@ -82,7 +82,12 @@ bool ObjectFilePDB::initPDBFile() { llvm::consumeError(info_stream.takeError()); return false; } - m_uuid = GetPDBUUID(*info_stream); + auto dbi_stream = m_file_up->getPDBDbiStream(); + if (!dbi_stream) { + llvm::consumeError(dbi_stream.takeError()); + return false; + } + m_uuid = GetPDBUUID(*info_stream, *dbi_stream); return true; } @@ -126,7 +131,7 @@ size_t ObjectFilePDB::GetModuleSpecifications( } lldb_private::UUID &uuid = module_spec.GetUUID(); - uuid = GetPDBUUID(*info_stream); + uuid = GetPDBUUID(*info_stream, *dbi_stream); ArchSpec &module_arch = module_spec.GetArchitecture(); switch (dbi_stream->getMachineType()) { diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.cpp b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.cpp new file mode 100644 index 000000000000..ec1f3f61892d --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.cpp @@ -0,0 +1,70 @@ +//===-- ObjectFilePlaceholder.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 "ObjectFilePlaceholder.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" + +#include <memory> + +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(ObjectFilePlaceholder) + +ObjectFilePlaceholder::ObjectFilePlaceholder( + const lldb::ModuleSP &module_sp, + const lldb_private::ModuleSpec &module_spec, lldb::addr_t base, + lldb::addr_t size) + : ObjectFile(module_sp, &module_spec.GetFileSpec(), /*file_offset*/ 0, + /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0), + m_arch(module_spec.GetArchitecture()), m_uuid(module_spec.GetUUID()), + m_base(base), m_size(size) { + m_symtab_up = std::make_unique<lldb_private::Symtab>(this); +} + +void ObjectFilePlaceholder::CreateSections( + lldb_private::SectionList &unified_section_list) { + m_sections_up = std::make_unique<lldb_private::SectionList>(); + auto section_sp = std::make_shared<lldb_private::Section>( + GetModule(), this, /*sect_id*/ 0, + lldb_private::ConstString(".module_image"), eSectionTypeOther, m_base, + m_size, /*file_offset*/ 0, /*file_size*/ 0, + /*log2align*/ 0, /*flags*/ 0); + section_sp->SetPermissions(ePermissionsReadable | ePermissionsExecutable); + m_sections_up->AddSection(section_sp); + unified_section_list.AddSection(std::move(section_sp)); +} + +lldb_private::Address ObjectFilePlaceholder::GetBaseAddress() { + return lldb_private::Address(m_sections_up->GetSectionAtIndex(0), 0); +} + +bool ObjectFilePlaceholder::SetLoadAddress(Target &target, addr_t value, + bool value_is_offset) { + assert(!value_is_offset); + assert(value == m_base); + + // Create sections if they haven't been created already. + GetModule()->GetSectionList(); + assert(m_sections_up->GetNumSections(0) == 1); + + target.GetSectionLoadList().SetSectionLoadAddress( + m_sections_up->GetSectionAtIndex(0), m_base); + return true; +} + +void ObjectFilePlaceholder::Dump(lldb_private::Stream *s) { + s->Format("Placeholder object file for {0} loaded at [{1:x}-{2:x})\n", + GetFileSpec(), m_base, m_base + m_size); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h new file mode 100644 index 000000000000..8798bcc5259e --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h @@ -0,0 +1,74 @@ +//===-- ObjectFilePlaceholder.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_OBJECTFILE_PLACEHOLDER_OBJECTFILEPLACEHOLDER_H +#define LLDB_SOURCE_PLUGINS_OBJECTFILE_PLACEHOLDER_OBJECTFILEPLACEHOLDER_H + +#include "lldb/Symbol/ObjectFile.h" + +#include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/UUID.h" +#include "lldb/lldb-private.h" + +/// A minimal ObjectFile implementation providing a dummy object file for the +/// cases when the real module binary is not available. This allows the module +/// to show up in "image list" and symbols to be added to it. +class ObjectFilePlaceholder : public lldb_private::ObjectFile { +public: + // Static Functions + static void Initialize() {} + + static void Terminate() {} + + static llvm::StringRef GetPluginNameStatic() { return "placeholder"; } + + ObjectFilePlaceholder(const lldb::ModuleSP &module_sp, + const lldb_private::ModuleSpec &module_spec, + lldb::addr_t base, lldb::addr_t size); + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + bool ParseHeader() override { return true; } + Type CalculateType() override { return eTypeUnknown; } + Strata CalculateStrata() override { return eStrataUnknown; } + uint32_t GetDependentModules(lldb_private::FileSpecList &file_list) override { + return 0; + } + bool IsExecutable() const override { return false; } + lldb_private::ArchSpec GetArchitecture() override { return m_arch; } + lldb_private::UUID GetUUID() override { return m_uuid; } + void ParseSymtab(lldb_private::Symtab &symtab) override {} + bool IsStripped() override { return true; } + lldb::ByteOrder GetByteOrder() const override { + return m_arch.GetByteOrder(); + } + + uint32_t GetAddressByteSize() const override { + return m_arch.GetAddressByteSize(); + } + + lldb_private::Address GetBaseAddress() override; + + void CreateSections(lldb_private::SectionList &unified_section_list) override; + + bool SetLoadAddress(lldb_private::Target &target, lldb::addr_t value, + bool value_is_offset) override; + + void Dump(lldb_private::Stream *s) override; + + lldb::addr_t GetBaseImageAddress() const { return m_base; } + +private: + lldb_private::ArchSpec m_arch; + lldb_private::UUID m_uuid; + lldb::addr_t m_base; + lldb::addr_t m_size; +}; + +#endif // LLDB_SOURCE_PLUGINS_OBJECTFILE_PLACEHOLDER_OBJECTFILEPLACEHOLDER_H 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 c22003f24f76..9560ae108f3e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -128,8 +128,9 @@ DynamicRegisterInfo *OperatingSystemPython::GetDynamicRegisterInfo() { if (!dictionary) return nullptr; - m_register_info_up = std::make_unique<DynamicRegisterInfo>( + m_register_info_up = DynamicRegisterInfo::Create( *dictionary, m_process->GetTarget().GetArchitecture()); + assert(m_register_info_up); assert(m_register_info_up->GetNumRegisters() > 0); assert(m_register_info_up->GetNumRegisterSets() > 0); } 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 0c6831b77d87..7abc71a1c53f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -28,8 +28,8 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Support/Host.h" +#include "llvm/TargetParser/Host.h" +#include "llvm/TargetParser/Triple.h" // Define these constants from FreeBSD mman.h for use when targeting remote // FreeBSD systems even when host has different values. @@ -244,7 +244,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_fault", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_trapno", int_type}, }), @@ -252,7 +252,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_timer", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_timerid", int_type}, {"_overrun", int_type}, @@ -261,7 +261,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_mesgq", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_mqd", int_type}, }), @@ -269,7 +269,7 @@ CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_poll", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_band", long_type}, }), 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 59bbc3f638af..393519d708d3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp @@ -277,7 +277,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_rt", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_pid", pid_type}, {"_uid", uid_type}, @@ -287,7 +287,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_child", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_pid", pid_type}, {"_uid", uid_type}, @@ -299,7 +299,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_fault", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_addr", voidp_type}, {"_trap", int_type}, @@ -310,7 +310,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_poll", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_band", long_type}, {"_fd", int_type}, @@ -319,7 +319,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType(union_type, "_syscall", ast->CreateStructForIdentifier( - ConstString(), + llvm::StringRef(), { {"_sysnum", int_type}, {"_retval", int_type.GetArrayType(2)}, @@ -330,7 +330,7 @@ CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) { ast->AddFieldToRecordType( union_type, "_ptrace_state", - ast->CreateStructForIdentifier(ConstString(), + ast->CreateStructForIdentifier(llvm::StringRef(), { {"_pe_report_event", int_type}, {"_option", ptrace_option_type}, 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 222dbfa71964..1e91f2ccd198 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -401,6 +401,7 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info, attach_info.SetHijackListener(listener_sp); } process_sp->HijackProcessEvents(listener_sp); + process_sp->SetShadowListener(attach_info.GetShadowListener()); error = process_sp->Attach(attach_info); } } @@ -458,6 +459,7 @@ lldb::ProcessSP PlatformPOSIX::DebugProcess(ProcessLaunchInfo &launch_info, LLDB_LOG(log, "successfully created process"); process_sp->HijackProcessEvents(launch_info.GetHijackListener()); + process_sp->SetShadowListener(launch_info.GetShadowListener()); // Log file actions. if (log) { 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 4ba20117cdb5..72a039d18872 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Platform/QemuUser/PlatformQemuUser.cpp @@ -41,33 +41,28 @@ public: } llvm::StringRef GetArchitecture() { - return m_collection_sp->GetPropertyAtIndexAsString( - nullptr, ePropertyArchitecture, ""); + return GetPropertyAtIndexAs<llvm::StringRef>(ePropertyArchitecture, ""); } FileSpec GetEmulatorPath() { - return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, - ePropertyEmulatorPath); + return GetPropertyAtIndexAs<FileSpec>(ePropertyEmulatorPath, {}); } Args GetEmulatorArgs() { Args result; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEmulatorArgs, - result); + m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEmulatorArgs, result); return result; } Environment GetEmulatorEnvVars() { Args args; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEmulatorEnvVars, - args); + m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEmulatorEnvVars, args); return Environment(args); } Environment GetTargetEnvVars() { Args args; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyTargetEnvVars, - args); + m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyTargetEnvVars, args); return Environment(args); } }; @@ -98,7 +93,7 @@ void PlatformQemuUser::DebuggerInitialize(Debugger &debugger) { debugger, ConstString(GetPluginNameStatic()))) { PluginManager::CreateSettingForPlatformPlugin( debugger, GetGlobalProperties().GetValueProperties(), - ConstString("Properties for the qemu-user platform plugin."), + "Properties for the qemu-user platform plugin.", /*is_global_property=*/true); } } @@ -196,8 +191,8 @@ lldb::ProcessSP PlatformQemuUser::DebugProcess(ProcessLaunchInfo &launch_info, launch_info.SetArguments(args, true); Environment emulator_env = Host::GetEnvironment(); - if (ConstString sysroot = GetSDKRootDirectory()) - emulator_env["QEMU_LD_PREFIX"] = sysroot.GetStringRef().str(); + if (const std::string &sysroot = GetSDKRootDirectory(); !sysroot.empty()) + emulator_env["QEMU_LD_PREFIX"] = sysroot; for (const auto &KV : GetGlobalProperties().GetEmulatorEnvVars()) emulator_env[KV.first()] = KV.second; launch_info.GetEnvironment() = ComputeLaunchEnvironment( 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 0858a2a8d3c8..053d79b8c3b5 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 @@ -423,6 +423,7 @@ PlatformRemoteGDBServer::DebugProcess(ProcessLaunchInfo &launch_info, if (process_sp) { process_sp->HijackProcessEvents(launch_info.GetHijackListener()); + process_sp->SetShadowListener(launch_info.GetShadowListener()); error = process_sp->ConnectRemote(connect_url.c_str()); // Retry the connect remote one time... @@ -515,6 +516,7 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach( ListenerSP listener_sp = attach_info.GetHijackListener(); if (listener_sp) process_sp->HijackProcessEvents(listener_sp); + process_sp->SetShadowListener(attach_info.GetShadowListener()); error = process_sp->Attach(attach_info); } @@ -699,8 +701,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() { response.GetResponseType() != response.eResponse) return m_remote_signals_sp; - auto object_sp = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + auto object_sp = StructuredData::ParseJSON(response.GetStringRef()); if (!object_sp || !object_sp->IsValid()) return m_remote_signals_sp; @@ -720,7 +721,7 @@ const UnixSignalsSP &PlatformRemoteGDBServer::GetRemoteUnixSignals() { return false; // Signal number and signal name are required. - int signo; + uint64_t signo; if (!dict->GetValueForKeyAsInteger("signo", signo)) return false; 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 dbaa83fd15d7..84a009be50bf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.cpp @@ -51,9 +51,8 @@ static Status EnsureFDFlags(int fd, int flags) { // Public Static Methods llvm::Expected<std::unique_ptr<NativeProcessProtocol>> -NativeProcessFreeBSD::Factory::Launch(ProcessLaunchInfo &launch_info, - NativeDelegate &native_delegate, - MainLoop &mainloop) const { +NativeProcessFreeBSD::Manager::Launch(ProcessLaunchInfo &launch_info, + NativeDelegate &native_delegate) { Log *log = GetLog(POSIXLog::Process); Status status; @@ -91,7 +90,7 @@ NativeProcessFreeBSD::Factory::Launch(ProcessLaunchInfo &launch_info, std::unique_ptr<NativeProcessFreeBSD> process_up(new NativeProcessFreeBSD( pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate, - Info.GetArchitecture(), mainloop)); + Info.GetArchitecture(), m_mainloop)); status = process_up->SetupTrace(); if (status.Fail()) @@ -105,9 +104,8 @@ NativeProcessFreeBSD::Factory::Launch(ProcessLaunchInfo &launch_info, } llvm::Expected<std::unique_ptr<NativeProcessProtocol>> -NativeProcessFreeBSD::Factory::Attach( - lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, - MainLoop &mainloop) const { +NativeProcessFreeBSD::Manager::Attach( + lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) { Log *log = GetLog(POSIXLog::Process); LLDB_LOG(log, "pid = {0:x}", pid); @@ -119,7 +117,7 @@ NativeProcessFreeBSD::Factory::Attach( } std::unique_ptr<NativeProcessFreeBSD> process_up(new NativeProcessFreeBSD( - pid, -1, native_delegate, Info.GetArchitecture(), mainloop)); + pid, -1, native_delegate, Info.GetArchitecture(), m_mainloop)); Status status = process_up->Attach(); if (!status.Success()) @@ -129,7 +127,7 @@ NativeProcessFreeBSD::Factory::Attach( } NativeProcessFreeBSD::Extension -NativeProcessFreeBSD::Factory::GetSupportedExtensions() const { +NativeProcessFreeBSD::Manager::GetSupportedExtensions() const { return #if defined(PT_COREDUMP) Extension::savecore | diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h index 44b8a53699bb..b638367ebbaa 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeProcessFreeBSD.h @@ -30,15 +30,16 @@ namespace process_freebsd { class NativeProcessFreeBSD : public NativeProcessELF, private NativeProcessSoftwareSingleStep { public: - class Factory : public NativeProcessProtocol::Factory { + class Manager : public NativeProcessProtocol::Manager { public: + using NativeProcessProtocol::Manager::Manager; + llvm::Expected<std::unique_ptr<NativeProcessProtocol>> - Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, - MainLoop &mainloop) const override; + Launch(ProcessLaunchInfo &launch_info, + NativeDelegate &native_delegate) override; llvm::Expected<std::unique_ptr<NativeProcessProtocol>> - Attach(lldb::pid_t pid, NativeDelegate &native_delegate, - MainLoop &mainloop) const override; + Attach(lldb::pid_t pid, NativeDelegate &native_delegate) override; Extension GetSupportedExtensions() const 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 8e6399bcf9c7..449ec27e0da8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/FreeBSD/NativeThreadFreeBSD.cpp @@ -90,8 +90,7 @@ void NativeThreadFreeBSD::SetStoppedBySignal(uint32_t signo, case SIGBUS: case SIGFPE: case SIGILL: - const auto reason = GetCrashReason(*info); - m_stop_description = GetCrashReasonString(reason, *info); + m_stop_description = GetCrashReasonString(*info); break; } } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 182eefb7bee7..26c562bd4790 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -56,9 +56,8 @@ static Status EnsureFDFlags(int fd, int flags) { // Public Static Methods llvm::Expected<std::unique_ptr<NativeProcessProtocol>> -NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info, - NativeDelegate &native_delegate, - MainLoop &mainloop) const { +NativeProcessNetBSD::Manager::Launch(ProcessLaunchInfo &launch_info, + NativeDelegate &native_delegate) { Log *log = GetLog(POSIXLog::Process); Status status; @@ -96,7 +95,7 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info, std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD( pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate, - Info.GetArchitecture(), mainloop)); + Info.GetArchitecture(), m_mainloop)); status = process_up->SetupTrace(); if (status.Fail()) @@ -110,9 +109,8 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info, } llvm::Expected<std::unique_ptr<NativeProcessProtocol>> -NativeProcessNetBSD::Factory::Attach( - lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate, - MainLoop &mainloop) const { +NativeProcessNetBSD::Manager::Attach( + lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate) { Log *log = GetLog(POSIXLog::Process); LLDB_LOG(log, "pid = {0:x}", pid); @@ -124,7 +122,7 @@ NativeProcessNetBSD::Factory::Attach( } std::unique_ptr<NativeProcessNetBSD> process_up(new NativeProcessNetBSD( - pid, -1, native_delegate, Info.GetArchitecture(), mainloop)); + pid, -1, native_delegate, Info.GetArchitecture(), m_mainloop)); Status status = process_up->Attach(); if (!status.Success()) @@ -134,7 +132,7 @@ NativeProcessNetBSD::Factory::Attach( } NativeProcessNetBSD::Extension -NativeProcessNetBSD::Factory::GetSupportedExtensions() const { +NativeProcessNetBSD::Manager::GetSupportedExtensions() const { return Extension::multiprocess | Extension::fork | Extension::vfork | Extension::pass_signals | Extension::auxv | Extension::libraries_svr4 | Extension::savecore; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h index 3f54d02a9075..86724fdd5b7e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -27,15 +27,16 @@ namespace process_netbsd { /// Changes in the inferior process state are broadcasted. class NativeProcessNetBSD : public NativeProcessELF { public: - class Factory : public NativeProcessProtocol::Factory { + class Manager : public NativeProcessProtocol::Manager { public: + using NativeProcessProtocol::Manager::Manager; + llvm::Expected<std::unique_ptr<NativeProcessProtocol>> - Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate, - MainLoop &mainloop) const override; + Launch(ProcessLaunchInfo &launch_info, + NativeDelegate &native_delegate) override; llvm::Expected<std::unique_ptr<NativeProcessProtocol>> - Attach(lldb::pid_t pid, NativeDelegate &native_delegate, - MainLoop &mainloop) const override; + Attach(lldb::pid_t pid, NativeDelegate &native_delegate) override; Extension GetSupportedExtensions() const override; }; 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 b8de5f084883..13607bd261d4 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 @@ -409,7 +409,7 @@ NativeRegisterContextNetBSD_x86_64::ReadRegister(const RegisterInfo *reg_info, return error; } - RegSetKind set = opt_set.getValue(); + RegSetKind set = *opt_set; error = ReadRegisterSet(set); if (error.Fail()) return error; @@ -476,7 +476,7 @@ Status NativeRegisterContextNetBSD_x86_64::WriteRegister( return error; } - RegSetKind set = opt_set.getValue(); + RegSetKind set = *opt_set; uint64_t new_xstate_bv = 0; error = ReadRegisterSet(set); 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 995fe3fa78e8..f561c21b9d91 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -90,8 +90,7 @@ void NativeThreadNetBSD::SetStoppedBySignal(uint32_t signo, case SIGBUS: case SIGFPE: case SIGILL: - const auto reason = GetCrashReason(*info); - m_stop_description = GetCrashReasonString(reason, *info); + m_stop_description = GetCrashReasonString(*info); break; } } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp index c6ede61cfe1b..d93b7cd0ce56 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.cpp @@ -8,348 +8,24 @@ #include "CrashReason.h" -#include "llvm/Support/raw_ostream.h" +#include "lldb/Target/UnixSignals.h" -#include <sstream> - -namespace { - -void AppendFaultAddr(std::string &str, lldb::addr_t addr) { - std::stringstream ss; - ss << " (fault address: 0x" << std::hex << addr << ")"; - str += ss.str(); -} - -#if defined(si_lower) && defined(si_upper) -void AppendBounds(std::string &str, lldb::addr_t lower_bound, - lldb::addr_t upper_bound, lldb::addr_t addr) { - llvm::raw_string_ostream stream(str); - if ((unsigned long)addr < lower_bound) - stream << ": lower bound violation "; - else - stream << ": upper bound violation "; - stream << "(fault address: 0x"; - stream.write_hex(addr); - stream << ", lower bound: 0x"; - stream.write_hex(lower_bound); - stream << ", upper bound: 0x"; - stream.write_hex(upper_bound); - stream << ")"; - stream.flush(); -} -#endif - -CrashReason GetCrashReasonForSIGSEGV(const siginfo_t &info) { - assert(info.si_signo == SIGSEGV); - - switch (info.si_code) { -#ifdef SI_KERNEL - case SI_KERNEL: - // Some platforms will occasionally send nonstandard spurious SI_KERNEL - // codes. One way to get this is via unaligned SIMD loads. - return CrashReason::eInvalidAddress; // for lack of anything better -#endif - case SEGV_MAPERR: - return CrashReason::eInvalidAddress; - case SEGV_ACCERR: - return CrashReason::ePrivilegedAddress; -#ifndef SEGV_BNDERR -#define SEGV_BNDERR 3 -#endif - case SEGV_BNDERR: - return CrashReason::eBoundViolation; -#ifdef __linux__ -#ifndef SEGV_MTEAERR -#define SEGV_MTEAERR 8 -#endif - case SEGV_MTEAERR: - return CrashReason::eAsyncTagCheckFault; -#ifndef SEGV_MTESERR -#define SEGV_MTESERR 9 -#endif - case SEGV_MTESERR: - return CrashReason::eSyncTagCheckFault; -#endif // __linux__ - } - - return CrashReason::eInvalidCrashReason; -} - -CrashReason GetCrashReasonForSIGILL(const siginfo_t &info) { - assert(info.si_signo == SIGILL); - - switch (info.si_code) { - case ILL_ILLOPC: - return CrashReason::eIllegalOpcode; - case ILL_ILLOPN: - return CrashReason::eIllegalOperand; - case ILL_ILLADR: - return CrashReason::eIllegalAddressingMode; - case ILL_ILLTRP: - return CrashReason::eIllegalTrap; - case ILL_PRVOPC: - return CrashReason::ePrivilegedOpcode; - case ILL_PRVREG: - return CrashReason::ePrivilegedRegister; - case ILL_COPROC: - return CrashReason::eCoprocessorError; - case ILL_BADSTK: - return CrashReason::eInternalStackError; - } - - return CrashReason::eInvalidCrashReason; -} - -CrashReason GetCrashReasonForSIGFPE(const siginfo_t &info) { - assert(info.si_signo == SIGFPE); - - switch (info.si_code) { - case FPE_INTDIV: - return CrashReason::eIntegerDivideByZero; - case FPE_INTOVF: - return CrashReason::eIntegerOverflow; - case FPE_FLTDIV: - return CrashReason::eFloatDivideByZero; - case FPE_FLTOVF: - return CrashReason::eFloatOverflow; - case FPE_FLTUND: - return CrashReason::eFloatUnderflow; - case FPE_FLTRES: - return CrashReason::eFloatInexactResult; - case FPE_FLTINV: - return CrashReason::eFloatInvalidOperation; - case FPE_FLTSUB: - return CrashReason::eFloatSubscriptRange; - } - - return CrashReason::eInvalidCrashReason; -} - -CrashReason GetCrashReasonForSIGBUS(const siginfo_t &info) { - assert(info.si_signo == SIGBUS); - - switch (info.si_code) { - case BUS_ADRALN: - return CrashReason::eIllegalAlignment; - case BUS_ADRERR: - return CrashReason::eIllegalAddress; - case BUS_OBJERR: - return CrashReason::eHardwareError; - } - - return CrashReason::eInvalidCrashReason; -} -} - -std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info) { - std::string str; - -// make sure that siginfo_t has the bound fields available. +std::string GetCrashReasonString(const siginfo_t &info) { #if defined(si_lower) && defined(si_upper) - if (reason == CrashReason::eBoundViolation) { - str = "signal SIGSEGV"; - AppendBounds(str, reinterpret_cast<uintptr_t>(info.si_lower), - reinterpret_cast<uintptr_t>(info.si_upper), - reinterpret_cast<uintptr_t>(info.si_addr)); - return str; - } + std::optional<lldb::addr_t> lower = + reinterpret_cast<lldb::addr_t>(info.si_lower); + std::optional<lldb::addr_t> upper = + reinterpret_cast<lldb::addr_t>(info.si_upper); +#else + std::optional<lldb::addr_t> lower; + std::optional<lldb::addr_t> upper; #endif - return GetCrashReasonString(reason, - reinterpret_cast<uintptr_t>(info.si_addr)); -} - -std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr) { - std::string str; - - switch (reason) { - default: - str = "unknown crash reason"; - break; - - case CrashReason::eInvalidAddress: - str = "signal SIGSEGV: invalid address"; - AppendFaultAddr(str, fault_addr); - break; - case CrashReason::ePrivilegedAddress: - str = "signal SIGSEGV: address access protected"; - AppendFaultAddr(str, fault_addr); - break; - case CrashReason::eBoundViolation: - str = "signal SIGSEGV: bound violation"; - break; - case CrashReason::eAsyncTagCheckFault: - str = "signal SIGSEGV: async tag check fault"; - break; - case CrashReason::eSyncTagCheckFault: - str = "signal SIGSEGV: sync tag check fault"; - AppendFaultAddr(str, fault_addr); - break; - case CrashReason::eIllegalOpcode: - str = "signal SIGILL: illegal instruction"; - break; - case CrashReason::eIllegalOperand: - str = "signal SIGILL: illegal instruction operand"; - break; - case CrashReason::eIllegalAddressingMode: - str = "signal SIGILL: illegal addressing mode"; - break; - case CrashReason::eIllegalTrap: - str = "signal SIGILL: illegal trap"; - break; - case CrashReason::ePrivilegedOpcode: - str = "signal SIGILL: privileged instruction"; - break; - case CrashReason::ePrivilegedRegister: - str = "signal SIGILL: privileged register"; - break; - case CrashReason::eCoprocessorError: - str = "signal SIGILL: coprocessor error"; - break; - case CrashReason::eInternalStackError: - str = "signal SIGILL: internal stack error"; - break; - case CrashReason::eIllegalAlignment: - str = "signal SIGBUS: illegal alignment"; - break; - case CrashReason::eIllegalAddress: - str = "signal SIGBUS: illegal address"; - break; - case CrashReason::eHardwareError: - str = "signal SIGBUS: hardware error"; - break; - case CrashReason::eIntegerDivideByZero: - str = "signal SIGFPE: integer divide by zero"; - break; - case CrashReason::eIntegerOverflow: - str = "signal SIGFPE: integer overflow"; - break; - case CrashReason::eFloatDivideByZero: - str = "signal SIGFPE: floating point divide by zero"; - break; - case CrashReason::eFloatOverflow: - str = "signal SIGFPE: floating point overflow"; - break; - case CrashReason::eFloatUnderflow: - str = "signal SIGFPE: floating point underflow"; - break; - case CrashReason::eFloatInexactResult: - str = "signal SIGFPE: inexact floating point result"; - break; - case CrashReason::eFloatInvalidOperation: - str = "signal SIGFPE: invalid floating point operation"; - break; - case CrashReason::eFloatSubscriptRange: - str = "signal SIGFPE: invalid floating point subscript range"; - break; - } - - return str; -} - -const char *CrashReasonAsString(CrashReason reason) { - const char *str = nullptr; - - switch (reason) { - case CrashReason::eInvalidCrashReason: - str = "eInvalidCrashReason"; - break; - - // SIGSEGV crash reasons. - case CrashReason::eInvalidAddress: - str = "eInvalidAddress"; - break; - case CrashReason::ePrivilegedAddress: - str = "ePrivilegedAddress"; - break; - case CrashReason::eBoundViolation: - str = "eBoundViolation"; - break; - case CrashReason::eAsyncTagCheckFault: - str = "eAsyncTagCheckFault"; - break; - case CrashReason::eSyncTagCheckFault: - str = "eSyncTagCheckFault"; - break; - - // SIGILL crash reasons. - case CrashReason::eIllegalOpcode: - str = "eIllegalOpcode"; - break; - case CrashReason::eIllegalOperand: - str = "eIllegalOperand"; - break; - case CrashReason::eIllegalAddressingMode: - str = "eIllegalAddressingMode"; - break; - case CrashReason::eIllegalTrap: - str = "eIllegalTrap"; - break; - case CrashReason::ePrivilegedOpcode: - str = "ePrivilegedOpcode"; - break; - case CrashReason::ePrivilegedRegister: - str = "ePrivilegedRegister"; - break; - case CrashReason::eCoprocessorError: - str = "eCoprocessorError"; - break; - case CrashReason::eInternalStackError: - str = "eInternalStackError"; - break; - - // SIGBUS crash reasons: - case CrashReason::eIllegalAlignment: - str = "eIllegalAlignment"; - break; - case CrashReason::eIllegalAddress: - str = "eIllegalAddress"; - break; - case CrashReason::eHardwareError: - str = "eHardwareError"; - break; - - // SIGFPE crash reasons: - case CrashReason::eIntegerDivideByZero: - str = "eIntegerDivideByZero"; - break; - case CrashReason::eIntegerOverflow: - str = "eIntegerOverflow"; - break; - case CrashReason::eFloatDivideByZero: - str = "eFloatDivideByZero"; - break; - case CrashReason::eFloatOverflow: - str = "eFloatOverflow"; - break; - case CrashReason::eFloatUnderflow: - str = "eFloatUnderflow"; - break; - case CrashReason::eFloatInexactResult: - str = "eFloatInexactResult"; - break; - case CrashReason::eFloatInvalidOperation: - str = "eFloatInvalidOperation"; - break; - case CrashReason::eFloatSubscriptRange: - str = "eFloatSubscriptRange"; - break; - } - return str; -} - -CrashReason GetCrashReason(const siginfo_t &info) { - switch (info.si_signo) { - case SIGSEGV: - return GetCrashReasonForSIGSEGV(info); - case SIGBUS: - return GetCrashReasonForSIGBUS(info); - case SIGFPE: - return GetCrashReasonForSIGFPE(info); - case SIGILL: - return GetCrashReasonForSIGILL(info); - } + std::string description = + lldb_private::UnixSignals::CreateForHost()->GetSignalDescription( + info.si_signo, info.si_code, + reinterpret_cast<uintptr_t>(info.si_addr), lower, upper); + assert(description.size() && "unexpected signal"); - assert(false && "unexpected signal"); - return CrashReason::eInvalidCrashReason; + return "signal " + description; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h index 24acdc08e900..2177726b76f0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/CrashReason.h @@ -15,47 +15,6 @@ #include <string> -enum class CrashReason { - eInvalidCrashReason, - - // SIGSEGV crash reasons. - eInvalidAddress, - ePrivilegedAddress, - eBoundViolation, - eAsyncTagCheckFault, - eSyncTagCheckFault, - - // SIGILL crash reasons. - eIllegalOpcode, - eIllegalOperand, - eIllegalAddressingMode, - eIllegalTrap, - ePrivilegedOpcode, - ePrivilegedRegister, - eCoprocessorError, - eInternalStackError, - - // SIGBUS crash reasons, - eIllegalAlignment, - eIllegalAddress, - eHardwareError, - - // SIGFPE crash reasons, - eIntegerDivideByZero, - eIntegerOverflow, - eFloatDivideByZero, - eFloatOverflow, - eFloatUnderflow, - eFloatInexactResult, - eFloatInvalidOperation, - eFloatSubscriptRange -}; - -std::string GetCrashReasonString(CrashReason reason, lldb::addr_t fault_addr); -std::string GetCrashReasonString(CrashReason reason, const siginfo_t &info); - -const char *CrashReasonAsString(CrashReason reason); - -CrashReason GetCrashReason(const siginfo_t &info); +std::string GetCrashReasonString(const siginfo_t &info); #endif // #ifndef liblldb_CrashReason_H_ diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp deleted file mode 100644 index 4e8c6f1ba2d2..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessMessage.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//===-- ProcessMessage.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 "ProcessMessage.h" - -using namespace lldb_private; - -const char *ProcessMessage::PrintCrashReason() const { - return CrashReasonAsString(m_crash_reason); -} - -const char *ProcessMessage::PrintKind(Kind kind) { - const char *str = nullptr; - - switch (kind) { - case eInvalidMessage: - str = "eInvalidMessage"; - break; - case eAttachMessage: - str = "eAttachMessage"; - break; - case eExitMessage: - str = "eExitMessage"; - break; - case eLimboMessage: - str = "eLimboMessage"; - break; - case eSignalMessage: - str = "eSignalMessage"; - break; - case eSignalDeliveredMessage: - str = "eSignalDeliveredMessage"; - break; - case eTraceMessage: - str = "eTraceMessage"; - break; - case eBreakpointMessage: - str = "eBreakpointMessage"; - break; - case eWatchpointMessage: - str = "eWatchpointMessage"; - break; - case eCrashMessage: - str = "eCrashMessage"; - break; - case eNewThreadMessage: - str = "eNewThreadMessage"; - break; - case eExecMessage: - str = "eExecMessage"; - break; - } - return str; -} - -const char *ProcessMessage::PrintKind() const { return PrintKind(m_kind); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessMessage.h b/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessMessage.h deleted file mode 100644 index d9c10caaa95e..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/POSIX/ProcessMessage.h +++ /dev/null @@ -1,168 +0,0 @@ -//===-- ProcessMessage.h ----------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ProcessMessage_H_ -#define liblldb_ProcessMessage_H_ - -#include "CrashReason.h" - -#include <cassert> -#include <string> - -#include "lldb/lldb-defines.h" -#include "lldb/lldb-types.h" - -class ProcessMessage { -public: - /// The type of signal this message can correspond to. - enum Kind { - eInvalidMessage, - eAttachMessage, - eExitMessage, - eLimboMessage, - eSignalMessage, - eSignalDeliveredMessage, - eTraceMessage, - eBreakpointMessage, - eWatchpointMessage, - eCrashMessage, - eNewThreadMessage, - eExecMessage - }; - - ProcessMessage() - : m_tid(LLDB_INVALID_PROCESS_ID), m_kind(eInvalidMessage), - m_crash_reason(CrashReason::eInvalidCrashReason), m_status(0), - m_addr(0) {} - - Kind GetKind() const { return m_kind; } - - lldb::tid_t GetTID() const { return m_tid; } - - /// Indicates that the process \p pid has successfully attached. - static ProcessMessage Attach(lldb::pid_t pid) { - return ProcessMessage(pid, eAttachMessage); - } - - /// Indicates that the thread \p tid is about to exit with status \p status. - static ProcessMessage Limbo(lldb::tid_t tid, int status) { - return ProcessMessage(tid, eLimboMessage, status); - } - - /// Indicates that the thread \p tid had the signal \p signum delivered. - static ProcessMessage Signal(lldb::tid_t tid, int signum) { - return ProcessMessage(tid, eSignalMessage, signum); - } - - /// Indicates that a signal \p signum generated by the debugging process was - /// delivered to the thread \p tid. - static ProcessMessage SignalDelivered(lldb::tid_t tid, int signum) { - return ProcessMessage(tid, eSignalDeliveredMessage, signum); - } - - /// Indicates that the thread \p tid encountered a trace point. - static ProcessMessage Trace(lldb::tid_t tid) { - return ProcessMessage(tid, eTraceMessage); - } - - /// Indicates that the thread \p tid encountered a break point. - static ProcessMessage Break(lldb::tid_t tid) { - return ProcessMessage(tid, eBreakpointMessage); - } - - static ProcessMessage Watch(lldb::tid_t tid, lldb::addr_t wp_addr) { - return ProcessMessage(tid, eWatchpointMessage, 0, wp_addr); - } - - /// Indicates that the thread \p tid crashed. - static ProcessMessage Crash(lldb::pid_t pid, CrashReason reason, int signo, - lldb::addr_t fault_addr) { - ProcessMessage message(pid, eCrashMessage, signo, fault_addr); - message.m_crash_reason = reason; - return message; - } - - /// Indicates that the thread \p child_tid was spawned. - static ProcessMessage NewThread(lldb::tid_t parent_tid, - lldb::tid_t child_tid) { - return ProcessMessage(parent_tid, eNewThreadMessage, child_tid); - } - - /// Indicates that the thread \p tid is about to exit with status \p status. - static ProcessMessage Exit(lldb::tid_t tid, int status) { - return ProcessMessage(tid, eExitMessage, status); - } - - /// Indicates that the thread \p pid has exec'd. - static ProcessMessage Exec(lldb::tid_t tid) { - return ProcessMessage(tid, eExecMessage); - } - - int GetExitStatus() const { - assert(GetKind() == eExitMessage || GetKind() == eLimboMessage); - return m_status; - } - - int GetSignal() const { - assert(GetKind() == eSignalMessage || GetKind() == eCrashMessage || - GetKind() == eSignalDeliveredMessage); - return m_status; - } - - int GetStopStatus() const { - assert(GetKind() == eSignalMessage); - return m_status; - } - - CrashReason GetCrashReason() const { - assert(GetKind() == eCrashMessage); - return m_crash_reason; - } - - lldb::addr_t GetFaultAddress() const { - assert(GetKind() == eCrashMessage); - return m_addr; - } - - lldb::addr_t GetHWAddress() const { - assert(GetKind() == eWatchpointMessage || GetKind() == eTraceMessage); - return m_addr; - } - - lldb::tid_t GetChildTID() const { - assert(GetKind() == eNewThreadMessage); - return m_child_tid; - } - - const char *PrintCrashReason() const; - - const char *PrintKind() const; - - static const char *PrintKind(Kind); - -private: - ProcessMessage(lldb::tid_t tid, Kind kind, int status = 0, - lldb::addr_t addr = 0) - : m_tid(tid), m_kind(kind), - m_crash_reason(CrashReason::eInvalidCrashReason), m_status(status), - m_addr(addr), m_child_tid(0) {} - - ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid) - : m_tid(tid), m_kind(kind), - m_crash_reason(CrashReason::eInvalidCrashReason), m_status(0), - m_addr(0), m_child_tid(child_tid) {} - - lldb::tid_t m_tid; - Kind m_kind : 8; - CrashReason m_crash_reason; - int m_status; - lldb::addr_t m_addr; - lldb::tid_t m_child_tid; -}; - -#endif // #ifndef liblldb_ProcessMessage_H_ diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMUtils.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMUtils.h index a7aaa5ac7a1f..9256f926275b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMUtils.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/ARMUtils.h @@ -11,6 +11,7 @@ #include "ARMDefines.h" #include "InstructionUtils.h" +#include "llvm/ADT/bit.h" #include "llvm/Support/MathExtras.h" // Common utilities for the ARM/Thumb Instruction Set Architecture. @@ -173,8 +174,7 @@ static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, return 0; } *success = true; - uint32_t amt = amount % 32; - uint32_t result = Rotr32(value, amt); + uint32_t result = llvm::rotr<uint32_t>(value, amount); carry_out = Bit32(value, 31); return result; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp index 0a4bdc72b364..ebf197339446 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -8,6 +8,24 @@ #include "FreeBSDSignals.h" +#ifdef __FreeBSD__ +#include <csignal> + +#ifndef FPE_FLTIDO +#define FPE_FLTIDO 9 +#endif + +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + static_assert(signal_name == signal_value, \ + "Value mismatch for signal number " #signal_name); \ + static_assert(code_name == code_value, \ + "Value mismatch for signal code " #code_name); \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#endif /* ifdef __FreeBSD */ + using namespace lldb_private; FreeBSDSignals::FreeBSDSignals() : UnixSignals() { Reset(); } @@ -15,72 +33,107 @@ FreeBSDSignals::FreeBSDSignals() : UnixSignals() { Reset(); } void FreeBSDSignals::Reset() { UnixSignals::Reset(); - // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION - // ====== ============ ======== ====== ====== - // =================================================== - AddSignal(32, "SIGTHR", false, false, false, "thread interrupt"); - AddSignal(33, "SIGLIBRT", false, false, false, - "reserved by real-time library"); - AddSignal(65, "SIGRTMIN", false, false, false, "real time signal 0"); - AddSignal(66, "SIGRTMIN+1", false, false, false, "real time signal 1"); - AddSignal(67, "SIGRTMIN+2", false, false, false, "real time signal 2"); - AddSignal(68, "SIGRTMIN+3", false, false, false, "real time signal 3"); - AddSignal(69, "SIGRTMIN+4", false, false, false, "real time signal 4"); - AddSignal(70, "SIGRTMIN+5", false, false, false, "real time signal 5"); - AddSignal(71, "SIGRTMIN+6", false, false, false, "real time signal 6"); - AddSignal(72, "SIGRTMIN+7", false, false, false, "real time signal 7"); - AddSignal(73, "SIGRTMIN+8", false, false, false, "real time signal 8"); - AddSignal(74, "SIGRTMIN+9", false, false, false, "real time signal 9"); - AddSignal(75, "SIGRTMIN+10", false, false, false, "real time signal 10"); - AddSignal(76, "SIGRTMIN+11", false, false, false, "real time signal 11"); - AddSignal(77, "SIGRTMIN+12", false, false, false, "real time signal 12"); - AddSignal(78, "SIGRTMIN+13", false, false, false, "real time signal 13"); - AddSignal(79, "SIGRTMIN+14", false, false, false, "real time signal 14"); - AddSignal(80, "SIGRTMIN+15", false, false, false, "real time signal 15"); - AddSignal(81, "SIGRTMIN+16", false, false, false, "real time signal 16"); - AddSignal(82, "SIGRTMIN+17", false, false, false, "real time signal 17"); - AddSignal(83, "SIGRTMIN+18", false, false, false, "real time signal 18"); - AddSignal(84, "SIGRTMIN+19", false, false, false, "real time signal 19"); - AddSignal(85, "SIGRTMIN+20", false, false, false, "real time signal 20"); - AddSignal(86, "SIGRTMIN+21", false, false, false, "real time signal 21"); - AddSignal(87, "SIGRTMIN+22", false, false, false, "real time signal 22"); - AddSignal(88, "SIGRTMIN+23", false, false, false, "real time signal 23"); - AddSignal(89, "SIGRTMIN+24", false, false, false, "real time signal 24"); - AddSignal(90, "SIGRTMIN+25", false, false, false, "real time signal 25"); - AddSignal(91, "SIGRTMIN+26", false, false, false, "real time signal 26"); - AddSignal(92, "SIGRTMIN+27", false, false, false, "real time signal 27"); - AddSignal(93, "SIGRTMIN+28", false, false, false, "real time signal 28"); - AddSignal(94, "SIGRTMIN+29", false, false, false, "real time signal 29"); - AddSignal(95, "SIGRTMIN+30", false, false, false, "real time signal 30"); - AddSignal(96, "SIGRTMAX-30", false, false, false, "real time signal 31"); - AddSignal(97, "SIGRTMAX-29", false, false, false, "real time signal 32"); - AddSignal(98, "SIGRTMAX-28", false, false, false, "real time signal 33"); - AddSignal(99, "SIGRTMAX-27", false, false, false, "real time signal 34"); - AddSignal(100, "SIGRTMAX-26", false, false, false, "real time signal 35"); - AddSignal(101, "SIGRTMAX-25", false, false, false, "real time signal 36"); - AddSignal(102, "SIGRTMAX-24", false, false, false, "real time signal 37"); - AddSignal(103, "SIGRTMAX-23", false, false, false, "real time signal 38"); - AddSignal(104, "SIGRTMAX-22", false, false, false, "real time signal 39"); - AddSignal(105, "SIGRTMAX-21", false, false, false, "real time signal 40"); - AddSignal(106, "SIGRTMAX-20", false, false, false, "real time signal 41"); - AddSignal(107, "SIGRTMAX-19", false, false, false, "real time signal 42"); - AddSignal(108, "SIGRTMAX-18", false, false, false, "real time signal 43"); - AddSignal(109, "SIGRTMAX-17", false, false, false, "real time signal 44"); - AddSignal(110, "SIGRTMAX-16", false, false, false, "real time signal 45"); - AddSignal(111, "SIGRTMAX-15", false, false, false, "real time signal 46"); - AddSignal(112, "SIGRTMAX-14", false, false, false, "real time signal 47"); - AddSignal(113, "SIGRTMAX-13", false, false, false, "real time signal 48"); - AddSignal(114, "SIGRTMAX-12", false, false, false, "real time signal 49"); - AddSignal(115, "SIGRTMAX-11", false, false, false, "real time signal 50"); - AddSignal(116, "SIGRTMAX-10", false, false, false, "real time signal 51"); - AddSignal(117, "SIGRTMAX-9", false, false, false, "real time signal 52"); - AddSignal(118, "SIGRTMAX-8", false, false, false, "real time signal 53"); - AddSignal(119, "SIGRTMAX-7", false, false, false, "real time signal 54"); - AddSignal(120, "SIGRTMAX-6", false, false, false, "real time signal 55"); - AddSignal(121, "SIGRTMAX-5", false, false, false, "real time signal 56"); - AddSignal(122, "SIGRTMAX-4", false, false, false, "real time signal 57"); - AddSignal(123, "SIGRTMAX-3", false, false, false, "real time signal 58"); - AddSignal(124, "SIGRTMAX-2", false, false, false, "real time signal 59"); - AddSignal(125, "SIGRTMAX-1", false, false, false, "real time signal 60"); - AddSignal(126, "SIGRTMAX", false, false, false, "real time signal 61"); + // clang-format off + // SIGILL + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(SIGILL, 4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(SIGILL, 4, ILL_BADSTK, 8, "internal stack error"); + + // SIGFPE + ADD_SIGCODE(SIGFPE, 8, FPE_INTOVF, 1, "integer overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_INTDIV, 2, "integer divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTINV, 7, "invalid floating point operation"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTSUB, 8, "subscript out of range"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTIDO, 9, "input denormal operation"); + + // SIGBUS + ADD_SIGCODE(SIGBUS, 10, BUS_ADRALN, 1, "invalid address alignment"); + ADD_SIGCODE(SIGBUS, 10, BUS_ADRERR, 2, "nonexistent physical address"); + ADD_SIGCODE(SIGBUS, 10, BUS_OBJERR, 3, "object-specific hardware error"); + ADD_SIGCODE(SIGBUS, 10, BUS_OOMERR, 100, "no memory"); + + // SIGSEGV + ADD_SIGCODE(SIGSEGV, 11, SEGV_MAPERR, 1, "address not mapped to object", + SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_ACCERR, 2, "invalid permissions for mapped object", + SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_PKUERR, 100, "PKU violation", + SignalCodePrintOption::Address); + + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION + // ===== ============== ======== ====== ====== ======================== + AddSignal(32, "SIGTHR", false, false, false, "thread interrupt"); + AddSignal(33, "SIGLIBRT", false, false, false, "reserved by real-time library"); + AddSignal(65, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(66, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(67, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(68, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(69, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(70, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(71, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(72, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(73, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(74, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(75, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(76, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(77, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(78, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(79, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(80, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(81, "SIGRTMIN+16", false, false, false, "real time signal 16"); + AddSignal(82, "SIGRTMIN+17", false, false, false, "real time signal 17"); + AddSignal(83, "SIGRTMIN+18", false, false, false, "real time signal 18"); + AddSignal(84, "SIGRTMIN+19", false, false, false, "real time signal 19"); + AddSignal(85, "SIGRTMIN+20", false, false, false, "real time signal 20"); + AddSignal(86, "SIGRTMIN+21", false, false, false, "real time signal 21"); + AddSignal(87, "SIGRTMIN+22", false, false, false, "real time signal 22"); + AddSignal(88, "SIGRTMIN+23", false, false, false, "real time signal 23"); + AddSignal(89, "SIGRTMIN+24", false, false, false, "real time signal 24"); + AddSignal(90, "SIGRTMIN+25", false, false, false, "real time signal 25"); + AddSignal(91, "SIGRTMIN+26", false, false, false, "real time signal 26"); + AddSignal(92, "SIGRTMIN+27", false, false, false, "real time signal 27"); + AddSignal(93, "SIGRTMIN+28", false, false, false, "real time signal 28"); + AddSignal(94, "SIGRTMIN+29", false, false, false, "real time signal 29"); + AddSignal(95, "SIGRTMIN+30", false, false, false, "real time signal 30"); + AddSignal(96, "SIGRTMAX-30", false, false, false, "real time signal 31"); + AddSignal(97, "SIGRTMAX-29", false, false, false, "real time signal 32"); + AddSignal(98, "SIGRTMAX-28", false, false, false, "real time signal 33"); + AddSignal(99, "SIGRTMAX-27", false, false, false, "real time signal 34"); + AddSignal(100, "SIGRTMAX-26", false, false, false, "real time signal 35"); + AddSignal(101, "SIGRTMAX-25", false, false, false, "real time signal 36"); + AddSignal(102, "SIGRTMAX-24", false, false, false, "real time signal 37"); + AddSignal(103, "SIGRTMAX-23", false, false, false, "real time signal 38"); + AddSignal(104, "SIGRTMAX-22", false, false, false, "real time signal 39"); + AddSignal(105, "SIGRTMAX-21", false, false, false, "real time signal 40"); + AddSignal(106, "SIGRTMAX-20", false, false, false, "real time signal 41"); + AddSignal(107, "SIGRTMAX-19", false, false, false, "real time signal 42"); + AddSignal(108, "SIGRTMAX-18", false, false, false, "real time signal 43"); + AddSignal(109, "SIGRTMAX-17", false, false, false, "real time signal 44"); + AddSignal(110, "SIGRTMAX-16", false, false, false, "real time signal 45"); + AddSignal(111, "SIGRTMAX-15", false, false, false, "real time signal 46"); + AddSignal(112, "SIGRTMAX-14", false, false, false, "real time signal 47"); + AddSignal(113, "SIGRTMAX-13", false, false, false, "real time signal 48"); + AddSignal(114, "SIGRTMAX-12", false, false, false, "real time signal 49"); + AddSignal(115, "SIGRTMAX-11", false, false, false, "real time signal 50"); + AddSignal(116, "SIGRTMAX-10", false, false, false, "real time signal 51"); + AddSignal(117, "SIGRTMAX-9", false, false, false, "real time signal 52"); + AddSignal(118, "SIGRTMAX-8", false, false, false, "real time signal 53"); + AddSignal(119, "SIGRTMAX-7", false, false, false, "real time signal 54"); + AddSignal(120, "SIGRTMAX-6", false, false, false, "real time signal 55"); + AddSignal(121, "SIGRTMAX-5", false, false, false, "real time signal 56"); + AddSignal(122, "SIGRTMAX-4", false, false, false, "real time signal 57"); + AddSignal(123, "SIGRTMAX-3", false, false, false, "real time signal 58"); + AddSignal(124, "SIGRTMAX-2", false, false, false, "real time signal 59"); + AddSignal(125, "SIGRTMAX-1", false, false, false, "real time signal 60"); + AddSignal(126, "SIGRTMAX", false, false, false, "real time signal 61"); + // clang-format on } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp index d4b0f4039da9..3f25dbc6abbb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -8,6 +8,30 @@ #include "LinuxSignals.h" +#ifdef __linux__ +#include <csignal> + +#ifndef SEGV_BNDERR +#define SEGV_BNDERR 3 +#endif +#ifndef SEGV_MTEAERR +#define SEGV_MTEAERR 8 +#endif +#ifndef SEGV_MTESERR +#define SEGV_MTESERR 9 +#endif + +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + static_assert(signal_name == signal_value, \ + "Value mismatch for signal number " #signal_name); \ + static_assert(code_name == code_value, \ + "Value mismatch for signal code " #code_name); \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#endif /* ifdef __linux__ */ + using namespace lldb_private; LinuxSignals::LinuxSignals() : UnixSignals() { Reset(); } @@ -20,14 +44,48 @@ void LinuxSignals::Reset() { AddSignal(1, "SIGHUP", false, true, true, "hangup"); AddSignal(2, "SIGINT", true, true, true, "interrupt"); AddSignal(3, "SIGQUIT", false, true, true, "quit"); + AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(SIGILL, 4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(SIGILL, 4, ILL_BADSTK, 8, "internal stack error"); + AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); + AddSignal(7, "SIGBUS", false, true, true, "bus error"); + ADD_SIGCODE(SIGBUS, 7, BUS_ADRALN, 1, "illegal alignment"); + ADD_SIGCODE(SIGBUS, 7, BUS_ADRERR, 2, "illegal address"); + ADD_SIGCODE(SIGBUS, 7, BUS_OBJERR, 3, "hardware error"); + AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); + ADD_SIGCODE(SIGFPE, 8, FPE_INTDIV, 1, "integer divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_INTOVF, 2, "integer overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTINV, 7, "floating point invalid operation"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTSUB, 8, "subscript out of range"); + AddSignal(9, "SIGKILL", false, true, true, "kill"); AddSignal(10, "SIGUSR1", false, true, true, "user defined signal 1"); + AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); + ADD_SIGCODE(SIGSEGV, 11, SEGV_MAPERR, 1, "address not mapped to object", SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_ACCERR, 2, "invalid permissions for mapped object", SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_BNDERR, 3, "failed address bounds checks", SignalCodePrintOption::Bounds); + ADD_SIGCODE(SIGSEGV, 11, SEGV_MTEAERR, 8, "async tag check fault"); + ADD_SIGCODE(SIGSEGV, 11, SEGV_MTESERR, 9, "sync tag check fault", SignalCodePrintOption::Address); + // Some platforms will occasionally send nonstandard spurious SI_KERNEL + // codes. One way to get this is via unaligned SIMD loads. Treat it as invalid address. + ADD_SIGCODE(SIGSEGV, 11, SI_KERNEL, 0x80, "invalid address", SignalCodePrintOption::Address); + AddSignal(12, "SIGUSR2", false, true, true, "user defined signal 2"); AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed"); AddSignal(14, "SIGALRM", false, false, false, "alarm"); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp deleted file mode 100644 index fb51c56953f8..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ /dev/null @@ -1,85 +0,0 @@ -//===-- MipsLinuxSignals.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 "MipsLinuxSignals.h" - -using namespace lldb_private; - -MipsLinuxSignals::MipsLinuxSignals() : UnixSignals() { Reset(); } - -void MipsLinuxSignals::Reset() { - m_signals.clear(); - // clang-format off - // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION - // ====== ============== ======== ====== ====== =================================================== - AddSignal(1, "SIGHUP", false, true, true, "hangup"); - AddSignal(2, "SIGINT", true, true, true, "interrupt"); - AddSignal(3, "SIGQUIT", false, true, true, "quit"); - AddSignal(4, "SIGILL", false, true, true, "illegal instruction"); - AddSignal(5, "SIGTRAP", true, true, true, "trace trap (not reset when caught)"); - AddSignal(6, "SIGABRT", false, true, true, "abort()/IOT trap", "SIGIOT"); - AddSignal(7, "SIGEMT", false, true, true, "terminate process with core dump"); - AddSignal(8, "SIGFPE", false, true, true, "floating point exception"); - AddSignal(9, "SIGKILL", false, true, true, "kill"); - AddSignal(10, "SIGBUS", false, true, true, "bus error"); - AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); - AddSignal(12, "SIGSYS", false, true, true, "invalid system call"); - AddSignal(13, "SIGPIPE", false, true, true, "write to pipe with reading end closed"); - AddSignal(14, "SIGALRM", false, false, false, "alarm"); - AddSignal(15, "SIGTERM", false, true, true, "termination requested"); - AddSignal(16, "SIGUSR1", false, true, true, "user defined signal 1"); - AddSignal(17, "SIGUSR2", false, true, true, "user defined signal 2"); - AddSignal(18, "SIGCHLD", false, false, true, "child status has changed", "SIGCLD"); - AddSignal(19, "SIGPWR", false, true, true, "power failure"); - AddSignal(20, "SIGWINCH", false, true, true, "window size changes"); - AddSignal(21, "SIGURG", false, true, true, "urgent data on socket"); - AddSignal(22, "SIGIO", false, true, true, "input/output ready/Pollable event", "SIGPOLL"); - AddSignal(23, "SIGSTOP", true, true, true, "process stop"); - AddSignal(24, "SIGTSTP", false, true, true, "tty stop"); - AddSignal(25, "SIGCONT", false, false, true, "process continue"); - AddSignal(26, "SIGTTIN", false, true, true, "background tty read"); - AddSignal(27, "SIGTTOU", false, true, true, "background tty write"); - AddSignal(28, "SIGVTALRM", false, true, true, "virtual time alarm"); - AddSignal(29, "SIGPROF", false, false, false, "profiling time alarm"); - AddSignal(30, "SIGXCPU", false, true, true, "CPU resource exceeded"); - AddSignal(31, "SIGXFSZ", false, true, true, "file size limit exceeded"); - AddSignal(32, "SIG32", false, false, false, "threading library internal signal 1"); - AddSignal(33, "SIG33", false, false, false, "threading library internal signal 2"); - AddSignal(34, "SIGRTMIN", false, false, false, "real time signal 0"); - AddSignal(35, "SIGRTMIN+1", false, false, false, "real time signal 1"); - AddSignal(36, "SIGRTMIN+2", false, false, false, "real time signal 2"); - AddSignal(37, "SIGRTMIN+3", false, false, false, "real time signal 3"); - AddSignal(38, "SIGRTMIN+4", false, false, false, "real time signal 4"); - AddSignal(39, "SIGRTMIN+5", false, false, false, "real time signal 5"); - AddSignal(40, "SIGRTMIN+6", false, false, false, "real time signal 6"); - AddSignal(41, "SIGRTMIN+7", false, false, false, "real time signal 7"); - AddSignal(42, "SIGRTMIN+8", false, false, false, "real time signal 8"); - AddSignal(43, "SIGRTMIN+9", false, false, false, "real time signal 9"); - AddSignal(44, "SIGRTMIN+10", false, false, false, "real time signal 10"); - AddSignal(45, "SIGRTMIN+11", false, false, false, "real time signal 11"); - AddSignal(46, "SIGRTMIN+12", false, false, false, "real time signal 12"); - AddSignal(47, "SIGRTMIN+13", false, false, false, "real time signal 13"); - AddSignal(48, "SIGRTMIN+14", false, false, false, "real time signal 14"); - AddSignal(49, "SIGRTMIN+15", false, false, false, "real time signal 15"); - AddSignal(50, "SIGRTMAX-14", false, false, false, "real time signal 16"); // switching to SIGRTMAX-xxx to match "kill -l" output - AddSignal(51, "SIGRTMAX-13", false, false, false, "real time signal 17"); - AddSignal(52, "SIGRTMAX-12", false, false, false, "real time signal 18"); - AddSignal(53, "SIGRTMAX-11", false, false, false, "real time signal 19"); - AddSignal(54, "SIGRTMAX-10", false, false, false, "real time signal 20"); - AddSignal(55, "SIGRTMAX-9", false, false, false, "real time signal 21"); - AddSignal(56, "SIGRTMAX-8", false, false, false, "real time signal 22"); - AddSignal(57, "SIGRTMAX-7", false, false, false, "real time signal 23"); - AddSignal(58, "SIGRTMAX-6", false, false, false, "real time signal 24"); - AddSignal(59, "SIGRTMAX-5", false, false, false, "real time signal 25"); - AddSignal(60, "SIGRTMAX-4", false, false, false, "real time signal 26"); - AddSignal(61, "SIGRTMAX-3", false, false, false, "real time signal 27"); - AddSignal(62, "SIGRTMAX-2", false, false, false, "real time signal 28"); - AddSignal(63, "SIGRTMAX-1", false, false, false, "real time signal 29"); - AddSignal(64, "SIGRTMAX", false, false, false, "real time signal 30"); - // clang-format on -} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h deleted file mode 100644 index 6b78fc72a91c..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ /dev/null @@ -1,28 +0,0 @@ -//===-- MipsLinuxSignals.h ------------------------------------------*- C++ -//-*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H -#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H - -#include "lldb/Target/UnixSignals.h" - -namespace lldb_private { - -/// Linux specific set of Unix signals. -class MipsLinuxSignals : public UnixSignals { -public: - MipsLinuxSignals(); - -private: - void Reset() override; -}; - -} // namespace lldb_private - -#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_MIPSLINUXSIGNALS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h index 3da0b0407ce6..f8246ff4d718 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_arm64.h @@ -55,7 +55,14 @@ public: enum DREGType { eDREGTypeWATCH = 0, eDREGTypeBREAK }; protected: - // Debug register info for hardware breakpoints and watchpoints management. + /// Debug register info for hardware breakpoints and watchpoints management. + /// Watchpoints: For a user requested size 4 at addr 0x1004, where BAS + /// watchpoints are at doubleword (8-byte) alignment. + /// \a real_addr is 0x1004 + /// \a address is 0x1000 + /// size is 8 + /// If a one-byte write to 0x1006 is the most recent watchpoint trap, + /// \a hit_addr is 0x1006 struct DREG { lldb::addr_t address; // Breakpoint/watchpoint address value. lldb::addr_t hit_addr; // Address at which last watchpoint trigger exception diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h index a4ed8bfb97ea..4ca288d9dff7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NativeRegisterContextDBReg_x86.h @@ -46,7 +46,7 @@ public: uint32_t NumSupportedHardwareWatchpoints() override; - const RegisterInfo *GetDR(int num) const; + virtual const RegisterInfo *GetDR(int num) const; }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp index ffdfd19b4efe..6e4e5038566b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp @@ -8,46 +8,92 @@ #include "NetBSDSignals.h" +#ifdef __NetBSD__ +#include <csignal> + +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + static_assert(signal_name == signal_value, \ + "Value mismatch for signal number " #signal_name); \ + static_assert(code_name == code_value, \ + "Value mismatch for signal code " #code_name); \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#else +#define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \ + AddSignalCode(signal_value, code_value, __VA_ARGS__) +#endif /* ifdef __NetBSD */ + using namespace lldb_private; NetBSDSignals::NetBSDSignals() : UnixSignals() { Reset(); } void NetBSDSignals::Reset() { UnixSignals::Reset(); + + // clang-format off + // SIGILL + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPC, 1, "illegal opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLOPN, 2, "illegal operand"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLADR, 3, "illegal addressing mode"); + ADD_SIGCODE(SIGILL, 4, ILL_ILLTRP, 4, "illegal trap"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVOPC, 5, "privileged opcode"); + ADD_SIGCODE(SIGILL, 4, ILL_PRVREG, 6, "privileged register"); + ADD_SIGCODE(SIGILL, 4, ILL_COPROC, 7, "coprocessor error"); + ADD_SIGCODE(SIGILL, 4, ILL_BADSTK, 8, "internal stack error"); + + // SIGFPE + ADD_SIGCODE(SIGFPE, 8, FPE_INTDIV, 1, "integer divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_INTOVF, 2, "integer overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTDIV, 3, "floating point divide by zero"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTOVF, 4, "floating point overflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTUND, 5, "floating point underflow"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTRES, 6, "floating point inexact result"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTINV, 7, "invalid floating point operation"); + ADD_SIGCODE(SIGFPE, 8, FPE_FLTSUB, 8, "subscript out of range"); + + // SIGBUS + ADD_SIGCODE(SIGBUS, 10, BUS_ADRALN, 1, "invalid address alignment"); + ADD_SIGCODE(SIGBUS, 10, BUS_ADRERR, 2, "non-existent physical address"); + ADD_SIGCODE(SIGBUS, 10, BUS_OBJERR, 3, "object specific hardware error"); + + // SIGSEGV + ADD_SIGCODE(SIGSEGV, 11, SEGV_MAPERR, 1, "address not mapped to object", + SignalCodePrintOption::Address); + ADD_SIGCODE(SIGSEGV, 11, SEGV_ACCERR, 2, "invalid permissions for mapped object", + SignalCodePrintOption::Address); + // SIGNO NAME SUPPRESS STOP NOTIFY DESCRIPTION - // ====== ============ ======== ====== ====== - // =================================================== - AddSignal(32, "SIGPWR", false, true, true, - "power fail/restart (not reset when caught)"); - AddSignal(33, "SIGRTMIN", false, false, false, "real time signal 0"); - AddSignal(34, "SIGRTMIN+1", false, false, false, "real time signal 1"); - AddSignal(35, "SIGRTMIN+2", false, false, false, "real time signal 2"); - AddSignal(36, "SIGRTMIN+3", false, false, false, "real time signal 3"); - AddSignal(37, "SIGRTMIN+4", false, false, false, "real time signal 4"); - AddSignal(38, "SIGRTMIN+5", false, false, false, "real time signal 5"); - AddSignal(39, "SIGRTMIN+6", false, false, false, "real time signal 6"); - AddSignal(40, "SIGRTMIN+7", false, false, false, "real time signal 7"); - AddSignal(41, "SIGRTMIN+8", false, false, false, "real time signal 8"); - AddSignal(42, "SIGRTMIN+9", false, false, false, "real time signal 9"); - AddSignal(43, "SIGRTMIN+10", false, false, false, "real time signal 10"); - AddSignal(44, "SIGRTMIN+11", false, false, false, "real time signal 11"); - AddSignal(45, "SIGRTMIN+12", false, false, false, "real time signal 12"); - AddSignal(46, "SIGRTMIN+13", false, false, false, "real time signal 13"); - AddSignal(47, "SIGRTMIN+14", false, false, false, "real time signal 14"); - AddSignal(48, "SIGRTMIN+15", false, false, false, "real time signal 15"); - AddSignal(49, "SIGRTMIN-14", false, false, false, "real time signal 16"); - AddSignal(50, "SIGRTMAX-13", false, false, false, "real time signal 17"); - AddSignal(51, "SIGRTMAX-12", false, false, false, "real time signal 18"); - AddSignal(52, "SIGRTMAX-11", false, false, false, "real time signal 19"); - AddSignal(53, "SIGRTMAX-10", false, false, false, "real time signal 20"); - AddSignal(54, "SIGRTMAX-9", false, false, false, "real time signal 21"); - AddSignal(55, "SIGRTMAX-8", false, false, false, "real time signal 22"); - AddSignal(56, "SIGRTMAX-7", false, false, false, "real time signal 23"); - AddSignal(57, "SIGRTMAX-6", false, false, false, "real time signal 24"); - AddSignal(58, "SIGRTMAX-5", false, false, false, "real time signal 25"); - AddSignal(59, "SIGRTMAX-4", false, false, false, "real time signal 26"); - AddSignal(60, "SIGRTMAX-3", false, false, false, "real time signal 27"); - AddSignal(61, "SIGRTMAX-2", false, false, false, "real time signal 28"); - AddSignal(62, "SIGRTMAX-1", false, false, false, "real time signal 29"); - AddSignal(63, "SIGRTMAX", false, false, false, "real time signal 30"); + // ===== ============== ======== ====== ====== ======================== + AddSignal(32, "SIGPWR", false, true, true, "power fail/restart (not reset when caught)"); + AddSignal(33, "SIGRTMIN", false, false, false, "real time signal 0"); + AddSignal(34, "SIGRTMIN+1", false, false, false, "real time signal 1"); + AddSignal(35, "SIGRTMIN+2", false, false, false, "real time signal 2"); + AddSignal(36, "SIGRTMIN+3", false, false, false, "real time signal 3"); + AddSignal(37, "SIGRTMIN+4", false, false, false, "real time signal 4"); + AddSignal(38, "SIGRTMIN+5", false, false, false, "real time signal 5"); + AddSignal(39, "SIGRTMIN+6", false, false, false, "real time signal 6"); + AddSignal(40, "SIGRTMIN+7", false, false, false, "real time signal 7"); + AddSignal(41, "SIGRTMIN+8", false, false, false, "real time signal 8"); + AddSignal(42, "SIGRTMIN+9", false, false, false, "real time signal 9"); + AddSignal(43, "SIGRTMIN+10", false, false, false, "real time signal 10"); + AddSignal(44, "SIGRTMIN+11", false, false, false, "real time signal 11"); + AddSignal(45, "SIGRTMIN+12", false, false, false, "real time signal 12"); + AddSignal(46, "SIGRTMIN+13", false, false, false, "real time signal 13"); + AddSignal(47, "SIGRTMIN+14", false, false, false, "real time signal 14"); + AddSignal(48, "SIGRTMIN+15", false, false, false, "real time signal 15"); + AddSignal(49, "SIGRTMIN-14", false, false, false, "real time signal 16"); + AddSignal(50, "SIGRTMAX-13", false, false, false, "real time signal 17"); + AddSignal(51, "SIGRTMAX-12", false, false, false, "real time signal 18"); + AddSignal(52, "SIGRTMAX-11", false, false, false, "real time signal 19"); + AddSignal(53, "SIGRTMAX-10", false, false, false, "real time signal 20"); + AddSignal(54, "SIGRTMAX-9", false, false, false, "real time signal 21"); + AddSignal(55, "SIGRTMAX-8", false, false, false, "real time signal 22"); + AddSignal(56, "SIGRTMAX-7", false, false, false, "real time signal 23"); + AddSignal(57, "SIGRTMAX-6", false, false, false, "real time signal 24"); + AddSignal(58, "SIGRTMAX-5", false, false, false, "real time signal 25"); + AddSignal(59, "SIGRTMAX-4", false, false, false, "real time signal 26"); + AddSignal(60, "SIGRTMAX-3", false, false, false, "real time signal 27"); + AddSignal(61, "SIGRTMAX-2", false, false, false, "real time signal 28"); + AddSignal(62, "SIGRTMAX-1", false, false, false, "real time signal 29"); + AddSignal(63, "SIGRTMAX", false, false, false, "real time signal 30"); + // clang-format on } 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 b29d44176c94..c23e82a741a0 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 @@ -177,7 +177,7 @@ enum { {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM }, \ - nullptr, nullptr, + nullptr, nullptr, nullptr, #define REG_CONTEXT_SIZE \ (sizeof(RegisterContextDarwin_arm::GPR) + \ sizeof(RegisterContextDarwin_arm::FPU) + \ @@ -200,6 +200,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0}, nullptr, nullptr, + nullptr, }, {"r1", nullptr, @@ -210,6 +211,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1}, nullptr, nullptr, + nullptr, }, {"r2", nullptr, @@ -220,6 +222,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2}, nullptr, nullptr, + nullptr, }, {"r3", nullptr, @@ -230,6 +233,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3}, nullptr, nullptr, + nullptr, }, {"r4", nullptr, @@ -240,6 +244,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4}, nullptr, nullptr, + nullptr, }, {"r5", nullptr, @@ -250,6 +255,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5}, nullptr, nullptr, + nullptr, }, {"r6", nullptr, @@ -260,6 +266,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6}, nullptr, nullptr, + nullptr, }, {"r7", nullptr, @@ -271,6 +278,7 @@ static RegisterInfo g_register_infos[] = { gpr_r7}, nullptr, nullptr, + nullptr, }, {"r8", nullptr, @@ -281,6 +289,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8}, nullptr, nullptr, + nullptr, }, {"r9", nullptr, @@ -291,6 +300,7 @@ static RegisterInfo g_register_infos[] = { {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9}, nullptr, nullptr, + nullptr, }, {"r10", nullptr, @@ -302,6 +312,7 @@ static RegisterInfo g_register_infos[] = { gpr_r10}, nullptr, nullptr, + nullptr, }, {"r11", nullptr, @@ -313,6 +324,7 @@ static RegisterInfo g_register_infos[] = { gpr_r11}, nullptr, nullptr, + nullptr, }, {"r12", nullptr, @@ -324,6 +336,7 @@ static RegisterInfo g_register_infos[] = { gpr_r12}, nullptr, nullptr, + nullptr, }, {"sp", "r13", @@ -335,6 +348,7 @@ static RegisterInfo g_register_infos[] = { gpr_sp}, nullptr, nullptr, + nullptr, }, {"lr", "r14", @@ -346,6 +360,7 @@ static RegisterInfo g_register_infos[] = { gpr_lr}, nullptr, nullptr, + nullptr, }, {"pc", "r15", @@ -357,6 +372,7 @@ static RegisterInfo g_register_infos[] = { gpr_pc}, nullptr, nullptr, + nullptr, }, {"cpsr", "psr", @@ -368,6 +384,7 @@ static RegisterInfo g_register_infos[] = { gpr_cpsr}, nullptr, nullptr, + nullptr, }, {"s0", @@ -380,6 +397,7 @@ static RegisterInfo g_register_infos[] = { fpu_s0}, nullptr, nullptr, + nullptr, }, {"s1", nullptr, @@ -391,6 +409,7 @@ static RegisterInfo g_register_infos[] = { fpu_s1}, nullptr, nullptr, + nullptr, }, {"s2", nullptr, @@ -402,6 +421,7 @@ static RegisterInfo g_register_infos[] = { fpu_s2}, nullptr, nullptr, + nullptr, }, {"s3", nullptr, @@ -413,6 +433,7 @@ static RegisterInfo g_register_infos[] = { fpu_s3}, nullptr, nullptr, + nullptr, }, {"s4", nullptr, @@ -424,6 +445,7 @@ static RegisterInfo g_register_infos[] = { fpu_s4}, nullptr, nullptr, + nullptr, }, {"s5", nullptr, @@ -435,6 +457,7 @@ static RegisterInfo g_register_infos[] = { fpu_s5}, nullptr, nullptr, + nullptr, }, {"s6", nullptr, @@ -446,6 +469,7 @@ static RegisterInfo g_register_infos[] = { fpu_s6}, nullptr, nullptr, + nullptr, }, {"s7", nullptr, @@ -457,6 +481,7 @@ static RegisterInfo g_register_infos[] = { fpu_s7}, nullptr, nullptr, + nullptr, }, {"s8", nullptr, @@ -468,6 +493,7 @@ static RegisterInfo g_register_infos[] = { fpu_s8}, nullptr, nullptr, + nullptr, }, {"s9", nullptr, @@ -479,6 +505,7 @@ static RegisterInfo g_register_infos[] = { fpu_s9}, nullptr, nullptr, + nullptr, }, {"s10", nullptr, @@ -490,6 +517,7 @@ static RegisterInfo g_register_infos[] = { fpu_s10}, nullptr, nullptr, + nullptr, }, {"s11", nullptr, @@ -501,6 +529,7 @@ static RegisterInfo g_register_infos[] = { fpu_s11}, nullptr, nullptr, + nullptr, }, {"s12", nullptr, @@ -512,6 +541,7 @@ static RegisterInfo g_register_infos[] = { fpu_s12}, nullptr, nullptr, + nullptr, }, {"s13", nullptr, @@ -523,6 +553,7 @@ static RegisterInfo g_register_infos[] = { fpu_s13}, nullptr, nullptr, + nullptr, }, {"s14", nullptr, @@ -534,6 +565,7 @@ static RegisterInfo g_register_infos[] = { fpu_s14}, nullptr, nullptr, + nullptr, }, {"s15", nullptr, @@ -545,6 +577,7 @@ static RegisterInfo g_register_infos[] = { fpu_s15}, nullptr, nullptr, + nullptr, }, {"s16", nullptr, @@ -556,6 +589,7 @@ static RegisterInfo g_register_infos[] = { fpu_s16}, nullptr, nullptr, + nullptr, }, {"s17", nullptr, @@ -567,6 +601,7 @@ static RegisterInfo g_register_infos[] = { fpu_s17}, nullptr, nullptr, + nullptr, }, {"s18", nullptr, @@ -578,6 +613,7 @@ static RegisterInfo g_register_infos[] = { fpu_s18}, nullptr, nullptr, + nullptr, }, {"s19", nullptr, @@ -589,6 +625,7 @@ static RegisterInfo g_register_infos[] = { fpu_s19}, nullptr, nullptr, + nullptr, }, {"s20", nullptr, @@ -600,6 +637,7 @@ static RegisterInfo g_register_infos[] = { fpu_s20}, nullptr, nullptr, + nullptr, }, {"s21", nullptr, @@ -611,6 +649,7 @@ static RegisterInfo g_register_infos[] = { fpu_s21}, nullptr, nullptr, + nullptr, }, {"s22", nullptr, @@ -622,6 +661,7 @@ static RegisterInfo g_register_infos[] = { fpu_s22}, nullptr, nullptr, + nullptr, }, {"s23", nullptr, @@ -633,6 +673,7 @@ static RegisterInfo g_register_infos[] = { fpu_s23}, nullptr, nullptr, + nullptr, }, {"s24", nullptr, @@ -644,6 +685,7 @@ static RegisterInfo g_register_infos[] = { fpu_s24}, nullptr, nullptr, + nullptr, }, {"s25", nullptr, @@ -655,6 +697,7 @@ static RegisterInfo g_register_infos[] = { fpu_s25}, nullptr, nullptr, + nullptr, }, {"s26", nullptr, @@ -666,6 +709,7 @@ static RegisterInfo g_register_infos[] = { fpu_s26}, nullptr, nullptr, + nullptr, }, {"s27", nullptr, @@ -677,6 +721,7 @@ static RegisterInfo g_register_infos[] = { fpu_s27}, nullptr, nullptr, + nullptr, }, {"s28", nullptr, @@ -688,6 +733,7 @@ static RegisterInfo g_register_infos[] = { fpu_s28}, nullptr, nullptr, + nullptr, }, {"s29", nullptr, @@ -699,6 +745,7 @@ static RegisterInfo g_register_infos[] = { fpu_s29}, nullptr, nullptr, + nullptr, }, {"s30", nullptr, @@ -710,6 +757,7 @@ static RegisterInfo g_register_infos[] = { fpu_s30}, nullptr, nullptr, + nullptr, }, {"s31", nullptr, @@ -721,6 +769,7 @@ static RegisterInfo g_register_infos[] = { fpu_s31}, nullptr, nullptr, + nullptr, }, {"fpscr", nullptr, @@ -732,6 +781,7 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, fpu_fpscr}, nullptr, nullptr, + nullptr, }, {"exception", @@ -744,6 +794,7 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_exception}, nullptr, nullptr, + nullptr, }, {"fsr", nullptr, @@ -755,6 +806,7 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_fsr}, nullptr, nullptr, + nullptr, }, {"far", nullptr, @@ -766,6 +818,7 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_far}, nullptr, nullptr, + nullptr, }, {DEFINE_DBG(bvr, 0)}, 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 8cf90e1e2501..3bcd9a28e3f1 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 @@ -59,7 +59,7 @@ using namespace lldb_private; {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM }, \ - NULL, NULL + NULL, NULL, NULL #define REG_CONTEXT_SIZE \ (sizeof(RegisterContextDarwin_arm64::GPR) + \ sizeof(RegisterContextDarwin_arm64::FPU) + \ 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 32a976086f29..bae34af43a92 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 @@ -154,7 +154,7 @@ enum { {LLDB_INVALID_REGNUM, dwarf_##reg##i, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ fpu_##reg##i }, \ - nullptr, nullptr, + nullptr, nullptr, nullptr, #define DEFINE_EXC(reg) \ #reg, NULL, sizeof(((RegisterContextDarwin_i386::EXC *) NULL)->reg), \ @@ -175,96 +175,112 @@ static RegisterInfo g_register_infos[] = { gpr_eax}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(ebx, nullptr), {ehframe_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_ebx}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(ecx, nullptr), {ehframe_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_ecx}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(edx, nullptr), {ehframe_edx, dwarf_edx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_edx}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(edi, nullptr), {ehframe_edi, dwarf_edi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_edi}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(esi, nullptr), {ehframe_esi, dwarf_esi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_esi}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(ebp, "fp"), {ehframe_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_ebp}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(esp, "sp"), {ehframe_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_esp}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(ss, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_ss}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(eflags, "flags"), {ehframe_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_eflags}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(eip, "pc"), {ehframe_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_eip}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(cs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_cs}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(ds, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_ds}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(es, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_es}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(fs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_fs}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(gs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_gs}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(fcw), @@ -272,60 +288,70 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, fpu_fcw}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(fsw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fsw}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(ftw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ftw}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(fop), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fop}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(ip), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ip}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(cs), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_cs}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(dp), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_dp}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(ds), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ds}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(mxcsr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_mxcsr}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(mxcsrmask), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_mxcsrmask}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_VECT(stmm, 0)}, {DEFINE_FPU_VECT(stmm, 1)}, @@ -349,18 +375,21 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_trapno}, nullptr, nullptr, + nullptr, }, {DEFINE_EXC(err), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_err}, nullptr, nullptr, + nullptr, }, {DEFINE_EXC(faultvaddr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_faultvaddr}, nullptr, nullptr, + nullptr, }}; static size_t k_num_register_infos = std::size(g_register_infos); 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 dcd86a1ff92b..08d84e827090 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 @@ -172,7 +172,7 @@ enum ehframe_dwarf_regnums { {ehframe_dwarf_fpu_##reg##i, \ ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, fpu_##reg##i }, \ - nullptr, nullptr, + nullptr, nullptr, nullptr, #define DEFINE_EXC(reg) \ #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg), \ EXC_OFFSET(reg), eEncodingUint, eFormatHex @@ -194,126 +194,147 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, gpr_rax}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rbx, nullptr), {ehframe_dwarf_gpr_rbx, ehframe_dwarf_gpr_rbx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rbx}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rcx, nullptr), {ehframe_dwarf_gpr_rcx, ehframe_dwarf_gpr_rcx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rcx}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rdx, nullptr), {ehframe_dwarf_gpr_rdx, ehframe_dwarf_gpr_rdx, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rdx}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rdi, nullptr), {ehframe_dwarf_gpr_rdi, ehframe_dwarf_gpr_rdi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rdi}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rsi, nullptr), {ehframe_dwarf_gpr_rsi, ehframe_dwarf_gpr_rsi, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_rsi}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rbp, "fp"), {ehframe_dwarf_gpr_rbp, ehframe_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM, gpr_rbp}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rsp, "sp"), {ehframe_dwarf_gpr_rsp, ehframe_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM, gpr_rsp}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(r8, nullptr), {ehframe_dwarf_gpr_r8, ehframe_dwarf_gpr_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(r9, nullptr), {ehframe_dwarf_gpr_r9, ehframe_dwarf_gpr_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(r10, nullptr), {ehframe_dwarf_gpr_r10, ehframe_dwarf_gpr_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r10}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(r11, nullptr), {ehframe_dwarf_gpr_r11, ehframe_dwarf_gpr_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r11}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(r12, nullptr), {ehframe_dwarf_gpr_r12, ehframe_dwarf_gpr_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r12}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(r13, nullptr), {ehframe_dwarf_gpr_r13, ehframe_dwarf_gpr_r13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r13}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(r14, nullptr), {ehframe_dwarf_gpr_r14, ehframe_dwarf_gpr_r14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r14}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(r15, nullptr), {ehframe_dwarf_gpr_r15, ehframe_dwarf_gpr_r15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r15}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rip, "pc"), {ehframe_dwarf_gpr_rip, ehframe_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM, gpr_rip}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(rflags, "flags"), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM, gpr_rflags}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(cs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_cs}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(fs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_fs}, nullptr, nullptr, + nullptr, }, {DEFINE_GPR(gs, nullptr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_gs}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(fcw), @@ -321,60 +342,70 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, fpu_fcw}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(fsw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fsw}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(ftw), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ftw}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(fop), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_fop}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(ip), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ip}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(cs), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_cs}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(dp), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_dp}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(ds), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_ds}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(mxcsr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_mxcsr}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_UINT(mxcsrmask), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fpu_mxcsrmask}, nullptr, nullptr, + nullptr, }, {DEFINE_FPU_VECT(stmm, 0)}, {DEFINE_FPU_VECT(stmm, 1)}, @@ -406,18 +437,21 @@ static RegisterInfo g_register_infos[] = { LLDB_INVALID_REGNUM, exc_trapno}, nullptr, nullptr, + nullptr, }, {DEFINE_EXC(err), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_err}, nullptr, nullptr, + nullptr, }, {DEFINE_EXC(faultvaddr), {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, exc_faultvaddr}, nullptr, nullptr, + nullptr, }}; static size_t k_num_register_infos = std::size(g_register_infos); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp index 0b3953e1ec2c..9e022baa297b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.cpp @@ -88,21 +88,19 @@ struct UserArea { RegisterContextLinux_i386::RegisterContextLinux_i386( const ArchSpec &target_arch) - : RegisterInfoInterface(target_arch) { - RegisterInfo orig_ax = { - "orig_eax", - nullptr, - sizeof(((GPR *)nullptr)->orig_eax), - (LLVM_EXTENSION offsetof(GPR, orig_eax)), - eEncodingUint, - eFormatHex, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, - nullptr, - nullptr, - }; - d_register_infos.push_back(orig_ax); -} + : RegisterContextLinux_x86( + target_arch, + {"orig_eax", + nullptr, + sizeof(((GPR *)nullptr)->orig_eax), + (LLVM_EXTENSION offsetof(GPR, orig_eax)), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr}) {} size_t RegisterContextLinux_i386::GetGPRSizeStatic() { return sizeof(GPR); } @@ -125,8 +123,3 @@ uint32_t RegisterContextLinux_i386::GetRegisterCount() const { uint32_t RegisterContextLinux_i386::GetUserRegisterCount() const { return static_cast<uint32_t>(k_num_user_registers_i386); } - -const std::vector<lldb_private::RegisterInfo> * -RegisterContextLinux_i386::GetDynamicRegisterInfoP() const { - return &d_register_infos; -} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h index e0f8114fa58f..c10613993689 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_i386.h @@ -9,9 +9,10 @@ #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_I386_H -#include "RegisterInfoInterface.h" +#include "Plugins/Process/Utility/RegisterContextLinux_x86.h" -class RegisterContextLinux_i386 : public lldb_private::RegisterInfoInterface { +class RegisterContextLinux_i386 + : public lldb_private::RegisterContextLinux_x86 { public: RegisterContextLinux_i386(const lldb_private::ArchSpec &target_arch); @@ -23,12 +24,6 @@ public: uint32_t GetRegisterCount() const override; uint32_t GetUserRegisterCount() const override; - - const std::vector<lldb_private::RegisterInfo> * - GetDynamicRegisterInfoP() const override; - -private: - std::vector<lldb_private::RegisterInfo> d_register_infos; }; #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp index 7a8989cd1225..77627cfbdefe 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.cpp @@ -54,11 +54,6 @@ RegisterContextLinux_s390x::RegisterContextLinux_s390x( m_register_info_count(GetRegisterInfoCount(target_arch)), m_user_register_count(GetUserRegisterInfoCount(target_arch)) {} -const std::vector<lldb_private::RegisterInfo> * -RegisterContextLinux_s390x::GetDynamicRegisterInfoP() const { - return &d_register_infos; -} - const RegisterInfo *RegisterContextLinux_s390x::GetRegisterInfo() const { return m_register_info_p; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h index f381f38ecbf9..6bfe34de7acf 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_s390x.h @@ -23,14 +23,10 @@ public: uint32_t GetUserRegisterCount() const override; - const std::vector<lldb_private::RegisterInfo> * - GetDynamicRegisterInfoP() const override; - private: const lldb_private::RegisterInfo *m_register_info_p; uint32_t m_register_info_count; uint32_t m_user_register_count; - std::vector<lldb_private::RegisterInfo> d_register_infos; }; #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86.h new file mode 100644 index 000000000000..0e1863864aa6 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86.h @@ -0,0 +1,30 @@ +//===-- RegisterContextLinux_i386.h -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_H +#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_H + +#include "RegisterInfoInterface.h" + +namespace lldb_private { + +class RegisterContextLinux_x86 : public RegisterInfoInterface { +public: + RegisterContextLinux_x86(const ArchSpec &target_arch, + RegisterInfo orig_ax_info) + : RegisterInfoInterface(target_arch), m_orig_ax_info(orig_ax_info) {} + + const RegisterInfo &GetOrigAxInfo() const { return m_orig_ax_info; } + +private: + lldb_private::RegisterInfo m_orig_ax_info; +}; + +} // namespace lldb_private + +#endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp index 85c57ca698d4..63c034a858d7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.cpp @@ -75,10 +75,10 @@ struct UserArea { (LLVM_EXTENSION offsetof(UserArea, dbg) + \ LLVM_EXTENSION offsetof(DBG, dr[reg_index])) -// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64 +// Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64_with_base // structure. #define DECLARE_REGISTER_INFOS_X86_64_STRUCT -#include "RegisterInfos_x86_64.h" +#include "RegisterInfos_x86_64_with_base.h" #undef DECLARE_REGISTER_INFOS_X86_64_STRUCT static std::vector<lldb_private::RegisterInfo> &GetPrivateRegisterInfoVector() { @@ -103,7 +103,7 @@ GetRegisterInfo_i386(const lldb_private::ArchSpec &arch) { // Include RegisterInfos_x86_64 to update the g_register_infos structure // with x86_64 offsets. #define UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS -#include "RegisterInfos_x86_64.h" +#include "RegisterInfos_x86_64_with_base.h" #undef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS } @@ -115,7 +115,7 @@ static const RegisterInfo *GetRegisterInfoPtr(const ArchSpec &target_arch) { case llvm::Triple::x86: return GetRegisterInfo_i386(target_arch); case llvm::Triple::x86_64: - return g_register_infos_x86_64; + return g_register_infos_x86_64_with_base; default: assert(false && "Unhandled target architecture."); return nullptr; @@ -130,8 +130,8 @@ static uint32_t GetRegisterInfoCount(const ArchSpec &target_arch) { return static_cast<uint32_t>(GetPrivateRegisterInfoVector().size()); } case llvm::Triple::x86_64: - return static_cast<uint32_t>(sizeof(g_register_infos_x86_64) / - sizeof(g_register_infos_x86_64[0])); + return static_cast<uint32_t>(sizeof(g_register_infos_x86_64_with_base) / + sizeof(g_register_infos_x86_64_with_base[0])); default: assert(false && "Unhandled target architecture."); return 0; @@ -143,7 +143,7 @@ static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) { case llvm::Triple::x86: return static_cast<uint32_t>(k_num_user_registers_i386); case llvm::Triple::x86_64: - return static_cast<uint32_t>(k_num_user_registers_x86_64); + return static_cast<uint32_t>(x86_64_with_base::k_num_user_registers); default: assert(false && "Unhandled target architecture."); return 0; @@ -152,32 +152,25 @@ static uint32_t GetUserRegisterInfoCount(const ArchSpec &target_arch) { RegisterContextLinux_x86_64::RegisterContextLinux_x86_64( const ArchSpec &target_arch) - : lldb_private::RegisterInfoInterface(target_arch), + : lldb_private::RegisterContextLinux_x86( + target_arch, + {"orig_rax", + nullptr, + sizeof(((GPR *)nullptr)->orig_rax), + (LLVM_EXTENSION offsetof(GPR, orig_rax)), + eEncodingUint, + eFormatHex, + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, + nullptr, + nullptr, + nullptr}), m_register_info_p(GetRegisterInfoPtr(target_arch)), m_register_info_count(GetRegisterInfoCount(target_arch)), - m_user_register_count(GetUserRegisterInfoCount(target_arch)) { - RegisterInfo orig_ax = { - "orig_rax", - nullptr, - sizeof(((GPR *)nullptr)->orig_rax), - (LLVM_EXTENSION offsetof(GPR, orig_rax)), - eEncodingUint, - eFormatHex, - {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, - nullptr, - nullptr, - }; - d_register_infos.push_back(orig_ax); -} + m_user_register_count(GetUserRegisterInfoCount(target_arch)) {} size_t RegisterContextLinux_x86_64::GetGPRSizeStatic() { return sizeof(GPR); } -const std::vector<lldb_private::RegisterInfo> * -RegisterContextLinux_x86_64::GetDynamicRegisterInfoP() const { - return &d_register_infos; -} - const RegisterInfo *RegisterContextLinux_x86_64::GetRegisterInfo() const { return m_register_info_p; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h index a09deebed23a..d141ba66b4e2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextLinux_x86_64.h @@ -9,9 +9,10 @@ #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTLINUX_X86_64_H -#include "RegisterInfoInterface.h" +#include "Plugins/Process/Utility/RegisterContextLinux_x86.h" -class RegisterContextLinux_x86_64 : public lldb_private::RegisterInfoInterface { +class RegisterContextLinux_x86_64 + : public lldb_private::RegisterContextLinux_x86 { public: RegisterContextLinux_x86_64(const lldb_private::ArchSpec &target_arch); @@ -24,14 +25,10 @@ public: uint32_t GetUserRegisterCount() const override; - const std::vector<lldb_private::RegisterInfo> * - GetDynamicRegisterInfoP() const override; - private: const lldb_private::RegisterInfo *m_register_info_p; uint32_t m_register_info_count; uint32_t m_user_register_count; - std::vector<lldb_private::RegisterInfo> d_register_infos; }; #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp index 21aad92ecda8..32bb7952820d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextNetBSD_x86_64.cpp @@ -9,8 +9,8 @@ #include "RegisterContextNetBSD_x86_64.h" #include "RegisterContextNetBSD_i386.h" #include "RegisterContextPOSIX_x86.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/Triple.h" #include <cassert> #include <cstddef> diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index 0e0db843c8b4..c14eb135c7b1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -374,15 +374,15 @@ static const RegisterSet g_reg_sets_x86_64[k_num_register_sets] = { g_avx_regnums_x86_64}}; bool RegisterContextPOSIX_x86::IsGPR(unsigned reg) { - return reg <= m_reg_info.last_gpr; // GPR's come first. + return reg <= GetRegInfo().last_gpr; // GPR's come first. } bool RegisterContextPOSIX_x86::IsFPR(unsigned reg) { - return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr); + return (GetRegInfo().first_fpr <= reg && reg <= GetRegInfo().last_fpr); } bool RegisterContextPOSIX_x86::IsAVX(unsigned reg) { - return (m_reg_info.first_ymm <= reg && reg <= m_reg_info.last_ymm); + return (GetRegInfo().first_ymm <= reg && reg <= GetRegInfo().last_ymm); } bool RegisterContextPOSIX_x86::IsFPR(unsigned reg, FPRType fpr_type) { @@ -399,50 +399,6 @@ RegisterContextPOSIX_x86::RegisterContextPOSIX_x86( : RegisterContext(thread, concrete_frame_idx) { m_register_info_up.reset(register_info); - switch (register_info->GetTargetArchitecture().GetMachine()) { - case llvm::Triple::x86: - m_reg_info.num_registers = k_num_registers_i386; - m_reg_info.num_gpr_registers = k_num_gpr_registers_i386; - m_reg_info.num_fpr_registers = k_num_fpr_registers_i386; - m_reg_info.num_avx_registers = k_num_avx_registers_i386; - m_reg_info.last_gpr = k_last_gpr_i386; - m_reg_info.first_fpr = k_first_fpr_i386; - m_reg_info.last_fpr = k_last_fpr_i386; - m_reg_info.first_st = lldb_st0_i386; - m_reg_info.last_st = lldb_st7_i386; - m_reg_info.first_mm = lldb_mm0_i386; - m_reg_info.last_mm = lldb_mm7_i386; - m_reg_info.first_xmm = lldb_xmm0_i386; - m_reg_info.last_xmm = lldb_xmm7_i386; - m_reg_info.first_ymm = lldb_ymm0_i386; - m_reg_info.last_ymm = lldb_ymm7_i386; - m_reg_info.first_dr = lldb_dr0_i386; - m_reg_info.gpr_flags = lldb_eflags_i386; - break; - case llvm::Triple::x86_64: - m_reg_info.num_registers = k_num_registers_x86_64; - m_reg_info.num_gpr_registers = k_num_gpr_registers_x86_64; - m_reg_info.num_fpr_registers = k_num_fpr_registers_x86_64; - m_reg_info.num_avx_registers = k_num_avx_registers_x86_64; - m_reg_info.last_gpr = k_last_gpr_x86_64; - m_reg_info.first_fpr = k_first_fpr_x86_64; - m_reg_info.last_fpr = k_last_fpr_x86_64; - m_reg_info.first_st = lldb_st0_x86_64; - m_reg_info.last_st = lldb_st7_x86_64; - m_reg_info.first_mm = lldb_mm0_x86_64; - m_reg_info.last_mm = lldb_mm7_x86_64; - m_reg_info.first_xmm = lldb_xmm0_x86_64; - m_reg_info.last_xmm = lldb_xmm15_x86_64; - m_reg_info.first_ymm = lldb_ymm0_x86_64; - m_reg_info.last_ymm = lldb_ymm15_x86_64; - m_reg_info.first_dr = lldb_dr0_x86_64; - m_reg_info.gpr_flags = lldb_rflags_x86_64; - break; - default: - assert(false && "Unhandled target architecture."); - break; - } - ::memset(&m_fpr, 0, sizeof(FPR)); ::memset(&m_ymm_set, 0, sizeof(YMM)); @@ -466,20 +422,26 @@ void RegisterContextPOSIX_x86::Invalidate() {} void RegisterContextPOSIX_x86::InvalidateAllRegisters() {} unsigned RegisterContextPOSIX_x86::GetRegisterOffset(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); + assert(reg < GetRegInfo().num_registers && "Invalid register number."); return GetRegisterInfo()[reg].byte_offset; } +RegInfo &RegisterContextPOSIX_x86::GetRegInfo() { + return GetRegInfoShared( + m_register_info_up->GetTargetArchitecture().GetMachine(), + /*with_base=*/false); +} + unsigned RegisterContextPOSIX_x86::GetRegisterSize(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register number."); + assert(reg < GetRegInfo().num_registers && "Invalid register number."); return GetRegisterInfo()[reg].byte_size; } size_t RegisterContextPOSIX_x86::GetRegisterCount() { size_t num_registers = - m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers; + GetRegInfo().num_gpr_registers + GetRegInfo().num_fpr_registers; if (GetFPRType() == eXSAVE) - return num_registers + m_reg_info.num_avx_registers; + return num_registers + GetRegInfo().num_avx_registers; return num_registers; } @@ -488,7 +450,7 @@ size_t RegisterContextPOSIX_x86::GetGPRSize() { } size_t RegisterContextPOSIX_x86::GetFXSAVEOffset() { - return GetRegisterInfo()[m_reg_info.first_fpr].byte_offset; + return GetRegisterInfo()[GetRegInfo().first_fpr].byte_offset; } const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() { @@ -500,7 +462,7 @@ const RegisterInfo *RegisterContextPOSIX_x86::GetRegisterInfo() { const RegisterInfo * RegisterContextPOSIX_x86::GetRegisterInfoAtIndex(size_t reg) { - if (reg < m_reg_info.num_registers) + if (reg < GetRegInfo().num_registers) return &GetRegisterInfo()[reg]; else return nullptr; @@ -532,7 +494,7 @@ const RegisterSet *RegisterContextPOSIX_x86::GetRegisterSet(size_t set) { } const char *RegisterContextPOSIX_x86::GetRegisterName(unsigned reg) { - assert(reg < m_reg_info.num_registers && "Invalid register offset."); + assert(reg < GetRegInfo().num_registers && "Invalid register offset."); return GetRegisterInfo()[reg].name; } @@ -543,10 +505,9 @@ bool RegisterContextPOSIX_x86::CopyYMMtoXSTATE(uint32_t reg, return false; if (byte_order == eByteOrderLittle) { - uint32_t reg_no = reg - m_reg_info.first_ymm; - YMMToXState(m_ymm_set.ymm[reg_no], - m_fpr.fxsave.xmm[reg_no].bytes, - m_fpr.xsave.ymmh[reg_no].bytes); + uint32_t reg_no = reg - GetRegInfo().first_ymm; + YMMToXState(m_ymm_set.ymm[reg_no], m_fpr.fxsave.xmm[reg_no].bytes, + m_fpr.xsave.ymmh[reg_no].bytes); return true; } @@ -560,10 +521,9 @@ bool RegisterContextPOSIX_x86::CopyXSTATEtoYMM(uint32_t reg, return false; if (byte_order == eByteOrderLittle) { - uint32_t reg_no = reg - m_reg_info.first_ymm; - m_ymm_set.ymm[reg_no] = XStateToYMM( - m_fpr.fxsave.xmm[reg_no].bytes, - m_fpr.xsave.ymmh[reg_no].bytes); + uint32_t reg_no = reg - GetRegInfo().first_ymm; + m_ymm_set.ymm[reg_no] = XStateToYMM(m_fpr.fxsave.xmm[reg_no].bytes, + m_fpr.xsave.ymmh[reg_no].bytes); return true; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h index d6672835b4a8..9284f5cc07d9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -11,6 +11,7 @@ #include "RegisterContext_x86.h" #include "RegisterInfoInterface.h" +#include "RegisterInfos_x86_64_with_base_shared.h" #include "lldb-x86-register-enums.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" @@ -149,34 +150,6 @@ public: static uint32_t g_invalidate_st7_64[]; protected: - struct RegInfo { - uint32_t num_registers; - uint32_t num_gpr_registers; - uint32_t num_fpr_registers; - uint32_t num_avx_registers; - - uint32_t last_gpr; - uint32_t first_fpr; - uint32_t last_fpr; - - uint32_t first_st; - uint32_t last_st; - uint32_t first_mm; - uint32_t last_mm; - uint32_t first_xmm; - uint32_t last_xmm; - uint32_t first_ymm; - uint32_t last_ymm; - - uint32_t first_dr; - uint32_t gpr_flags; - }; - - uint64_t m_gpr_x86_64[lldb_private::k_num_gpr_registers_x86_64]; // 64-bit - // general - // purpose - // registers. - RegInfo m_reg_info; FPRType m_fpr_type; // determines the type of data stored by union FPR, if any. lldb_private::FPR m_fpr; // floating-point registers including extended @@ -206,6 +179,7 @@ protected: virtual bool ReadFPR() = 0; virtual bool WriteGPR() = 0; virtual bool WriteFPR() = 0; + virtual lldb_private::RegInfo &GetRegInfo(); }; #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_X86_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp index 323f7e911866..faf4021aa499 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_i386.cpp @@ -41,6 +41,7 @@ typedef struct _GPR { #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ eFormatHex, \ {kind1, kind2, kind3, kind4, lldb_##reg##_i386 }, nullptr, nullptr, \ + nullptr, \ } // clang-format off diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp index aaebeaa686e3..c3fc2e0026bc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContextWindows_x86_64.cpp @@ -49,6 +49,7 @@ typedef struct _GPR { #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ eFormatHex, \ {kind1, kind2, kind3, kind4, lldb_##reg##_x86_64 }, nullptr, nullptr, \ + nullptr, \ } typedef struct _FPReg { @@ -79,7 +80,7 @@ typedef struct _FPReg { eEncodingUint, eFormatVectorOfUInt64, \ {dwarf_##reg##_x86_64, dwarf_##reg##_x86_64, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##reg##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } // clang-format off diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h index 76e004ce0ceb..e24da37b7261 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -201,6 +201,9 @@ enum { dwarf_ds_x86_64, dwarf_fs_x86_64, dwarf_gs_x86_64, + // Base registers + dwarf_fs_base_x86_64 = 58, + dwarf_gs_base_x86_64 = 59, // Floating point control registers dwarf_mxcsr_x86_64 = 64, // Media Control and Status dwarf_fctrl_x86_64, // x87 control word diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h index d8414c594d24..a79c5cc22b24 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoInterface.h @@ -41,26 +41,6 @@ public: return m_target_arch; } - virtual const lldb_private::RegisterInfo * - GetDynamicRegisterInfo(const char *reg_name) const { - const std::vector<lldb_private::RegisterInfo> *d_register_infos = - GetDynamicRegisterInfoP(); - if (d_register_infos != nullptr) { - std::vector<lldb_private::RegisterInfo>::const_iterator pos = - d_register_infos->begin(); - for (; pos < d_register_infos->end(); pos++) { - if (::strcmp(reg_name, pos->name) == 0) - return (d_register_infos->data() + (pos - d_register_infos->begin())); - } - } - return nullptr; - } - - virtual const std::vector<lldb_private::RegisterInfo> * - GetDynamicRegisterInfoP() const { - return nullptr; - } - private: lldb_private::ArchSpec m_target_arch; }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp index fd4c373e2cb1..d47647422ae2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm.cpp @@ -38,7 +38,7 @@ using namespace lldb_private; {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ dbg_##reg##i }, \ - NULL, NULL, + NULL, NULL, NULL, #define REG_CONTEXT_SIZE \ (sizeof(RegisterInfoPOSIX_arm::GPR) + sizeof(RegisterInfoPOSIX_arm::FPU) + \ sizeof(RegisterInfoPOSIX_arm::EXC)) 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 1c46df79c7d0..af5bbda7bfcf 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 @@ -60,7 +60,7 @@ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ dbg_##reg##i }, \ - NULL, NULL, + NULL, NULL, NULL, #define REG_CONTEXT_SIZE \ (sizeof(RegisterInfoPOSIX_arm64::GPR) + \ sizeof(RegisterInfoPOSIX_arm64::FPU) + \ @@ -78,12 +78,16 @@ static lldb_private::RegisterInfo g_register_infos_pauth[] = { static lldb_private::RegisterInfo g_register_infos_mte[] = { DEFINE_EXTENSION_REG(mte_ctrl)}; +static lldb_private::RegisterInfo g_register_infos_tls[] = { + DEFINE_EXTENSION_REG(tpidr)}; + // Number of register sets provided by this context. enum { k_num_gpr_registers = gpr_w28 - gpr_x0 + 1, k_num_fpr_registers = fpu_fpcr - fpu_v0 + 1, k_num_sve_registers = sve_ffr - sve_vg + 1, k_num_mte_register = 1, + k_num_tls_register = 1, k_num_pauth_register = 2, k_num_register_sets_default = 2, k_num_register_sets = 3 @@ -189,6 +193,9 @@ static const lldb_private::RegisterSet g_reg_set_pauth_arm64 = { static const lldb_private::RegisterSet g_reg_set_mte_arm64 = { "MTE Control Register", "mte", k_num_mte_register, nullptr}; +static const lldb_private::RegisterSet g_reg_set_tls_arm64 = { + "Thread Local Storage Registers", "tls", k_num_tls_register, nullptr}; + RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets) : lldb_private::RegisterInfoAndSetInterface(target_arch), @@ -229,6 +236,10 @@ RegisterInfoPOSIX_arm64::RegisterInfoPOSIX_arm64( if (m_opt_regsets.AllSet(eRegsetMaskMTE)) AddRegSetMTE(); + // tpidr is always present, but in future there will be others so this is + // done as a dynamic set. + AddRegSetTLS(); + m_register_info_count = m_dynamic_reg_infos.size(); m_register_info_p = m_dynamic_reg_infos.data(); m_register_set_p = m_dynamic_reg_sets.data(); @@ -312,6 +323,21 @@ void RegisterInfoPOSIX_arm64::AddRegSetMTE() { m_dynamic_reg_sets.back().registers = m_mte_regnum_collection.data(); } +void RegisterInfoPOSIX_arm64::AddRegSetTLS() { + uint32_t tls_regnum = m_dynamic_reg_infos.size(); + m_tls_regnum_collection.push_back(tls_regnum); + m_dynamic_reg_infos.push_back(g_register_infos_tls[0]); + m_dynamic_reg_infos[tls_regnum].byte_offset = + m_dynamic_reg_infos[tls_regnum - 1].byte_offset + + m_dynamic_reg_infos[tls_regnum - 1].byte_size; + m_dynamic_reg_infos[tls_regnum].kinds[lldb::eRegisterKindLLDB] = tls_regnum; + + m_per_regset_regnum_range[m_register_set_count] = + std::make_pair(tls_regnum, tls_regnum + 1); + m_dynamic_reg_sets.push_back(g_reg_set_tls_arm64); + m_dynamic_reg_sets.back().registers = m_tls_regnum_collection.data(); +} + uint32_t RegisterInfoPOSIX_arm64::ConfigureVectorLength(uint32_t sve_vq) { // sve_vq contains SVE Quad vector length in context of AArch64 SVE. // SVE register infos if enabled cannot be disabled by selecting sve_vq = 0. @@ -403,6 +429,10 @@ bool RegisterInfoPOSIX_arm64::IsMTEReg(unsigned reg) const { return llvm::is_contained(m_mte_regnum_collection, reg); } +bool RegisterInfoPOSIX_arm64::IsTLSReg(unsigned reg) const { + return llvm::is_contained(m_tls_regnum_collection, reg); +} + uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEZ0() const { return sve_z0; } uint32_t RegisterInfoPOSIX_arm64::GetRegNumSVEFFR() const { return sve_ffr; } @@ -420,3 +450,7 @@ uint32_t RegisterInfoPOSIX_arm64::GetPAuthOffset() const { uint32_t RegisterInfoPOSIX_arm64::GetMTEOffset() const { return m_register_info_p[m_mte_regnum_collection[0]].byte_offset; } + +uint32_t RegisterInfoPOSIX_arm64::GetTLSOffset() const { + return m_register_info_p[m_tls_regnum_collection[0]].byte_offset; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h index 4c52de99fde6..465d3f5b9f3b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h @@ -28,6 +28,7 @@ public: eRegsetMaskSVE = 1, eRegsetMaskPAuth = 2, eRegsetMaskMTE = 4, + eRegsetMaskTLS = 8, eRegsetMaskDynamic = ~1, }; @@ -102,6 +103,8 @@ public: void AddRegSetMTE(); + void AddRegSetTLS(); + uint32_t ConfigureVectorLength(uint32_t sve_vq); bool VectorSizeIsValid(uint32_t vq) { @@ -121,6 +124,7 @@ public: bool IsSVERegVG(unsigned reg) const; bool IsPAuthReg(unsigned reg) const; bool IsMTEReg(unsigned reg) const; + bool IsTLSReg(unsigned reg) const; uint32_t GetRegNumSVEZ0() const; uint32_t GetRegNumSVEFFR() const; @@ -129,6 +133,7 @@ public: uint32_t GetRegNumSVEVG() const; uint32_t GetPAuthOffset() const; uint32_t GetMTEOffset() const; + uint32_t GetTLSOffset() const; private: typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>> @@ -155,6 +160,7 @@ private: std::vector<uint32_t> pauth_regnum_collection; std::vector<uint32_t> m_mte_regnum_collection; + std::vector<uint32_t> m_tls_regnum_collection; }; #endif diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h index c5b955f93af6..4bf4bede0132 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h @@ -35,6 +35,11 @@ public: uint32_t fcsr; }; + struct VPR { + // The size should be VLEN*32 in bits, but we don't have VLEN here. + void *vpr; + }; + RegisterInfoPOSIX_riscv64(const lldb_private::ArchSpec &target_arch, lldb_private::Flags flags); diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h index ace2e5a9f68b..ae6a442d7a1d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h @@ -350,7 +350,7 @@ static uint32_t g_q15_contained[] = {fpu_q15, LLDB_INVALID_REGNUM}; #name, nullptr, size, FPU_OFFSET(offset), eEncodingIEEE754, eFormatFloat, \ {LLDB_INVALID_REGNUM, dwarf_##name, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, fpu_##name }, \ - g_##qreg##_contained, g_##name##_invalidates, \ + g_##qreg##_contained, g_##name##_invalidates, nullptr, \ } #define FPU_QREG(name, offset) \ @@ -359,7 +359,7 @@ static uint32_t g_q15_contained[] = {fpu_q15, LLDB_INVALID_REGNUM}; eFormatVectorOfUInt8, \ {LLDB_INVALID_REGNUM, dwarf_##name, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, fpu_##name }, \ - nullptr, g_##name##_invalidates, \ + nullptr, g_##name##_invalidates, nullptr, \ } static RegisterInfo g_register_infos_arm[] = { @@ -381,6 +381,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r0}, nullptr, nullptr, + nullptr, }, { "r1", @@ -393,6 +394,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r1}, nullptr, nullptr, + nullptr, }, { "r2", @@ -405,6 +407,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r2}, nullptr, nullptr, + nullptr, }, { "r3", @@ -417,6 +420,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r3}, nullptr, nullptr, + nullptr, }, { "r4", @@ -429,6 +433,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r4}, nullptr, nullptr, + nullptr, }, { "r5", @@ -441,6 +446,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r5}, nullptr, nullptr, + nullptr, }, { "r6", @@ -453,6 +459,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r6}, nullptr, nullptr, + nullptr, }, { "r7", @@ -465,6 +472,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r7}, nullptr, nullptr, + nullptr, }, { "r8", @@ -477,6 +485,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r8}, nullptr, nullptr, + nullptr, }, { "r9", @@ -489,6 +498,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r9}, nullptr, nullptr, + nullptr, }, { "r10", @@ -501,6 +511,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r10}, nullptr, nullptr, + nullptr, }, { "r11", @@ -513,6 +524,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r11}, nullptr, nullptr, + nullptr, }, { "r12", @@ -525,6 +537,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_r12}, nullptr, nullptr, + nullptr, }, { "sp", @@ -537,6 +550,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_sp}, nullptr, nullptr, + nullptr, }, { "lr", @@ -549,6 +563,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_lr}, nullptr, nullptr, + nullptr, }, { "pc", @@ -561,6 +576,7 @@ static RegisterInfo g_register_infos_arm[] = { gpr_pc}, nullptr, nullptr, + nullptr, }, { "cpsr", @@ -573,6 +589,7 @@ static RegisterInfo g_register_infos_arm[] = { LLDB_INVALID_REGNUM, gpr_cpsr}, nullptr, nullptr, + nullptr, }, FPU_REG(s0, 4, 0, q0), @@ -619,6 +636,7 @@ static RegisterInfo g_register_infos_arm[] = { LLDB_INVALID_REGNUM, fpu_fpscr}, nullptr, nullptr, + nullptr, }, FPU_REG(d0, 8, 0, q0), @@ -682,6 +700,7 @@ static RegisterInfo g_register_infos_arm[] = { LLDB_INVALID_REGNUM, exc_exception}, nullptr, nullptr, + nullptr, }, { "fsr", @@ -694,6 +713,7 @@ static RegisterInfo g_register_infos_arm[] = { LLDB_INVALID_REGNUM, exc_fsr}, nullptr, nullptr, + nullptr, }, { "far", @@ -706,6 +726,7 @@ static RegisterInfo g_register_infos_arm[] = { LLDB_INVALID_REGNUM, exc_far}, nullptr, nullptr, + nullptr, }, {DEFINE_DBG(bvr, 0)}, 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 513ca5a8f10c..c9c4d7ceae55 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 @@ -491,6 +491,7 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #reg, nullptr, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \ lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \ + nullptr, \ } // Defines a 64-bit general purpose register @@ -498,6 +499,7 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #reg, #alt, 8, GPR_OFFSET(gpr_##reg), lldb::eEncodingUint, \ lldb::eFormatHex, GPR64_KIND(reg, generic_kind), nullptr, nullptr, \ + nullptr, \ } // Defines a 32-bit general purpose pseudo register @@ -506,14 +508,14 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; #wreg, nullptr, 4, \ GPR_OFFSET(gpr_##xreg) + GPR_W_PSEUDO_REG_ENDIAN_OFFSET, \ lldb::eEncodingUint, lldb::eFormatHex, LLDB_KIND(gpr_##wreg), \ - g_contained_##xreg, g_##wreg##_invalidates, \ + g_contained_##xreg, g_##wreg##_invalidates, nullptr, \ } // Defines a vector register with 16-byte size #define DEFINE_VREG(reg) \ { \ #reg, nullptr, 16, FPU_OFFSET(fpu_##reg - fpu_v0), lldb::eEncodingVector, \ - lldb::eFormatVectorOfUInt8, VREG_KIND(reg), nullptr, nullptr, \ + lldb::eFormatVectorOfUInt8, VREG_KIND(reg), nullptr, nullptr, nullptr, \ } // Defines S and D pseudo registers mapping over corresponding vector register @@ -521,7 +523,7 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #reg, nullptr, size, FPU_OFFSET(fpu_##vreg - fpu_v0) + offset, \ lldb::eEncodingIEEE754, lldb::eFormatFloat, LLDB_KIND(fpu_##reg), \ - g_contained_##vreg, g_##reg##_invalidates, \ + g_contained_##vreg, g_##reg##_invalidates, nullptr, \ } // Defines miscellaneous status and control registers like cpsr, fpsr etc @@ -529,13 +531,14 @@ static uint32_t g_d31_invalidates[] = {fpu_v31, fpu_s31, LLDB_INVALID_REGNUM}; { \ #reg, nullptr, size, TYPE##_OFFSET_NAME(reg), lldb::eEncodingUint, \ lldb::eFormatHex, MISC_##TYPE##_KIND(lldb_kind), nullptr, nullptr, \ + nullptr, \ } // Defines pointer authentication mask registers #define DEFINE_EXTENSION_REG(reg) \ { \ #reg, nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \ - KIND_ALL_INVALID, nullptr, nullptr, \ + KIND_ALL_INVALID, nullptr, nullptr, nullptr, \ } static lldb_private::RegisterInfo g_register_infos_arm64_le[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h index f61e3738b8fc..283c4c17e760 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64_sve.h @@ -311,6 +311,7 @@ static uint32_t g_contained_z31[] = {sve_z31, LLDB_INVALID_REGNUM}; { \ #vreg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \ VREG_KIND(vreg), g_contained_##zreg, g_sve_##vreg##_invalidates, \ + nullptr, \ } // Defines S and D pseudo registers mapping over corresponding vector register @@ -318,20 +319,21 @@ static uint32_t g_contained_z31[] = {sve_z31, LLDB_INVALID_REGNUM}; { \ #reg, nullptr, size, 0, lldb::eEncodingIEEE754, lldb::eFormatFloat, \ LLDB_KIND(fpu_##reg), g_contained_##zreg, g_sve_##reg##_invalidates, \ + nullptr, \ } // Defines a Z vector register with 16-byte default size #define DEFINE_ZREG(reg) \ { \ #reg, nullptr, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \ - SVE_REG_KIND(reg), nullptr, nullptr, \ + SVE_REG_KIND(reg), nullptr, nullptr, nullptr, \ } // Defines a P vector register with 2-byte default size #define DEFINE_PREG(reg) \ { \ #reg, nullptr, 2, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \ - SVE_REG_KIND(reg), nullptr, nullptr, \ + SVE_REG_KIND(reg), nullptr, nullptr, nullptr, \ } static lldb_private::RegisterInfo g_register_infos_arm64_sve_le[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h index 4b73008adb16..e9f8065bffd8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -64,7 +64,7 @@ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ lldb_##reg##_i386 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ @@ -72,7 +72,7 @@ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ lldb_##name##_i386 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } // RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB @@ -84,7 +84,7 @@ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \ {ehframe_st##i##_i386, dwarf_st##i##_i386, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_st##i##_i386 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_FP_MM(reg, i, streg) \ @@ -95,6 +95,7 @@ LLDB_INVALID_REGNUM, lldb_mm##i##_i386 }, \ RegisterContextPOSIX_x86::g_contained_##streg##_32, \ RegisterContextPOSIX_x86::g_invalidate_##streg##_32, \ + nullptr, \ } #define DEFINE_XMM(reg, i) \ @@ -104,7 +105,7 @@ reg[i]), eEncodingVector, eFormatVectorOfUInt8, \ {ehframe_##reg##i##_i386, dwarf_##reg##i##_i386, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } // I believe the YMM registers use dwarf_xmm_%_i386 register numbers and then @@ -116,7 +117,7 @@ {LLDB_INVALID_REGNUM, dwarf_xmm##i##_i386, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_i386 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_BNDR(reg, i) \ @@ -125,7 +126,7 @@ LLVM_EXTENSION BNDR_OFFSET(i), eEncodingVector, eFormatVectorOfUInt64, \ {dwarf_##reg##i##_i386, dwarf_##reg##i##_i386, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##reg##i##_i386 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_BNDC(name, i) \ @@ -135,7 +136,7 @@ eFormatVectorOfUInt8, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##name##_i386 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_DR(reg, i) \ @@ -145,7 +146,7 @@ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_i386 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_GPR_PSEUDO_16(reg16, reg32) \ @@ -157,6 +158,7 @@ lldb_##reg16##_i386 }, \ RegisterContextPOSIX_x86::g_contained_##reg32, \ RegisterContextPOSIX_x86::g_invalidate_##reg32, \ + nullptr, \ } #define DEFINE_GPR_PSEUDO_8H(reg8, reg32) \ @@ -168,6 +170,7 @@ lldb_##reg8##_i386 }, \ RegisterContextPOSIX_x86::g_contained_##reg32, \ RegisterContextPOSIX_x86::g_invalidate_##reg32, \ + nullptr, \ } #define DEFINE_GPR_PSEUDO_8L(reg8, reg32) \ @@ -179,6 +182,7 @@ lldb_##reg8##_i386 }, \ RegisterContextPOSIX_x86::g_contained_##reg32, \ RegisterContextPOSIX_x86::g_invalidate_##reg32, \ + nullptr, \ } static RegisterInfo g_register_infos_i386[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h index 27f2bac22dd5..3fb1e6a5fbef 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h @@ -48,7 +48,7 @@ using namespace loongarch_dwarf; { \ #reg, #alt, 8, GPR_OFFSET(gpr_##reg##_loongarch - gpr_first_loongarch), \ lldb::eEncodingUint, lldb::eFormatHex, \ - GPR64_KIND(gpr_##reg, generic_kind), nullptr, nullptr \ + GPR64_KIND(gpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ } // Defines a 64-bit floating point register @@ -57,21 +57,21 @@ using namespace loongarch_dwarf; { \ #reg, #alt, 8, FPR_OFFSET(fpr_##reg##_loongarch - fpr_first_loongarch), \ lldb::eEncodingUint, lldb::eFormatHex, \ - FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr \ + FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ } #define DEFINE_FCC(reg, generic_kind) \ { \ #reg, nullptr, 1, FCC_OFFSET(fpr_##reg##_loongarch - fpr_fcc0_loongarch), \ lldb::eEncodingUint, lldb::eFormatHex, \ - FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr \ + FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ } #define DEFINE_FCSR(reg, generic_kind) \ { \ #reg, nullptr, 4, FCSR_OFFSET, \ lldb::eEncodingUint, lldb::eFormatHex, \ - FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr \ + FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ } // clang-format on diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h index 60811d65ffc5..0a382032ac8b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h @@ -30,7 +30,7 @@ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ gpr_##reg##_mips64 }, \ - NULL, NULL \ + NULL, NULL, NULL, \ } #define DEFINE_FPR(reg, alt, kind1, kind2, kind3) \ @@ -39,7 +39,7 @@ FPR_OFFSET(reg), eEncodingIEEE754, eFormatFloat, \ {kind1, kind2, kind3, LLDB_INVALID_REGNUM, \ fpr_##reg##_mips64 }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_FPR_INFO(reg, alt, kind1, kind2, kind3) \ @@ -48,7 +48,7 @@ FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, LLDB_INVALID_REGNUM, \ fpr_##reg##_mips64 }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h index 0fd0a526f921..31f79f537911 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_powerpc.h @@ -24,7 +24,7 @@ dwarf_##reg##_powerpc, lldb_kind, \ LLDB_INVALID_REGNUM, \ gpr_##reg##_powerpc }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_FPR(reg, lldb_kind) \ { \ @@ -32,7 +32,7 @@ {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \ lldb_kind, LLDB_INVALID_REGNUM, \ fpr_##reg##_powerpc }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_VMX(reg, lldb_kind) \ { \ @@ -40,7 +40,7 @@ {dwarf_##reg##_powerpc, dwarf_##reg##_powerpc, \ lldb_kind, LLDB_INVALID_REGNUM, \ vmx_##reg##_powerpc }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } // General purpose registers. EH_Frame, DWARF, @@ -125,6 +125,7 @@ LLDB_INVALID_REGNUM, fpr_fpscr_powerpc}, \ NULL, \ NULL, \ + NULL, \ }, \ DEFINE_VMX(v0, LLDB_INVALID_REGNUM), \ DEFINE_VMX(v1, LLDB_INVALID_REGNUM), \ @@ -168,6 +169,7 @@ LLDB_INVALID_REGNUM, vmx_vrsave_powerpc}, \ NULL, \ NULL, \ + NULL, \ }, \ {"vscr", \ NULL, \ @@ -179,6 +181,7 @@ LLDB_INVALID_REGNUM, vmx_vscr_powerpc}, \ NULL, \ NULL, \ + NULL, \ }, static RegisterInfo g_register_infos_powerpc64[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h index 19f2e5627703..e15e1d5fc4a2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h @@ -31,7 +31,7 @@ lldb_kind, \ LLDB_INVALID_REGNUM, \ gpr_##reg##_ppc64 }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_FPR_PPC64(reg, alt, lldb_kind) \ { \ @@ -40,7 +40,7 @@ {ppc64_dwarf::dwarf_##reg##_ppc64, \ ppc64_dwarf::dwarf_##reg##_ppc64, lldb_kind, LLDB_INVALID_REGNUM, \ fpr_##reg##_ppc64 }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_VMX_PPC64(reg, lldb_kind) \ { \ @@ -49,7 +49,7 @@ {ppc64_dwarf::dwarf_##reg##_ppc64, \ ppc64_dwarf::dwarf_##reg##_ppc64, lldb_kind, LLDB_INVALID_REGNUM, \ vmx_##reg##_ppc64 }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } // General purpose registers. @@ -136,6 +136,7 @@ LLDB_INVALID_REGNUM, fpr_fpscr_ppc64}, \ NULL, \ NULL, \ + NULL, \ }, \ DEFINE_VMX_PPC64(vr0, LLDB_INVALID_REGNUM), \ DEFINE_VMX_PPC64(vr1, LLDB_INVALID_REGNUM), \ @@ -179,6 +180,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64}, \ NULL, \ NULL, \ + NULL, \ }, \ {"vrsave", \ NULL, \ @@ -191,6 +193,7 @@ LLDB_INVALID_REGNUM, vmx_vrsave_ppc64}, \ NULL, \ NULL, \ + NULL, \ }, /* */ typedef struct _GPR_PPC64 { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h index f8f8651c856c..18489fb74f86 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h @@ -31,7 +31,7 @@ lldb_kind, \ LLDB_INVALID_REGNUM, \ gpr_##reg##_ppc64le }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_FPR(reg, alt, lldb_kind) \ { \ @@ -39,7 +39,7 @@ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ fpr_##reg##_ppc64le }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_VMX(reg, lldb_kind) \ { \ @@ -48,7 +48,7 @@ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ vmx_##reg##_ppc64le }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_VSX(reg, lldb_kind) \ { \ @@ -57,7 +57,7 @@ {ppc64le_dwarf::dwarf_##reg##_ppc64le, \ ppc64le_dwarf::dwarf_##reg##_ppc64le, lldb_kind, LLDB_INVALID_REGNUM, \ vsx_##reg##_ppc64le }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } // General purpose registers. @@ -147,6 +147,7 @@ LLDB_INVALID_REGNUM, fpr_fpscr_ppc64le}, \ NULL, \ NULL, \ + NULL, \ }, \ DEFINE_VMX(vr0, LLDB_INVALID_REGNUM), \ DEFINE_VMX(vr1, LLDB_INVALID_REGNUM), \ @@ -190,6 +191,7 @@ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, vmx_vscr_ppc64le}, \ NULL, \ NULL, \ + NULL, \ }, \ {"vrsave", \ NULL, \ @@ -202,6 +204,7 @@ LLDB_INVALID_REGNUM, vmx_vrsave_ppc64le}, \ NULL, \ NULL, \ + NULL, \ }, \ DEFINE_VSX(vs0, LLDB_INVALID_REGNUM), \ DEFINE_VSX(vs1, LLDB_INVALID_REGNUM), \ diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h index 331155eab32f..720d900c7b97 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv64.h @@ -42,6 +42,9 @@ using namespace riscv_dwarf; // FPR register kinds array for vector registers #define FPR64_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) +// VPR register kinds array for vector registers +#define VPR_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) + // Defines a 64-bit general purpose register #define DEFINE_GPR64(reg, generic_kind) DEFINE_GPR64_ALT(reg, reg, generic_kind) @@ -50,7 +53,7 @@ using namespace riscv_dwarf; { \ #reg, #alt, 8, GPR_OFFSET(gpr_##reg##_riscv - gpr_first_riscv), \ lldb::eEncodingUint, lldb::eFormatHex, \ - GPR64_KIND(gpr_##reg, generic_kind), nullptr, nullptr \ + GPR64_KIND(gpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ } #define DEFINE_FPR64(reg, generic_kind) DEFINE_FPR64_ALT(reg, reg, generic_kind) @@ -61,7 +64,17 @@ using namespace riscv_dwarf; { \ #reg, #alt, size, FPR_OFFSET(fpr_##reg##_riscv - fpr_first_riscv), \ lldb::eEncodingUint, lldb::eFormatHex, \ - FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr \ + FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \ + } + +#define DEFINE_VPR(reg, generic_kind) DEFINE_VPR_ALT(reg, reg, generic_kind) + +// Defines a scalable vector register, with default size 128 bits +// The byte offset 0 is a placeholder, which should be corrected at runtime. +#define DEFINE_VPR_ALT(reg, alt, generic_kind) \ + { \ + #reg, #alt, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \ + VPR_KIND(vpr_##reg, generic_kind), nullptr, nullptr, nullptr \ } // clang-format on @@ -135,6 +148,39 @@ static lldb_private::RegisterInfo g_register_infos_riscv64_le[] = { DEFINE_FPR64_ALT(ft10, f30, LLDB_INVALID_REGNUM), DEFINE_FPR64_ALT(ft11, f31, LLDB_INVALID_REGNUM), DEFINE_FPR_ALT(fcsr, nullptr, 4, LLDB_INVALID_REGNUM), + + DEFINE_VPR(v0, LLDB_INVALID_REGNUM), + DEFINE_VPR(v1, LLDB_INVALID_REGNUM), + DEFINE_VPR(v2, LLDB_INVALID_REGNUM), + DEFINE_VPR(v3, LLDB_INVALID_REGNUM), + DEFINE_VPR(v4, LLDB_INVALID_REGNUM), + DEFINE_VPR(v5, LLDB_INVALID_REGNUM), + DEFINE_VPR(v6, LLDB_INVALID_REGNUM), + DEFINE_VPR(v7, LLDB_INVALID_REGNUM), + DEFINE_VPR(v8, LLDB_INVALID_REGNUM), + DEFINE_VPR(v9, LLDB_INVALID_REGNUM), + DEFINE_VPR(v10, LLDB_INVALID_REGNUM), + DEFINE_VPR(v11, LLDB_INVALID_REGNUM), + DEFINE_VPR(v12, LLDB_INVALID_REGNUM), + DEFINE_VPR(v13, LLDB_INVALID_REGNUM), + DEFINE_VPR(v14, LLDB_INVALID_REGNUM), + DEFINE_VPR(v15, LLDB_INVALID_REGNUM), + DEFINE_VPR(v16, LLDB_INVALID_REGNUM), + DEFINE_VPR(v17, LLDB_INVALID_REGNUM), + DEFINE_VPR(v18, LLDB_INVALID_REGNUM), + DEFINE_VPR(v19, LLDB_INVALID_REGNUM), + DEFINE_VPR(v20, LLDB_INVALID_REGNUM), + DEFINE_VPR(v21, LLDB_INVALID_REGNUM), + DEFINE_VPR(v22, LLDB_INVALID_REGNUM), + DEFINE_VPR(v23, LLDB_INVALID_REGNUM), + DEFINE_VPR(v24, LLDB_INVALID_REGNUM), + DEFINE_VPR(v25, LLDB_INVALID_REGNUM), + DEFINE_VPR(v26, LLDB_INVALID_REGNUM), + DEFINE_VPR(v27, LLDB_INVALID_REGNUM), + DEFINE_VPR(v28, LLDB_INVALID_REGNUM), + DEFINE_VPR(v29, LLDB_INVALID_REGNUM), + DEFINE_VPR(v30, LLDB_INVALID_REGNUM), + DEFINE_VPR(v31, LLDB_INVALID_REGNUM), }; #endif // DECLARE_REGISTER_INFOS_RISCV64_STRUCT diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h index 65878b04eed8..7b5f204ebbad 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h @@ -27,7 +27,7 @@ #name, alt, size, offset, eEncodingUint, eFormatHex, \ {dwarf_##name##_s390x, dwarf_##name##_s390x, generic, \ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_GPR_NODWARF(name, size, offset, alt, generic) \ @@ -35,7 +35,7 @@ #name, alt, size, offset, eEncodingUint, eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, generic, \ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_FPR(name, size, offset) \ @@ -43,7 +43,7 @@ #name, NULL, size, offset, eEncodingUint, eFormatHex, \ {dwarf_##name##_s390x, dwarf_##name##_s390x, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } #define DEFINE_FPR_NODWARF(name, size, offset) \ @@ -51,7 +51,7 @@ #name, NULL, size, offset, eEncodingUint, eFormatHex, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##name##_s390x }, \ - NULL, NULL, \ + NULL, NULL, NULL, \ } static RegisterInfo g_register_infos_s390x[] = { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h index 1de67165fb2f..163438158155 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64.h @@ -67,7 +67,7 @@ GPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ lldb_##reg##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ @@ -75,7 +75,7 @@ #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ {kind1, kind2, kind3, kind4, \ lldb_##name##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_FP_ST(reg, i) \ @@ -85,7 +85,7 @@ stmm[i]), eEncodingVector, eFormatVectorOfUInt8, \ {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_st##i##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_FP_MM(reg, i, streg) \ @@ -96,6 +96,7 @@ LLDB_INVALID_REGNUM, lldb_mm##i##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##streg##_64, \ RegisterContextPOSIX_x86::g_invalidate_##streg##_64, \ + nullptr, \ } #define DEFINE_XMM(reg, i) \ @@ -106,7 +107,7 @@ {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_YMM(reg, i) \ @@ -117,7 +118,7 @@ dwarf_##reg##i##h_x86_64, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_BNDR(reg, i) \ @@ -128,7 +129,7 @@ dwarf_##reg##i##_x86_64, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_BNDC(name, i) \ @@ -137,7 +138,7 @@ LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, eFormatVectorOfUInt8, \ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, lldb_##name##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_DR(reg, i) \ @@ -147,7 +148,7 @@ {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ lldb_##reg##i##_x86_64 }, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ @@ -159,6 +160,7 @@ lldb_##reg32##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr, \ } #define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ @@ -170,6 +172,7 @@ lldb_##reg16##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr, \ } #define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ @@ -181,6 +184,7 @@ lldb_##reg8##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr, \ } #define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ @@ -192,6 +196,7 @@ lldb_##reg8##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr \ } #define DEFINE_FPR_32(name, reg, kind1, kind2, kind3, kind4, reg64) \ @@ -200,6 +205,7 @@ {kind1, kind2, kind3, kind4, lldb_##name##_x86_64 }, \ RegisterContextPOSIX_x86::g_contained_##reg64, \ RegisterContextPOSIX_x86::g_invalidate_##reg64, \ + nullptr, \ } // clang-format off diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h new file mode 100644 index 000000000000..39428bdd0a08 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base.h @@ -0,0 +1,480 @@ +//===-- RegisterInfos_x86_64_with_base.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 "RegisterInfos_x86_64_with_base_shared.h" + +// This file is meant to be textually included. Do not #include modular +// headers here. + +// Computes the offset of the given GPR in the user data area. +#define GPR_OFFSET(regname) (LLVM_EXTENSION offsetof(GPR, regname)) + +// Computes the offset of the given FPR in the extended data area. +#define FPR_OFFSET(regname) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, fxsave) + \ + LLVM_EXTENSION offsetof(FXSAVE, regname)) + +// Computes the offset of the YMM register assembled from register halves. +// Based on DNBArchImplX86_64.cpp from debugserver +#define YMM_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, ymmh[0]) + (32 * reg_index)) + +// Guarantees BNDR/BNDC offsets do not overlap with YMM offsets. +#define GDB_REMOTE_OFFSET 128 + +#define BNDR_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxr[reg_index]) + GDB_REMOTE_OFFSET) + +#define BNDC_OFFSET(reg_index) \ + (LLVM_EXTENSION offsetof(UserArea, fpr) + \ + LLVM_EXTENSION offsetof(FPR, xsave) + \ + LLVM_EXTENSION offsetof(XSAVE, mpxc[reg_index]) + GDB_REMOTE_OFFSET) + +#ifdef DECLARE_REGISTER_INFOS_X86_64_STRUCT + +// Number of bytes needed to represent a FPR. +#define FPR_SIZE(reg) sizeof(((FXSAVE *)nullptr)->reg) + +// Number of bytes needed to represent the i'th FP register. +#define FP_SIZE sizeof(((MMSReg *)nullptr)->bytes) + +// Number of bytes needed to represent an XMM register. +#define XMM_SIZE sizeof(XMMReg) + +// Number of bytes needed to represent a YMM register. +#define YMM_SIZE sizeof(YMMReg) + +// Number of bytes needed to represent MPX registers. +#define BNDR_SIZE sizeof(MPXReg) +#define BNDC_SIZE sizeof(MPXCsr) + +#define DR_SIZE sizeof(((DBG *)nullptr)->dr[0]) + +// RegisterKind: EHFrame, DWARF, Generic, Process Plugin, LLDB + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ + eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##reg}, nullptr, \ + nullptr, nullptr, \ + } + +// Note that the size and offset will be updated by platform-specific classes. +#define DEFINE_GPR_WITH_BASE(reg, alt, kind1, kind2, kind3, kind4) \ + { \ + #reg, alt, sizeof(((GPR *)nullptr)->reg), GPR_OFFSET(reg), eEncodingUint, \ + eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##reg}, nullptr, \ + nullptr, nullptr, \ + } + +#define DEFINE_FPR(name, reg, kind1, kind2, kind3, kind4) \ + { \ + #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##name}, nullptr, \ + nullptr, nullptr, \ + } + +#define DEFINE_FP_ST(reg, i) \ + { \ + #reg #i, nullptr, FP_SIZE, LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ + eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_st##i##_x86_64, dwarf_st##i##_x86_64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_st##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_FP_MM(reg, i, streg) \ + { \ + #reg #i, nullptr, sizeof(uint64_t), LLVM_EXTENSION FPR_OFFSET(stmm[i]), \ + eEncodingUint, eFormatHex, \ + {dwarf_mm##i##_x86_64, dwarf_mm##i##_x86_64, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_mm##i}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##streg##_64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##streg##_64, \ + nullptr, \ + } + +#define DEFINE_XMM(reg, i) \ + { \ + #reg #i, nullptr, XMM_SIZE, LLVM_EXTENSION FPR_OFFSET(reg[i]), \ + eEncodingVector, eFormatVectorOfUInt8, \ + {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_YMM(reg, i) \ + { \ + #reg #i, nullptr, YMM_SIZE, LLVM_EXTENSION YMM_OFFSET(i), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {dwarf_##reg##i##h_x86_64, dwarf_##reg##i##h_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDR(reg, i) \ + { \ + #reg #i, nullptr, BNDR_SIZE, LLVM_EXTENSION BNDR_OFFSET(i), \ + eEncodingVector, eFormatVectorOfUInt64, \ + {dwarf_##reg##i##_x86_64, dwarf_##reg##i##_x86_64, \ + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_BNDC(name, i) \ + { \ + #name, nullptr, BNDC_SIZE, LLVM_EXTENSION BNDC_OFFSET(i), eEncodingVector, \ + eFormatVectorOfUInt8, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##name}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_DR(reg, i) \ + { \ + #reg #i, nullptr, DR_SIZE, DR_OFFSET(i), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg##i}, \ + nullptr, nullptr, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_32(reg32, reg64) \ + { \ + #reg32, nullptr, 4, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg32}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_16(reg16, reg64) \ + { \ + #reg16, nullptr, 2, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg16}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8H(reg8, reg64) \ + { \ + #reg8, nullptr, 1, GPR_OFFSET(reg64) + 1, eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg8}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +#define DEFINE_GPR_PSEUDO_8L(reg8, reg64) \ + { \ + #reg8, nullptr, 1, GPR_OFFSET(reg64), eEncodingUint, eFormatHex, \ + {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \ + LLDB_INVALID_REGNUM, x86_64_with_base::lldb_##reg8}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr \ + } + +#define DEFINE_FPR_32(name, reg, kind1, kind2, kind3, kind4, reg64) \ + { \ + #name, nullptr, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, eFormatHex, \ + {kind1, kind2, kind3, kind4, x86_64_with_base::lldb_##name}, \ + RegisterInfos_x86_64_with_base_shared::g_contained_##reg64, \ + RegisterInfos_x86_64_with_base_shared::g_invalidate_##reg64, nullptr, \ + } + +// clang-format off +static RegisterInfo g_register_infos_x86_64_with_base[] = { +// General purpose registers EH_Frame DWARF Generic Process Plugin +// =========================== ================== ================ ========================= ==================== + DEFINE_GPR(rax, nullptr, dwarf_rax_x86_64, dwarf_rax_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbx, nullptr, dwarf_rbx_x86_64, dwarf_rbx_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rcx, nullptr, dwarf_rcx_x86_64, dwarf_rcx_x86_64, LLDB_REGNUM_GENERIC_ARG4, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdx, nullptr, dwarf_rdx_x86_64, dwarf_rdx_x86_64, LLDB_REGNUM_GENERIC_ARG3, LLDB_INVALID_REGNUM), + DEFINE_GPR(rdi, nullptr, dwarf_rdi_x86_64, dwarf_rdi_x86_64, LLDB_REGNUM_GENERIC_ARG1, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsi, nullptr, dwarf_rsi_x86_64, dwarf_rsi_x86_64, LLDB_REGNUM_GENERIC_ARG2, LLDB_INVALID_REGNUM), + DEFINE_GPR(rbp, nullptr, dwarf_rbp_x86_64, dwarf_rbp_x86_64, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM), + DEFINE_GPR(rsp, nullptr, dwarf_rsp_x86_64, dwarf_rsp_x86_64, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM), + DEFINE_GPR(r8, nullptr, dwarf_r8_x86_64, dwarf_r8_x86_64, LLDB_REGNUM_GENERIC_ARG5, LLDB_INVALID_REGNUM), + DEFINE_GPR(r9, nullptr, dwarf_r9_x86_64, dwarf_r9_x86_64, LLDB_REGNUM_GENERIC_ARG6, LLDB_INVALID_REGNUM), + DEFINE_GPR(r10, nullptr, dwarf_r10_x86_64, dwarf_r10_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r11, nullptr, dwarf_r11_x86_64, dwarf_r11_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r12, nullptr, dwarf_r12_x86_64, dwarf_r12_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r13, nullptr, dwarf_r13_x86_64, dwarf_r13_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r14, nullptr, dwarf_r14_x86_64, dwarf_r14_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(r15, nullptr, dwarf_r15_x86_64, dwarf_r15_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(rip, nullptr, dwarf_rip_x86_64, dwarf_rip_x86_64, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM), + DEFINE_GPR(rflags, nullptr, dwarf_rflags_x86_64, dwarf_rflags_x86_64, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM), + DEFINE_GPR(cs, nullptr, dwarf_cs_x86_64, dwarf_cs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs, nullptr, dwarf_fs_x86_64, dwarf_fs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs, nullptr, dwarf_gs_x86_64, dwarf_gs_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ss, nullptr, dwarf_ss_x86_64, dwarf_ss_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(fs_base, nullptr, dwarf_fs_base_x86_64, dwarf_fs_base_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(gs_base, nullptr, dwarf_gs_base_x86_64, dwarf_gs_base_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(ds, nullptr, dwarf_ds_x86_64, dwarf_ds_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_GPR(es, nullptr, dwarf_es_x86_64, dwarf_es_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + DEFINE_GPR_PSEUDO_32(eax, rax), DEFINE_GPR_PSEUDO_32(ebx, rbx), + DEFINE_GPR_PSEUDO_32(ecx, rcx), DEFINE_GPR_PSEUDO_32(edx, rdx), + DEFINE_GPR_PSEUDO_32(edi, rdi), DEFINE_GPR_PSEUDO_32(esi, rsi), + DEFINE_GPR_PSEUDO_32(ebp, rbp), DEFINE_GPR_PSEUDO_32(esp, rsp), + DEFINE_GPR_PSEUDO_32(r8d, r8), DEFINE_GPR_PSEUDO_32(r9d, r9), + DEFINE_GPR_PSEUDO_32(r10d, r10), DEFINE_GPR_PSEUDO_32(r11d, r11), + DEFINE_GPR_PSEUDO_32(r12d, r12), DEFINE_GPR_PSEUDO_32(r13d, r13), + DEFINE_GPR_PSEUDO_32(r14d, r14), DEFINE_GPR_PSEUDO_32(r15d, r15), + DEFINE_GPR_PSEUDO_16(ax, rax), DEFINE_GPR_PSEUDO_16(bx, rbx), + DEFINE_GPR_PSEUDO_16(cx, rcx), DEFINE_GPR_PSEUDO_16(dx, rdx), + DEFINE_GPR_PSEUDO_16(di, rdi), DEFINE_GPR_PSEUDO_16(si, rsi), + DEFINE_GPR_PSEUDO_16(bp, rbp), DEFINE_GPR_PSEUDO_16(sp, rsp), + DEFINE_GPR_PSEUDO_16(r8w, r8), DEFINE_GPR_PSEUDO_16(r9w, r9), + DEFINE_GPR_PSEUDO_16(r10w, r10), DEFINE_GPR_PSEUDO_16(r11w, r11), + DEFINE_GPR_PSEUDO_16(r12w, r12), DEFINE_GPR_PSEUDO_16(r13w, r13), + DEFINE_GPR_PSEUDO_16(r14w, r14), DEFINE_GPR_PSEUDO_16(r15w, r15), + DEFINE_GPR_PSEUDO_8H(ah, rax), DEFINE_GPR_PSEUDO_8H(bh, rbx), + DEFINE_GPR_PSEUDO_8H(ch, rcx), DEFINE_GPR_PSEUDO_8H(dh, rdx), + DEFINE_GPR_PSEUDO_8L(al, rax), DEFINE_GPR_PSEUDO_8L(bl, rbx), + DEFINE_GPR_PSEUDO_8L(cl, rcx), DEFINE_GPR_PSEUDO_8L(dl, rdx), + DEFINE_GPR_PSEUDO_8L(dil, rdi), DEFINE_GPR_PSEUDO_8L(sil, rsi), + DEFINE_GPR_PSEUDO_8L(bpl, rbp), DEFINE_GPR_PSEUDO_8L(spl, rsp), + DEFINE_GPR_PSEUDO_8L(r8l, r8), DEFINE_GPR_PSEUDO_8L(r9l, r9), + DEFINE_GPR_PSEUDO_8L(r10l, r10), DEFINE_GPR_PSEUDO_8L(r11l, r11), + DEFINE_GPR_PSEUDO_8L(r12l, r12), DEFINE_GPR_PSEUDO_8L(r13l, r13), + DEFINE_GPR_PSEUDO_8L(r14l, r14), DEFINE_GPR_PSEUDO_8L(r15l, r15), + +// i387 Floating point registers. EH_frame DWARF Generic Process Plugin reg64 +// ====================================== =============== ================== =================== ==================== ===== + DEFINE_FPR(fctrl, fctrl, dwarf_fctrl_x86_64, dwarf_fctrl_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(fstat, fstat, dwarf_fstat_x86_64, dwarf_fstat_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(ftag, ftag, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(fop, fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR_32(fiseg, ptr.i386_.fiseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip), + DEFINE_FPR_32(fioff, ptr.i386_.fioff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fip), + DEFINE_FPR(fip, ptr.x86_64.fip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR_32(foseg, ptr.i386_.foseg, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp), + DEFINE_FPR_32(fooff, ptr.i386_.fooff, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, fdp), + DEFINE_FPR(fdp, ptr.x86_64.fdp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(mxcsr, mxcsr, dwarf_mxcsr_x86_64, dwarf_mxcsr_x86_64, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + DEFINE_FPR(mxcsrmask, mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM), + + // FP registers. + DEFINE_FP_ST(st, 0), DEFINE_FP_ST(st, 1), DEFINE_FP_ST(st, 2), + DEFINE_FP_ST(st, 3), DEFINE_FP_ST(st, 4), DEFINE_FP_ST(st, 5), + DEFINE_FP_ST(st, 6), DEFINE_FP_ST(st, 7), + + DEFINE_FP_MM(mm, 0, st0), DEFINE_FP_MM(mm, 1, st1), + DEFINE_FP_MM(mm, 2, st2), DEFINE_FP_MM(mm, 3, st3), + DEFINE_FP_MM(mm, 4, st4), DEFINE_FP_MM(mm, 5, st5), + DEFINE_FP_MM(mm, 6, st6), DEFINE_FP_MM(mm, 7, st7), + + // XMM registers + DEFINE_XMM(xmm, 0), DEFINE_XMM(xmm, 1), DEFINE_XMM(xmm, 2), + DEFINE_XMM(xmm, 3), DEFINE_XMM(xmm, 4), DEFINE_XMM(xmm, 5), + DEFINE_XMM(xmm, 6), DEFINE_XMM(xmm, 7), DEFINE_XMM(xmm, 8), + DEFINE_XMM(xmm, 9), DEFINE_XMM(xmm, 10), DEFINE_XMM(xmm, 11), + DEFINE_XMM(xmm, 12), DEFINE_XMM(xmm, 13), DEFINE_XMM(xmm, 14), + DEFINE_XMM(xmm, 15), + + // Copy of YMM registers assembled from xmm and ymmh + DEFINE_YMM(ymm, 0), DEFINE_YMM(ymm, 1), DEFINE_YMM(ymm, 2), + DEFINE_YMM(ymm, 3), DEFINE_YMM(ymm, 4), DEFINE_YMM(ymm, 5), + DEFINE_YMM(ymm, 6), DEFINE_YMM(ymm, 7), DEFINE_YMM(ymm, 8), + DEFINE_YMM(ymm, 9), DEFINE_YMM(ymm, 10), DEFINE_YMM(ymm, 11), + DEFINE_YMM(ymm, 12), DEFINE_YMM(ymm, 13), DEFINE_YMM(ymm, 14), + DEFINE_YMM(ymm, 15), + + // MPX registers + DEFINE_BNDR(bnd, 0), + DEFINE_BNDR(bnd, 1), + DEFINE_BNDR(bnd, 2), + DEFINE_BNDR(bnd, 3), + + DEFINE_BNDC(bndcfgu, 0), + DEFINE_BNDC(bndstatus, 1), + + // Debug registers for lldb internal use + DEFINE_DR(dr, 0), DEFINE_DR(dr, 1), DEFINE_DR(dr, 2), DEFINE_DR(dr, 3), + DEFINE_DR(dr, 4), DEFINE_DR(dr, 5), DEFINE_DR(dr, 6), DEFINE_DR(dr, 7)}; + +// clang-format on + +static_assert( + (sizeof(g_register_infos_x86_64_with_base) / + sizeof(g_register_infos_x86_64_with_base[0])) == + x86_64_with_base::k_num_registers, + "g_register_infos_x86_64_with_base has wrong number of register infos"); + +#undef FPR_SIZE +#undef FP_SIZE +#undef XMM_SIZE +#undef YMM_SIZE +#undef DEFINE_GPR +#undef DEFINE_FPR +#undef DEFINE_FP +#undef DEFINE_XMM +#undef DEFINE_YMM +#undef DEFINE_BNDR +#undef DEFINE_BNDC +#undef DEFINE_DR +#undef DEFINE_GPR_PSEUDO_32 +#undef DEFINE_GPR_PSEUDO_16 +#undef DEFINE_GPR_PSEUDO_8H +#undef DEFINE_GPR_PSEUDO_8L + +#endif // DECLARE_REGISTER_INFOS_X86_64_STRUCT + +#ifdef UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + +#define UPDATE_GPR_INFO(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64); \ + } while (false); + +#define UPDATE_GPR_INFO_8H(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = GPR_OFFSET(reg64) + 1; \ + } while (false); + +#define UPDATE_FPR_INFO(reg, reg64) \ + do { \ + g_register_infos[lldb_##reg##_i386].byte_offset = FPR_OFFSET(reg64); \ + } while (false); + +#define UPDATE_FP_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(stmm[i]); \ + } while (false); + +#define UPDATE_XMM_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = FPR_OFFSET(reg[i]); \ + } while (false); + +#define UPDATE_YMM_INFO(reg, i) \ + do { \ + g_register_infos[lldb_##reg##i##_i386].byte_offset = YMM_OFFSET(i); \ + } while (false); + +#define UPDATE_DR_INFO(reg_index) \ + do { \ + g_register_infos[lldb_dr##reg_index##_i386].byte_offset = \ + DR_OFFSET(reg_index); \ + } while (false); + +// Update the register offsets +UPDATE_GPR_INFO(eax, rax); +UPDATE_GPR_INFO(ebx, rbx); +UPDATE_GPR_INFO(ecx, rcx); +UPDATE_GPR_INFO(edx, rdx); +UPDATE_GPR_INFO(edi, rdi); +UPDATE_GPR_INFO(esi, rsi); +UPDATE_GPR_INFO(ebp, rbp); +UPDATE_GPR_INFO(esp, rsp); +UPDATE_GPR_INFO(eip, rip); +UPDATE_GPR_INFO(eflags, rflags); +UPDATE_GPR_INFO(cs, cs); +UPDATE_GPR_INFO(fs, fs); +UPDATE_GPR_INFO(gs, gs); +UPDATE_GPR_INFO(ss, ss); +UPDATE_GPR_INFO(ds, ds); +UPDATE_GPR_INFO(es, es); + +UPDATE_GPR_INFO(ax, rax); +UPDATE_GPR_INFO(bx, rbx); +UPDATE_GPR_INFO(cx, rcx); +UPDATE_GPR_INFO(dx, rdx); +UPDATE_GPR_INFO(di, rdi); +UPDATE_GPR_INFO(si, rsi); +UPDATE_GPR_INFO(bp, rbp); +UPDATE_GPR_INFO(sp, rsp); +UPDATE_GPR_INFO_8H(ah, rax); +UPDATE_GPR_INFO_8H(bh, rbx); +UPDATE_GPR_INFO_8H(ch, rcx); +UPDATE_GPR_INFO_8H(dh, rdx); +UPDATE_GPR_INFO(al, rax); +UPDATE_GPR_INFO(bl, rbx); +UPDATE_GPR_INFO(cl, rcx); +UPDATE_GPR_INFO(dl, rdx); + +UPDATE_FPR_INFO(fctrl, fctrl); +UPDATE_FPR_INFO(fstat, fstat); +UPDATE_FPR_INFO(ftag, ftag); +UPDATE_FPR_INFO(fop, fop); +UPDATE_FPR_INFO(fiseg, ptr.i386_.fiseg); +UPDATE_FPR_INFO(fioff, ptr.i386_.fioff); +UPDATE_FPR_INFO(fooff, ptr.i386_.fooff); +UPDATE_FPR_INFO(foseg, ptr.i386_.foseg); +UPDATE_FPR_INFO(mxcsr, mxcsr); +UPDATE_FPR_INFO(mxcsrmask, mxcsrmask); + +UPDATE_FP_INFO(st, 0); +UPDATE_FP_INFO(st, 1); +UPDATE_FP_INFO(st, 2); +UPDATE_FP_INFO(st, 3); +UPDATE_FP_INFO(st, 4); +UPDATE_FP_INFO(st, 5); +UPDATE_FP_INFO(st, 6); +UPDATE_FP_INFO(st, 7); +UPDATE_FP_INFO(mm, 0); +UPDATE_FP_INFO(mm, 1); +UPDATE_FP_INFO(mm, 2); +UPDATE_FP_INFO(mm, 3); +UPDATE_FP_INFO(mm, 4); +UPDATE_FP_INFO(mm, 5); +UPDATE_FP_INFO(mm, 6); +UPDATE_FP_INFO(mm, 7); + +UPDATE_XMM_INFO(xmm, 0); +UPDATE_XMM_INFO(xmm, 1); +UPDATE_XMM_INFO(xmm, 2); +UPDATE_XMM_INFO(xmm, 3); +UPDATE_XMM_INFO(xmm, 4); +UPDATE_XMM_INFO(xmm, 5); +UPDATE_XMM_INFO(xmm, 6); +UPDATE_XMM_INFO(xmm, 7); + +UPDATE_YMM_INFO(ymm, 0); +UPDATE_YMM_INFO(ymm, 1); +UPDATE_YMM_INFO(ymm, 2); +UPDATE_YMM_INFO(ymm, 3); +UPDATE_YMM_INFO(ymm, 4); +UPDATE_YMM_INFO(ymm, 5); +UPDATE_YMM_INFO(ymm, 6); +UPDATE_YMM_INFO(ymm, 7); + +UPDATE_DR_INFO(0); +UPDATE_DR_INFO(1); +UPDATE_DR_INFO(2); +UPDATE_DR_INFO(3); +UPDATE_DR_INFO(4); +UPDATE_DR_INFO(5); +UPDATE_DR_INFO(6); +UPDATE_DR_INFO(7); + +#undef UPDATE_GPR_INFO +#undef UPDATE_GPR_INFO_8H +#undef UPDATE_FPR_INFO +#undef UPDATE_FP_INFO +#undef UPDATE_XMM_INFO +#undef UPDATE_YMM_INFO +#undef UPDATE_DR_INFO + +#endif // UPDATE_REGISTER_INFOS_I386_STRUCT_WITH_X86_64_OFFSETS + +#undef GPR_OFFSET +#undef FPR_OFFSET +#undef YMM_OFFSET diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp new file mode 100644 index 000000000000..7b2d64de230f --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.cpp @@ -0,0 +1,321 @@ +//===-- RegisterInfos_x86_64_with_base_shared.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 "RegisterInfos_x86_64_with_base_shared.h" + +#include "lldb/lldb-defines.h" +#include <mutex> + +using namespace lldb; + +namespace lldb_private { + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_eax[] = { + lldb_eax_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ebx[] = { + lldb_ebx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ecx[] = { + lldb_ecx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_edx[] = { + lldb_edx_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_edi[] = { + lldb_edi_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_esi[] = { + lldb_esi_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_ebp[] = { + lldb_ebp_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_esp[] = { + lldb_esp_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_eax[] = { + lldb_eax_i386, lldb_ax_i386, lldb_ah_i386, lldb_al_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ebx[] = { + lldb_ebx_i386, lldb_bx_i386, lldb_bh_i386, lldb_bl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ecx[] = { + lldb_ecx_i386, lldb_cx_i386, lldb_ch_i386, lldb_cl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_edx[] = { + lldb_edx_i386, lldb_dx_i386, lldb_dh_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_edi[] = { + lldb_edi_i386, lldb_di_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_esi[] = { + lldb_esi_i386, lldb_si_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_ebp[] = { + lldb_ebp_i386, lldb_bp_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_esp[] = { + lldb_esp_i386, lldb_sp_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rax[] = { + x86_64_with_base::lldb_rax, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rbx[] = { + x86_64_with_base::lldb_rbx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rcx[] = { + x86_64_with_base::lldb_rcx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rdx[] = { + x86_64_with_base::lldb_rdx, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rdi[] = { + x86_64_with_base::lldb_rdi, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rsi[] = { + x86_64_with_base::lldb_rsi, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rbp[] = { + x86_64_with_base::lldb_rbp, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_rsp[] = { + x86_64_with_base::lldb_rsp, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r8[] = { + x86_64_with_base::lldb_r8, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r9[] = { + x86_64_with_base::lldb_r9, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r10[] = { + x86_64_with_base::lldb_r10, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r11[] = { + x86_64_with_base::lldb_r11, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r12[] = { + x86_64_with_base::lldb_r12, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r13[] = { + x86_64_with_base::lldb_r13, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r14[] = { + x86_64_with_base::lldb_r14, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_r15[] = { + x86_64_with_base::lldb_r15, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rax[] = { + x86_64_with_base::lldb_rax, x86_64_with_base::lldb_eax, + x86_64_with_base::lldb_ax, x86_64_with_base::lldb_ah, + x86_64_with_base::lldb_al, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rbx[] = { + x86_64_with_base::lldb_rbx, x86_64_with_base::lldb_ebx, + x86_64_with_base::lldb_bx, x86_64_with_base::lldb_bh, + x86_64_with_base::lldb_bl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rcx[] = { + x86_64_with_base::lldb_rcx, x86_64_with_base::lldb_ecx, + x86_64_with_base::lldb_cx, x86_64_with_base::lldb_ch, + x86_64_with_base::lldb_cl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rdx[] = { + x86_64_with_base::lldb_rdx, x86_64_with_base::lldb_edx, + x86_64_with_base::lldb_dx, x86_64_with_base::lldb_dh, + x86_64_with_base::lldb_dl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rdi[] = { + x86_64_with_base::lldb_rdi, x86_64_with_base::lldb_edi, + x86_64_with_base::lldb_di, x86_64_with_base::lldb_dil, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rsi[] = { + x86_64_with_base::lldb_rsi, x86_64_with_base::lldb_esi, + x86_64_with_base::lldb_si, x86_64_with_base::lldb_sil, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rbp[] = { + x86_64_with_base::lldb_rbp, x86_64_with_base::lldb_ebp, + x86_64_with_base::lldb_bp, x86_64_with_base::lldb_bpl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_rsp[] = { + x86_64_with_base::lldb_rsp, x86_64_with_base::lldb_esp, + x86_64_with_base::lldb_sp, x86_64_with_base::lldb_spl, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r8[] = { + x86_64_with_base::lldb_r8, x86_64_with_base::lldb_r8d, + x86_64_with_base::lldb_r8w, x86_64_with_base::lldb_r8l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r9[] = { + x86_64_with_base::lldb_r9, x86_64_with_base::lldb_r9d, + x86_64_with_base::lldb_r9w, x86_64_with_base::lldb_r9l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r10[] = { + x86_64_with_base::lldb_r10, x86_64_with_base::lldb_r10d, + x86_64_with_base::lldb_r10w, x86_64_with_base::lldb_r10l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r11[] = { + x86_64_with_base::lldb_r11, x86_64_with_base::lldb_r11d, + x86_64_with_base::lldb_r11w, x86_64_with_base::lldb_r11l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r12[] = { + x86_64_with_base::lldb_r12, x86_64_with_base::lldb_r12d, + x86_64_with_base::lldb_r12w, x86_64_with_base::lldb_r12l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r13[] = { + x86_64_with_base::lldb_r13, x86_64_with_base::lldb_r13d, + x86_64_with_base::lldb_r13w, x86_64_with_base::lldb_r13l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r14[] = { + x86_64_with_base::lldb_r14, x86_64_with_base::lldb_r14d, + x86_64_with_base::lldb_r14w, x86_64_with_base::lldb_r14l, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_r15[] = { + x86_64_with_base::lldb_r15, x86_64_with_base::lldb_r15d, + x86_64_with_base::lldb_r15w, x86_64_with_base::lldb_r15l, + LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_fip[] = { + x86_64_with_base::lldb_fip, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_fdp[] = { + x86_64_with_base::lldb_fdp, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_fip[] = { + x86_64_with_base::lldb_fip, x86_64_with_base::lldb_fioff, + x86_64_with_base::lldb_fiseg, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_fdp[] = { + x86_64_with_base::lldb_fdp, x86_64_with_base::lldb_fooff, + x86_64_with_base::lldb_foseg, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st0_32[] = { + lldb_st0_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st1_32[] = { + lldb_st1_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st2_32[] = { + lldb_st2_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st3_32[] = { + lldb_st3_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st4_32[] = { + lldb_st4_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st5_32[] = { + lldb_st5_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st6_32[] = { + lldb_st6_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st7_32[] = { + lldb_st7_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st0_32[] = { + lldb_st0_i386, lldb_mm0_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st1_32[] = { + lldb_st1_i386, lldb_mm1_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st2_32[] = { + lldb_st2_i386, lldb_mm2_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st3_32[] = { + lldb_st3_i386, lldb_mm3_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st4_32[] = { + lldb_st4_i386, lldb_mm4_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st5_32[] = { + lldb_st5_i386, lldb_mm5_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st6_32[] = { + lldb_st6_i386, lldb_mm6_i386, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st7_32[] = { + lldb_st7_i386, lldb_mm7_i386, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st0_64[] = { + x86_64_with_base::lldb_st0, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st1_64[] = { + x86_64_with_base::lldb_st1, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st2_64[] = { + x86_64_with_base::lldb_st2, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st3_64[] = { + x86_64_with_base::lldb_st3, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st4_64[] = { + x86_64_with_base::lldb_st4, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st5_64[] = { + x86_64_with_base::lldb_st5, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st6_64[] = { + x86_64_with_base::lldb_st6, LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_contained_st7_64[] = { + x86_64_with_base::lldb_st7, LLDB_INVALID_REGNUM}; + +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st0_64[] = { + x86_64_with_base::lldb_st0, x86_64_with_base::lldb_mm0, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st1_64[] = { + x86_64_with_base::lldb_st1, x86_64_with_base::lldb_mm1, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st2_64[] = { + x86_64_with_base::lldb_st2, x86_64_with_base::lldb_mm2, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st3_64[] = { + x86_64_with_base::lldb_st3, x86_64_with_base::lldb_mm3, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st4_64[] = { + x86_64_with_base::lldb_st4, x86_64_with_base::lldb_mm4, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st5_64[] = { + x86_64_with_base::lldb_st5, x86_64_with_base::lldb_mm5, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st6_64[] = { + x86_64_with_base::lldb_st6, x86_64_with_base::lldb_mm6, + LLDB_INVALID_REGNUM}; +uint32_t RegisterInfos_x86_64_with_base_shared::g_invalidate_st7_64[] = { + x86_64_with_base::lldb_st7, x86_64_with_base::lldb_mm7, + LLDB_INVALID_REGNUM}; + +RegInfo &GetRegInfoShared(llvm::Triple::ArchType arch_type, bool with_base) { + static std::once_flag once_flag_x86, once_flag_x86_64, + once_flag_x86_64_with_base; + static RegInfo reg_info_x86, reg_info_x86_64, reg_info_x86_64_with_base, reg_info_invalid; + + switch (arch_type) { + case llvm::Triple::x86: + std::call_once(once_flag_x86, []() { + reg_info_x86.num_registers = k_num_registers_i386; + reg_info_x86.num_gpr_registers = k_num_gpr_registers_i386; + reg_info_x86.num_fpr_registers = k_num_fpr_registers_i386; + reg_info_x86.num_avx_registers = k_num_avx_registers_i386; + reg_info_x86.last_gpr = k_last_gpr_i386; + reg_info_x86.first_fpr = k_first_fpr_i386; + reg_info_x86.last_fpr = k_last_fpr_i386; + reg_info_x86.first_st = lldb_st0_i386; + reg_info_x86.last_st = lldb_st7_i386; + reg_info_x86.first_mm = lldb_mm0_i386; + reg_info_x86.last_mm = lldb_mm7_i386; + reg_info_x86.first_xmm = lldb_xmm0_i386; + reg_info_x86.last_xmm = lldb_xmm7_i386; + reg_info_x86.first_ymm = lldb_ymm0_i386; + reg_info_x86.last_ymm = lldb_ymm7_i386; + reg_info_x86.first_dr = lldb_dr0_i386; + reg_info_x86.gpr_flags = lldb_eflags_i386; + }); + + return reg_info_x86; + case llvm::Triple::x86_64: + if (with_base) { + std::call_once(once_flag_x86_64_with_base, []() { + reg_info_x86_64_with_base.num_registers = + x86_64_with_base::k_num_registers; + reg_info_x86_64_with_base.num_gpr_registers = + x86_64_with_base::k_num_gpr_registers; + reg_info_x86_64_with_base.num_fpr_registers = + x86_64_with_base::k_num_fpr_registers; + reg_info_x86_64_with_base.num_avx_registers = + x86_64_with_base::k_num_avx_registers; + reg_info_x86_64_with_base.last_gpr = x86_64_with_base::k_last_gpr; + reg_info_x86_64_with_base.first_fpr = x86_64_with_base::k_first_fpr; + reg_info_x86_64_with_base.last_fpr = x86_64_with_base::k_last_fpr; + reg_info_x86_64_with_base.first_st = x86_64_with_base::lldb_st0; + reg_info_x86_64_with_base.last_st = x86_64_with_base::lldb_st7; + reg_info_x86_64_with_base.first_mm = x86_64_with_base::lldb_mm0; + reg_info_x86_64_with_base.last_mm = x86_64_with_base::lldb_mm7; + reg_info_x86_64_with_base.first_xmm = x86_64_with_base::lldb_xmm0; + reg_info_x86_64_with_base.last_xmm = x86_64_with_base::lldb_xmm15; + reg_info_x86_64_with_base.first_ymm = x86_64_with_base::lldb_ymm0; + reg_info_x86_64_with_base.last_ymm = x86_64_with_base::lldb_ymm15; + reg_info_x86_64_with_base.first_dr = x86_64_with_base::lldb_dr0; + reg_info_x86_64_with_base.gpr_flags = x86_64_with_base::lldb_rflags; + }); + + return reg_info_x86_64_with_base; + } else { + std::call_once(once_flag_x86_64, []() { + reg_info_x86_64.num_registers = k_num_registers_x86_64; + reg_info_x86_64.num_gpr_registers = k_num_gpr_registers_x86_64; + reg_info_x86_64.num_fpr_registers = k_num_fpr_registers_x86_64; + reg_info_x86_64.num_avx_registers = k_num_avx_registers_x86_64; + reg_info_x86_64.last_gpr = k_last_gpr_x86_64; + reg_info_x86_64.first_fpr = k_first_fpr_x86_64; + reg_info_x86_64.last_fpr = k_last_fpr_x86_64; + reg_info_x86_64.first_st = lldb_st0_x86_64; + reg_info_x86_64.last_st = lldb_st7_x86_64; + reg_info_x86_64.first_mm = lldb_mm0_x86_64; + reg_info_x86_64.last_mm = lldb_mm7_x86_64; + reg_info_x86_64.first_xmm = lldb_xmm0_x86_64; + reg_info_x86_64.last_xmm = lldb_xmm15_x86_64; + reg_info_x86_64.first_ymm = lldb_ymm0_x86_64; + reg_info_x86_64.last_ymm = lldb_ymm15_x86_64; + reg_info_x86_64.first_dr = lldb_dr0_x86_64; + reg_info_x86_64.gpr_flags = lldb_rflags_x86_64; + }); + return reg_info_x86_64; + } + default: + assert(false && "Unhandled target architecture."); + return reg_info_invalid; + } +} + +} // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h new file mode 100644 index 000000000000..5e4406c1fa27 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/RegisterInfos_x86_64_with_base_shared.h @@ -0,0 +1,142 @@ +//===-- RegisterInfos_x86_64_with_base_shared.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 "Plugins/Process/Utility/lldb-x86-register-enums.h" +#include <stdint.h> + +#ifndef lldb_RegisterInfos_x86_64_with_base_shared_h +#define lldb_RegisterInfos_x86_64_with_base_shared_h + +#include "Plugins/Process/Utility/NativeRegisterContextRegisterInfo.h" + +namespace lldb_private { + +struct RegisterInfos_x86_64_with_base_shared { + static uint32_t g_contained_eax[]; + static uint32_t g_contained_ebx[]; + static uint32_t g_contained_ecx[]; + static uint32_t g_contained_edx[]; + static uint32_t g_contained_edi[]; + static uint32_t g_contained_esi[]; + static uint32_t g_contained_ebp[]; + static uint32_t g_contained_esp[]; + + static uint32_t g_invalidate_eax[]; + static uint32_t g_invalidate_ebx[]; + static uint32_t g_invalidate_ecx[]; + static uint32_t g_invalidate_edx[]; + static uint32_t g_invalidate_edi[]; + static uint32_t g_invalidate_esi[]; + static uint32_t g_invalidate_ebp[]; + static uint32_t g_invalidate_esp[]; + + static uint32_t g_contained_rax[]; + static uint32_t g_contained_rbx[]; + static uint32_t g_contained_rcx[]; + static uint32_t g_contained_rdx[]; + static uint32_t g_contained_rdi[]; + static uint32_t g_contained_rsi[]; + static uint32_t g_contained_rbp[]; + static uint32_t g_contained_rsp[]; + static uint32_t g_contained_r8[]; + static uint32_t g_contained_r9[]; + static uint32_t g_contained_r10[]; + static uint32_t g_contained_r11[]; + static uint32_t g_contained_r12[]; + static uint32_t g_contained_r13[]; + static uint32_t g_contained_r14[]; + static uint32_t g_contained_r15[]; + + static uint32_t g_invalidate_rax[]; + static uint32_t g_invalidate_rbx[]; + static uint32_t g_invalidate_rcx[]; + static uint32_t g_invalidate_rdx[]; + static uint32_t g_invalidate_rdi[]; + static uint32_t g_invalidate_rsi[]; + static uint32_t g_invalidate_rbp[]; + static uint32_t g_invalidate_rsp[]; + static uint32_t g_invalidate_r8[]; + static uint32_t g_invalidate_r9[]; + static uint32_t g_invalidate_r10[]; + static uint32_t g_invalidate_r11[]; + static uint32_t g_invalidate_r12[]; + static uint32_t g_invalidate_r13[]; + static uint32_t g_invalidate_r14[]; + static uint32_t g_invalidate_r15[]; + + static uint32_t g_contained_fip[]; + static uint32_t g_contained_fdp[]; + + static uint32_t g_invalidate_fip[]; + static uint32_t g_invalidate_fdp[]; + + static uint32_t g_contained_st0_32[]; + static uint32_t g_contained_st1_32[]; + static uint32_t g_contained_st2_32[]; + static uint32_t g_contained_st3_32[]; + static uint32_t g_contained_st4_32[]; + static uint32_t g_contained_st5_32[]; + static uint32_t g_contained_st6_32[]; + static uint32_t g_contained_st7_32[]; + + static uint32_t g_invalidate_st0_32[]; + static uint32_t g_invalidate_st1_32[]; + static uint32_t g_invalidate_st2_32[]; + static uint32_t g_invalidate_st3_32[]; + static uint32_t g_invalidate_st4_32[]; + static uint32_t g_invalidate_st5_32[]; + static uint32_t g_invalidate_st6_32[]; + static uint32_t g_invalidate_st7_32[]; + + static uint32_t g_contained_st0_64[]; + static uint32_t g_contained_st1_64[]; + static uint32_t g_contained_st2_64[]; + static uint32_t g_contained_st3_64[]; + static uint32_t g_contained_st4_64[]; + static uint32_t g_contained_st5_64[]; + static uint32_t g_contained_st6_64[]; + static uint32_t g_contained_st7_64[]; + + static uint32_t g_invalidate_st0_64[]; + static uint32_t g_invalidate_st1_64[]; + static uint32_t g_invalidate_st2_64[]; + static uint32_t g_invalidate_st3_64[]; + static uint32_t g_invalidate_st4_64[]; + static uint32_t g_invalidate_st5_64[]; + static uint32_t g_invalidate_st6_64[]; + static uint32_t g_invalidate_st7_64[]; +}; + +struct RegInfo { + uint32_t num_registers; + uint32_t num_gpr_registers; + uint32_t num_fpr_registers; + uint32_t num_avx_registers; + + uint32_t last_gpr; + uint32_t first_fpr; + uint32_t last_fpr; + + uint32_t first_st; + uint32_t last_st; + uint32_t first_mm; + uint32_t last_mm; + uint32_t first_xmm; + uint32_t last_xmm; + uint32_t first_ymm; + uint32_t last_ymm; + + uint32_t first_dr; + uint32_t gpr_flags; +}; + +RegInfo &GetRegInfoShared(llvm::Triple::ArchType arch_type, bool with_base); + +} // namespace lldb_private + +#endif // ifndef lldb_RegisterInfos_x86_64_with_base_shared_h diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index aae15b2ef462..d60e6250c7c0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -708,12 +708,50 @@ StopInfoSP StopInfoMachException::CreateStopReasonWithMachException( case llvm::Triple::aarch64_32: case llvm::Triple::aarch64: { + // xnu describes three things with type EXC_BREAKPOINT: + // + // exc_code 0x102 [EXC_ARM_DA_DEBUG], exc_sub_code addr-of-insn + // Watchpoint access. exc_sub_code is the address of the + // instruction which trigged the watchpoint trap. + // debugserver may add the watchpoint number that was triggered + // in exc_sub_sub_code. + // + // exc_code 1 [EXC_ARM_BREAKPOINT], exc_sub_code 0 + // Instruction step has completed. + // + // exc_code 1 [EXC_ARM_BREAKPOINT], exc_sub_code address-of-instruction + // Software breakpoint instruction executed. + if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT { // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0 // is set - is_actual_breakpoint = false; + is_actual_breakpoint = true; is_trace_if_actual_breakpoint_missing = true; +#ifndef NDEBUG + if (thread.GetTemporaryResumeState() != eStateStepping) { + StreamString s; + s.Printf("CreateStopReasonWithMachException got EXC_BREAKPOINT [1,0] " + "indicating trace event, but thread is not tracing, it has " + "ResumeState %d", + thread.GetTemporaryResumeState()); + if (RegisterContextSP regctx = thread.GetRegisterContext()) { + if (const RegisterInfo *ri = regctx->GetRegisterInfoByName("esr")) { + uint32_t esr = + (uint32_t)regctx->ReadRegisterAsUnsigned(ri, UINT32_MAX); + if (esr != UINT32_MAX) { + s.Printf(" esr value: 0x%" PRIx32, esr); + } + } + } + thread.GetProcess()->DumpPluginHistory(s); + llvm::report_fatal_error(s.GetData()); + lldbassert( + false && + "CreateStopReasonWithMachException got EXC_BREAKPOINT [1,0] " + "indicating trace event, but thread was not doing a step."); + } +#endif } if (exc_code == 0x102) // EXC_ARM_DA_DEBUG { diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-riscv-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-riscv-register-enums.h index 8c335b8c1094..caec313750ab 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-riscv-register-enums.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-riscv-register-enums.h @@ -152,6 +152,41 @@ enum { fpr_ft11_riscv = fpr_f31_riscv, fpr_last_riscv = fpr_fcsr_riscv, + vpr_first_riscv = 66, + vpr_v0_riscv = vpr_first_riscv, + vpr_v1_riscv, + vpr_v2_riscv, + vpr_v3_riscv, + vpr_v4_riscv, + vpr_v5_riscv, + vpr_v6_riscv, + vpr_v7_riscv, + vpr_v8_riscv, + vpr_v9_riscv, + vpr_v10_riscv, + vpr_v11_riscv, + vpr_v12_riscv, + vpr_v13_riscv, + vpr_v14_riscv, + vpr_v15_riscv, + vpr_v16_riscv, + vpr_v17_riscv, + vpr_v18_riscv, + vpr_v19_riscv, + vpr_v20_riscv, + vpr_v21_riscv, + vpr_v22_riscv, + vpr_v23_riscv, + vpr_v24_riscv, + vpr_v25_riscv, + vpr_v26_riscv, + vpr_v27_riscv, + vpr_v28_riscv, + vpr_v29_riscv, + vpr_v30_riscv, + vpr_v31_riscv, + vpr_last_riscv = vpr_v31_riscv, + k_num_registers_riscv }; diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h index 4d10600f4771..85aa254d6621 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/Utility/lldb-x86-register-enums.h @@ -321,6 +321,197 @@ enum { k_num_mpx_registers_x86_64, k_num_dbr_registers_x86_64 = k_last_dbr_x86_64 - k_first_dbr_x86_64 + 1, }; + +// For platform that supports fs_base/gs_base registers. +namespace x86_64_with_base { +enum { + k_first_gpr, + lldb_rax = k_first_gpr, + lldb_rbx, + lldb_rcx, + lldb_rdx, + lldb_rdi, + lldb_rsi, + lldb_rbp, + lldb_rsp, + lldb_r8, + lldb_r9, + lldb_r10, + lldb_r11, + lldb_r12, + lldb_r13, + lldb_r14, + lldb_r15, + lldb_rip, + lldb_rflags, + lldb_cs, + lldb_fs, + lldb_gs, + lldb_ss, + lldb_fs_base, + lldb_gs_base, + lldb_ds, + lldb_es, + + k_first_alias, + lldb_eax = k_first_alias, + lldb_ebx, + lldb_ecx, + lldb_edx, + lldb_edi, + lldb_esi, + lldb_ebp, + lldb_esp, + lldb_r8d, // Low 32 bits of r8 + lldb_r9d, // Low 32 bits of r9 + lldb_r10d, // Low 32 bits of r10 + lldb_r11d, // Low 32 bits of r11 + lldb_r12d, // Low 32 bits of r12 + lldb_r13d, // Low 32 bits of r13 + lldb_r14d, // Low 32 bits of r14 + lldb_r15d, // Low 32 bits of r15 + lldb_ax, + lldb_bx, + lldb_cx, + lldb_dx, + lldb_di, + lldb_si, + lldb_bp, + lldb_sp, + lldb_r8w, // Low 16 bits of r8 + lldb_r9w, // Low 16 bits of r9 + lldb_r10w, // Low 16 bits of r10 + lldb_r11w, // Low 16 bits of r11 + lldb_r12w, // Low 16 bits of r12 + lldb_r13w, // Low 16 bits of r13 + lldb_r14w, // Low 16 bits of r14 + lldb_r15w, // Low 16 bits of r15 + lldb_ah, + lldb_bh, + lldb_ch, + lldb_dh, + lldb_al, + lldb_bl, + lldb_cl, + lldb_dl, + lldb_dil, + lldb_sil, + lldb_bpl, + lldb_spl, + lldb_r8l, // Low 8 bits of r8 + lldb_r9l, // Low 8 bits of r9 + lldb_r10l, // Low 8 bits of r10 + lldb_r11l, // Low 8 bits of r11 + lldb_r12l, // Low 8 bits of r12 + lldb_r13l, // Low 8 bits of r13 + lldb_r14l, // Low 8 bits of r14 + lldb_r15l, // Low 8 bits of r15 + k_last_alias = lldb_r15l, + + k_last_gpr = k_last_alias, + + k_first_fpr, + lldb_fctrl = k_first_fpr, + lldb_fstat, + lldb_ftag, + lldb_fop, + lldb_fiseg, + lldb_fioff, + lldb_fip, + lldb_foseg, + lldb_fooff, + lldb_fdp, + lldb_mxcsr, + lldb_mxcsrmask, + lldb_st0, + lldb_st1, + lldb_st2, + lldb_st3, + lldb_st4, + lldb_st5, + lldb_st6, + lldb_st7, + lldb_mm0, + lldb_mm1, + lldb_mm2, + lldb_mm3, + lldb_mm4, + lldb_mm5, + lldb_mm6, + lldb_mm7, + lldb_xmm0, + lldb_xmm1, + lldb_xmm2, + lldb_xmm3, + lldb_xmm4, + lldb_xmm5, + lldb_xmm6, + lldb_xmm7, + lldb_xmm8, + lldb_xmm9, + lldb_xmm10, + lldb_xmm11, + lldb_xmm12, + lldb_xmm13, + lldb_xmm14, + lldb_xmm15, + k_last_fpr = lldb_xmm15, + + k_first_avx, + lldb_ymm0 = k_first_avx, + lldb_ymm1, + lldb_ymm2, + lldb_ymm3, + lldb_ymm4, + lldb_ymm5, + lldb_ymm6, + lldb_ymm7, + lldb_ymm8, + lldb_ymm9, + lldb_ymm10, + lldb_ymm11, + lldb_ymm12, + lldb_ymm13, + lldb_ymm14, + lldb_ymm15, + k_last_avx = lldb_ymm15, + + k_first_mpxr, + lldb_bnd0 = k_first_mpxr, + lldb_bnd1, + lldb_bnd2, + lldb_bnd3, + k_last_mpxr = lldb_bnd3, + + k_first_mpxc, + lldb_bndcfgu = k_first_mpxc, + lldb_bndstatus, + k_last_mpxc = lldb_bndstatus, + + k_first_dbr, + lldb_dr0 = k_first_dbr, + lldb_dr1, + lldb_dr2, + lldb_dr3, + lldb_dr4, + lldb_dr5, + lldb_dr6, + lldb_dr7, + k_last_dbr = lldb_dr7, + + k_num_registers, + k_num_gpr_registers = k_last_gpr - k_first_gpr + 1, + k_num_fpr_registers = k_last_fpr - k_first_fpr + 1, + k_num_avx_registers = k_last_avx - k_first_avx + 1, + k_num_mpx_registers = k_last_mpxc - k_first_mpxr + 1, + k_num_user_registers = k_num_gpr_registers + + k_num_fpr_registers + + k_num_avx_registers + + k_num_mpx_registers, + k_num_dbr_registers = k_last_dbr - k_first_dbr + 1, +}; +} // namespace x86_64_with_base + } #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_X86_REGISTER_ENUMS_H diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 24d3c4bd0ba2..bfb59eceb2d0 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 @@ -258,8 +258,8 @@ Status ProcessElfCore::DoLoadCore() { if (!m_nt_file_entries.empty()) { ModuleSpec exe_module_spec; exe_module_spec.GetArchitecture() = arch; - exe_module_spec.GetFileSpec().SetFile( - m_nt_file_entries[0].path.GetCString(), FileSpec::Style::native); + exe_module_spec.GetFileSpec().SetFile(m_nt_file_entries[0].path, + FileSpec::Style::native); if (exe_module_spec.GetFileSpec()) { exe_module_sp = GetTarget().GetOrCreateModule(exe_module_spec, true /* notify */); @@ -920,6 +920,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { if (status.Fail()) return status.ToError(); thread_data.signo = siginfo.si_signo; + thread_data.code = siginfo.si_code; break; } case ELF::NT_FILE: { @@ -937,7 +938,7 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef<CoreNote> notes) { for (uint64_t i = 0; i < count; ++i) { const char *path = note.data.GetCStr(&offset); if (path && path[0]) - m_nt_file_entries[i].path.SetCString(path); + m_nt_file_entries[i].path.assign(path); } break; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 03c23378e3c1..1454e8735a67 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -20,7 +20,6 @@ #include <vector> #include "lldb/Target/PostMortemProcess.h" -#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" #include "Plugins/ObjectFile/ELF/ELFHeader.h" @@ -117,7 +116,7 @@ private: lldb::addr_t start; lldb::addr_t end; lldb::addr_t file_ofs; - lldb_private::ConstString path; + std::string path; }; // For ProcessElfCore only diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.cpp new file mode 100644 index 000000000000..b806292c7a1a --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.cpp @@ -0,0 +1,237 @@ +//===-- RegisterContextLinuxCore_x86_64.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 "RegisterContextLinuxCore_x86_64.h" +#include "lldb/Target/Thread.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" + +using namespace lldb_private; + +const uint32_t g_gpr_regnums_i386[] = { + lldb_eax_i386, lldb_ebx_i386, lldb_ecx_i386, lldb_edx_i386, + lldb_edi_i386, lldb_esi_i386, lldb_ebp_i386, lldb_esp_i386, + lldb_eip_i386, lldb_eflags_i386, lldb_cs_i386, lldb_fs_i386, + lldb_gs_i386, lldb_ss_i386, lldb_ds_i386, lldb_es_i386, + lldb_ax_i386, lldb_bx_i386, lldb_cx_i386, lldb_dx_i386, + lldb_di_i386, lldb_si_i386, lldb_bp_i386, lldb_sp_i386, + lldb_ah_i386, lldb_bh_i386, lldb_ch_i386, lldb_dh_i386, + lldb_al_i386, lldb_bl_i386, lldb_cl_i386, lldb_dl_i386, + LLDB_INVALID_REGNUM, // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_gpr_regnums_i386) / sizeof(g_gpr_regnums_i386[0])) - + 1 == + k_num_gpr_registers_i386, + "g_gpr_regnums_i386 has wrong number of register infos"); + +const uint32_t g_lldb_regnums_i386[] = { + lldb_fctrl_i386, lldb_fstat_i386, lldb_ftag_i386, lldb_fop_i386, + lldb_fiseg_i386, lldb_fioff_i386, lldb_foseg_i386, lldb_fooff_i386, + lldb_mxcsr_i386, lldb_mxcsrmask_i386, lldb_st0_i386, lldb_st1_i386, + lldb_st2_i386, lldb_st3_i386, lldb_st4_i386, lldb_st5_i386, + lldb_st6_i386, lldb_st7_i386, lldb_mm0_i386, lldb_mm1_i386, + lldb_mm2_i386, lldb_mm3_i386, lldb_mm4_i386, lldb_mm5_i386, + lldb_mm6_i386, lldb_mm7_i386, lldb_xmm0_i386, lldb_xmm1_i386, + lldb_xmm2_i386, lldb_xmm3_i386, lldb_xmm4_i386, lldb_xmm5_i386, + lldb_xmm6_i386, lldb_xmm7_i386, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_lldb_regnums_i386) / sizeof(g_lldb_regnums_i386[0])) - + 1 == + k_num_fpr_registers_i386, + "g_lldb_regnums_i386 has wrong number of register infos"); + +const uint32_t g_avx_regnums_i386[] = { + lldb_ymm0_i386, lldb_ymm1_i386, lldb_ymm2_i386, lldb_ymm3_i386, + lldb_ymm4_i386, lldb_ymm5_i386, lldb_ymm6_i386, lldb_ymm7_i386, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_avx_regnums_i386) / sizeof(g_avx_regnums_i386[0])) - + 1 == + k_num_avx_registers_i386, + " g_avx_regnums_i386 has wrong number of register infos"); + +static const uint32_t g_gpr_regnums_x86_64[] = { + x86_64_with_base::lldb_rax, + x86_64_with_base::lldb_rbx, + x86_64_with_base::lldb_rcx, + x86_64_with_base::lldb_rdx, + x86_64_with_base::lldb_rdi, + x86_64_with_base::lldb_rsi, + x86_64_with_base::lldb_rbp, + x86_64_with_base::lldb_rsp, + x86_64_with_base::lldb_r8, + x86_64_with_base::lldb_r9, + x86_64_with_base::lldb_r10, + x86_64_with_base::lldb_r11, + x86_64_with_base::lldb_r12, + x86_64_with_base::lldb_r13, + x86_64_with_base::lldb_r14, + x86_64_with_base::lldb_r15, + x86_64_with_base::lldb_rip, + x86_64_with_base::lldb_rflags, + x86_64_with_base::lldb_cs, + x86_64_with_base::lldb_fs, + x86_64_with_base::lldb_gs, + x86_64_with_base::lldb_ss, + x86_64_with_base::lldb_fs_base, + x86_64_with_base::lldb_gs_base, + x86_64_with_base::lldb_ds, + x86_64_with_base::lldb_es, + x86_64_with_base::lldb_eax, + x86_64_with_base::lldb_ebx, + x86_64_with_base::lldb_ecx, + x86_64_with_base::lldb_edx, + x86_64_with_base::lldb_edi, + x86_64_with_base::lldb_esi, + x86_64_with_base::lldb_ebp, + x86_64_with_base::lldb_esp, + x86_64_with_base::lldb_r8d, // Low 32 bits or r8 + x86_64_with_base::lldb_r9d, // Low 32 bits or r9 + x86_64_with_base::lldb_r10d, // Low 32 bits or r10 + x86_64_with_base::lldb_r11d, // Low 32 bits or r11 + x86_64_with_base::lldb_r12d, // Low 32 bits or r12 + x86_64_with_base::lldb_r13d, // Low 32 bits or r13 + x86_64_with_base::lldb_r14d, // Low 32 bits or r14 + x86_64_with_base::lldb_r15d, // Low 32 bits or r15 + x86_64_with_base::lldb_ax, + x86_64_with_base::lldb_bx, + x86_64_with_base::lldb_cx, + x86_64_with_base::lldb_dx, + x86_64_with_base::lldb_di, + x86_64_with_base::lldb_si, + x86_64_with_base::lldb_bp, + x86_64_with_base::lldb_sp, + x86_64_with_base::lldb_r8w, // Low 16 bits or r8 + x86_64_with_base::lldb_r9w, // Low 16 bits or r9 + x86_64_with_base::lldb_r10w, // Low 16 bits or r10 + x86_64_with_base::lldb_r11w, // Low 16 bits or r11 + x86_64_with_base::lldb_r12w, // Low 16 bits or r12 + x86_64_with_base::lldb_r13w, // Low 16 bits or r13 + x86_64_with_base::lldb_r14w, // Low 16 bits or r14 + x86_64_with_base::lldb_r15w, // Low 16 bits or r15 + x86_64_with_base::lldb_ah, + x86_64_with_base::lldb_bh, + x86_64_with_base::lldb_ch, + x86_64_with_base::lldb_dh, + x86_64_with_base::lldb_al, + x86_64_with_base::lldb_bl, + x86_64_with_base::lldb_cl, + x86_64_with_base::lldb_dl, + x86_64_with_base::lldb_dil, + x86_64_with_base::lldb_sil, + x86_64_with_base::lldb_bpl, + x86_64_with_base::lldb_spl, + x86_64_with_base::lldb_r8l, // Low 8 bits or r8 + x86_64_with_base::lldb_r9l, // Low 8 bits or r9 + x86_64_with_base::lldb_r10l, // Low 8 bits or r10 + x86_64_with_base::lldb_r11l, // Low 8 bits or r11 + x86_64_with_base::lldb_r12l, // Low 8 bits or r12 + x86_64_with_base::lldb_r13l, // Low 8 bits or r13 + x86_64_with_base::lldb_r14l, // Low 8 bits or r14 + x86_64_with_base::lldb_r15l, // Low 8 bits or r15 + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_gpr_regnums_x86_64) / sizeof(g_gpr_regnums_x86_64[0])) - + 1 == + x86_64_with_base::k_num_gpr_registers, + "g_gpr_regnums_x86_64 has wrong number of register infos"); + +static const uint32_t g_lldb_regnums_x86_64[] = { + x86_64_with_base::lldb_fctrl, x86_64_with_base::lldb_fstat, + x86_64_with_base::lldb_ftag, x86_64_with_base::lldb_fop, + x86_64_with_base::lldb_fiseg, x86_64_with_base::lldb_fioff, + x86_64_with_base::lldb_fip, x86_64_with_base::lldb_foseg, + x86_64_with_base::lldb_fooff, x86_64_with_base::lldb_fdp, + x86_64_with_base::lldb_mxcsr, x86_64_with_base::lldb_mxcsrmask, + x86_64_with_base::lldb_st0, x86_64_with_base::lldb_st1, + x86_64_with_base::lldb_st2, x86_64_with_base::lldb_st3, + x86_64_with_base::lldb_st4, x86_64_with_base::lldb_st5, + x86_64_with_base::lldb_st6, x86_64_with_base::lldb_st7, + x86_64_with_base::lldb_mm0, x86_64_with_base::lldb_mm1, + x86_64_with_base::lldb_mm2, x86_64_with_base::lldb_mm3, + x86_64_with_base::lldb_mm4, x86_64_with_base::lldb_mm5, + x86_64_with_base::lldb_mm6, x86_64_with_base::lldb_mm7, + x86_64_with_base::lldb_xmm0, x86_64_with_base::lldb_xmm1, + x86_64_with_base::lldb_xmm2, x86_64_with_base::lldb_xmm3, + x86_64_with_base::lldb_xmm4, x86_64_with_base::lldb_xmm5, + x86_64_with_base::lldb_xmm6, x86_64_with_base::lldb_xmm7, + x86_64_with_base::lldb_xmm8, x86_64_with_base::lldb_xmm9, + x86_64_with_base::lldb_xmm10, x86_64_with_base::lldb_xmm11, + x86_64_with_base::lldb_xmm12, x86_64_with_base::lldb_xmm13, + x86_64_with_base::lldb_xmm14, x86_64_with_base::lldb_xmm15, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert( + (sizeof(g_lldb_regnums_x86_64) / sizeof(g_lldb_regnums_x86_64[0])) - 1 == + x86_64_with_base::k_num_fpr_registers, + "g_lldb_regnums_x86_64 has wrong number of register infos"); + +static const uint32_t g_avx_regnums_x86_64[] = { + x86_64_with_base::lldb_ymm0, x86_64_with_base::lldb_ymm1, + x86_64_with_base::lldb_ymm2, x86_64_with_base::lldb_ymm3, + x86_64_with_base::lldb_ymm4, x86_64_with_base::lldb_ymm5, + x86_64_with_base::lldb_ymm6, x86_64_with_base::lldb_ymm7, + x86_64_with_base::lldb_ymm8, x86_64_with_base::lldb_ymm9, + x86_64_with_base::lldb_ymm10, x86_64_with_base::lldb_ymm11, + x86_64_with_base::lldb_ymm12, x86_64_with_base::lldb_ymm13, + x86_64_with_base::lldb_ymm14, x86_64_with_base::lldb_ymm15, + LLDB_INVALID_REGNUM // Register sets must be terminated with + // LLDB_INVALID_REGNUM. +}; +static_assert((sizeof(g_avx_regnums_x86_64) / sizeof(g_avx_regnums_x86_64[0])) - + 1 == + x86_64_with_base::k_num_avx_registers, + "g_avx_regnums_x86_64 has wrong number of register infos"); + +static const RegisterSet g_reg_sets_i386[] = { + {"General Purpose Registers", "gpr", k_num_gpr_registers_i386, + g_gpr_regnums_i386}, + {"Floating Point Registers", "fpu", k_num_fpr_registers_i386, + g_lldb_regnums_i386}, + {"Advanced Vector Extensions", "avx", k_num_avx_registers_i386, + g_avx_regnums_i386}}; + +static const RegisterSet g_reg_sets_x86_64[] = { + {"General Purpose Registers", "gpr", x86_64_with_base::k_num_gpr_registers, + g_gpr_regnums_x86_64}, + {"Floating Point Registers", "fpu", x86_64_with_base::k_num_fpr_registers, + g_lldb_regnums_x86_64}, + {"Advanced Vector Extensions", "avx", x86_64_with_base::k_num_avx_registers, + g_avx_regnums_x86_64}}; + +RegisterContextLinuxCore_x86_64::RegisterContextLinuxCore_x86_64( + Thread &thread, RegisterInfoInterface *register_info, + const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes) + : RegisterContextCorePOSIX_x86_64(thread, register_info, gpregset, notes) {} + +const RegisterSet *RegisterContextLinuxCore_x86_64::GetRegisterSet(size_t set) { + if (IsRegisterSetAvailable(set)) { + switch (m_register_info_up->GetTargetArchitecture().GetMachine()) { + case llvm::Triple::x86: + return &g_reg_sets_i386[set]; + case llvm::Triple::x86_64: + return &g_reg_sets_x86_64[set]; + default: + assert(false && "Unhandled target architecture."); + return nullptr; + } + } + return nullptr; +} + +RegInfo &RegisterContextLinuxCore_x86_64::GetRegInfo() { + return GetRegInfoShared( + m_register_info_up->GetTargetArchitecture().GetMachine(), + /*with_base=*/true); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.h new file mode 100644 index 000000000000..a68ed82d718c --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/RegisterContextLinuxCore_x86_64.h @@ -0,0 +1,28 @@ +//===-- RegisterContextLinuxCore_x86_64.h -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTLINUXCORE_X86_64_H +#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTLINUXCORE_X86_64_H + +#include "Plugins/Process/elf-core/RegisterUtilities.h" +#include "RegisterContextPOSIXCore_x86_64.h" + +class RegisterContextLinuxCore_x86_64 : public RegisterContextCorePOSIX_x86_64 { +public: + RegisterContextLinuxCore_x86_64( + lldb_private::Thread &thread, + lldb_private::RegisterInfoInterface *register_info, + const lldb_private::DataExtractor &gpregset, + llvm::ArrayRef<lldb_private::CoreNote> notes); + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + lldb_private::RegInfo &GetRegInfo() override; +}; + +#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTLINUXCORE_X86_64_H 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 357140d269f1..a7c620c883ba 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 @@ -31,6 +31,7 @@ #include "Plugins/Process/Utility/RegisterInfoPOSIX_arm64.h" #include "Plugins/Process/Utility/RegisterInfoPOSIX_ppc64le.h" #include "ProcessElfCore.h" +#include "RegisterContextLinuxCore_x86_64.h" #include "RegisterContextPOSIXCore_arm.h" #include "RegisterContextPOSIXCore_arm64.h" #include "RegisterContextPOSIXCore_mips64.h" @@ -50,7 +51,8 @@ using namespace lldb_private; // Construct a Thread object with given data ThreadElfCore::ThreadElfCore(Process &process, const ThreadData &td) : Thread(process, td.tid), m_thread_name(td.name), m_thread_reg_ctx_sp(), - m_signo(td.signo), m_gpregset_data(td.gpregset), m_notes(td.notes) {} + m_signo(td.signo), m_code(td.code), m_gpregset_data(td.gpregset), + m_notes(td.notes) {} ThreadElfCore::~ThreadElfCore() { DestroyThread(); } @@ -74,6 +76,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); + bool is_linux = false; if (concrete_frame_idx == 0) { if (m_thread_reg_ctx_sp) return m_thread_reg_ctx_sp; @@ -126,6 +129,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { } case llvm::Triple::Linux: { + is_linux = true; switch (arch.GetMachine()) { case llvm::Triple::aarch64: break; @@ -213,8 +217,13 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { #endif // LLDB_ENABLE_ALL case llvm::Triple::x86: case llvm::Triple::x86_64: - m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>( - *this, reg_interface, m_gpregset_data, m_notes); + if (is_linux) { + m_thread_reg_ctx_sp = std::make_shared<RegisterContextLinuxCore_x86_64>( + *this, reg_interface, m_gpregset_data, m_notes); + } else { + m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_x86_64>( + *this, reg_interface, m_gpregset_data, m_notes); + } break; default: break; @@ -229,11 +238,12 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) { bool ThreadElfCore::CalculateStopInfo() { ProcessSP process_sp(GetProcess()); - if (process_sp) { - SetStopInfo(StopInfo::CreateStopReasonWithSignal(*this, m_signo)); - return true; - } - return false; + if (!process_sp) + return false; + + SetStopInfo(StopInfo::CreateStopReasonWithSignal( + *this, m_signo, /*description=*/nullptr, m_code)); + return true; } // Parse PRSTATUS from NOTE entry @@ -417,8 +427,8 @@ Status ELFLinuxSigInfo::Parse(const DataExtractor &data, const ArchSpec &arch) { // properly, because the struct is for the 64 bit version offset_t offset = 0; si_signo = data.GetU32(&offset); - si_code = data.GetU32(&offset); si_errno = data.GetU32(&offset); + si_code = data.GetU32(&offset); return error; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h index 8d973bb840d2..2f3ed2a01779 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/elf-core/ThreadElfCore.h @@ -128,6 +128,7 @@ struct ThreadData { std::vector<lldb_private::CoreNote> notes; lldb::tid_t tid; int signo = 0; + int code = 0; int prstatus_sig = 0; std::string name; }; @@ -166,6 +167,7 @@ protected: lldb::RegisterContextSP m_thread_reg_ctx_sp; int m_signo; + int m_code; lldb_private::DataExtractor m_gpregset_data; std::vector<lldb_private::CoreNote> m_notes; 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 6e47e5b3e3d1..c6503129685a 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 @@ -35,6 +35,7 @@ #include "lldb/Host/Config.h" #include "lldb/Utility/StringExtractorGDBRemote.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/JSON.h" @@ -69,10 +70,10 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() m_supports_vFileSize(true), m_supports_vFileMode(true), m_supports_vFileExists(true), m_supports_vRun(true), - m_host_arch(), m_process_arch(), m_os_build(), m_os_kernel(), - m_hostname(), m_gdb_server_name(), m_default_packet_timeout(0), - m_qSupported_response(), m_supported_async_json_packets_sp(), - m_qXfer_memory_map() {} + m_host_arch(), m_host_distribution_id(), m_process_arch(), m_os_build(), + m_os_kernel(), m_hostname(), m_gdb_server_name(), + m_default_packet_timeout(0), m_qSupported_response(), + m_supported_async_json_packets_sp(), m_qXfer_memory_map() {} // Destructor GDBRemoteCommunicationClient::~GDBRemoteCommunicationClient() { @@ -307,6 +308,7 @@ void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) { m_qSymbol_requests_done = false; m_supports_qModuleInfo = true; m_host_arch.Clear(); + m_host_distribution_id.clear(); m_os_version = llvm::VersionTuple(); m_os_build.clear(); m_os_kernel.clear(); @@ -549,8 +551,7 @@ StructuredData::ObjectSP GDBRemoteCommunicationClient::GetThreadsInfo() { if (response.IsUnsupportedResponse()) { m_supports_jThreadsInfo = false; } else if (!response.Empty()) { - object_sp = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + object_sp = StructuredData::ParseJSON(response.GetStringRef()); } } } @@ -826,8 +827,12 @@ llvm::Error GDBRemoteCommunicationClient::LaunchProcess(const Args &args) { } int GDBRemoteCommunicationClient::SendEnvironment(const Environment &env) { - for (const auto &KV : env) { - int r = SendEnvironmentPacket(Environment::compose(KV).c_str()); + llvm::SmallVector<std::pair<llvm::StringRef, llvm::StringRef>, 0> vec; + for (const auto &kv : env) + vec.emplace_back(kv.first(), kv.second); + llvm::sort(vec, llvm::less_first()); + for (const auto &[k, v] : vec) { + int r = SendEnvironmentPacket((k + "=" + v).str().c_str()); if (r != 0) return r; } @@ -1207,7 +1212,6 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { std::string environment; std::string vendor_name; std::string triple; - std::string distribution_id; uint32_t pointer_byte_size = 0; ByteOrder byte_order = eByteOrderInvalid; uint32_t num_keys_decoded = 0; @@ -1229,7 +1233,7 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { ++num_keys_decoded; } else if (name.equals("distribution_id")) { StringExtractor extractor(value); - extractor.GetHexByteString(distribution_id); + extractor.GetHexByteString(m_host_distribution_id); ++num_keys_decoded; } else if (name.equals("os_build")) { StringExtractor extractor(value); @@ -1377,8 +1381,6 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { m_host_arch.GetTriple().getTriple().c_str(), triple.c_str()); } - if (!distribution_id.empty()) - m_host_arch.SetDistributionId(distribution_id.c_str()); } } } @@ -1780,16 +1782,12 @@ Status GDBRemoteCommunicationClient::LoadQXferMemoryMap() { return error; } -Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) { - Status error; - +std::optional<uint32_t> GDBRemoteCommunicationClient::GetWatchpointSlotCount() { if (m_supports_watchpoint_support_info == eLazyBoolYes) { - num = m_num_supported_hardware_watchpoints; - return error; + return m_num_supported_hardware_watchpoints; } - // Set num to 0 first. - num = 0; + std::optional<uint32_t> num; if (m_supports_watchpoint_support_info != eLazyBoolNo) { StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse("qWatchpointSupportInfo:", response) == @@ -1797,15 +1795,13 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) { m_supports_watchpoint_support_info = eLazyBoolYes; llvm::StringRef name; llvm::StringRef value; - bool found_num_field = false; while (response.GetNameColonValue(name, value)) { if (name.equals("num")) { value.getAsInteger(0, m_num_supported_hardware_watchpoints); num = m_num_supported_hardware_watchpoints; - found_num_field = true; } } - if (!found_num_field) { + if (!num) { m_supports_watchpoint_support_info = eLazyBoolNo; } } else { @@ -1813,44 +1809,24 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) { } } - if (m_supports_watchpoint_support_info == eLazyBoolNo) { - error.SetErrorString("qWatchpointSupportInfo is not supported"); - } - return error; -} - -lldb_private::Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo( - uint32_t &num, bool &after, const ArchSpec &arch) { - Status error(GetWatchpointSupportInfo(num)); - if (error.Success()) - error = GetWatchpointsTriggerAfterInstruction(after, arch); - return error; + return num; } -lldb_private::Status -GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction( - bool &after, const ArchSpec &arch) { - Status error; - llvm::Triple triple = arch.GetTriple(); - - // we assume watchpoints will happen after running the relevant opcode and we - // only want to override this behavior if we have explicitly received a - // qHostInfo telling us otherwise - if (m_qHostInfo_is_valid != eLazyBoolYes) { - // On targets like MIPS and ppc64, watchpoint exceptions are always - // generated before the instruction is executed. The connected target may - // not support qHostInfo or qWatchpointSupportInfo packets. - after = !(triple.isMIPS() || triple.isPPC64()); - } else { - // For MIPS and ppc64, set m_watchpoints_trigger_after_instruction to - // eLazyBoolNo if it is not calculated before. - if (m_watchpoints_trigger_after_instruction == eLazyBoolCalculate && - (triple.isMIPS() || triple.isPPC64())) - m_watchpoints_trigger_after_instruction = eLazyBoolNo; +std::optional<bool> GDBRemoteCommunicationClient::GetWatchpointReportedAfter() { + if (m_qHostInfo_is_valid == eLazyBoolCalculate) + GetHostInfo(); - after = (m_watchpoints_trigger_after_instruction != eLazyBoolNo); + // Process determines this by target CPU, but allow for the + // remote stub to override it via the qHostInfo + // watchpoint_exceptions_received key, if it is present. + if (m_qHostInfo_is_valid == eLazyBoolYes) { + if (m_watchpoints_trigger_after_instruction == eLazyBoolNo) + return false; + if (m_watchpoints_trigger_after_instruction == eLazyBoolYes) + return true; } - return error; + + return std::nullopt; } int GDBRemoteCommunicationClient::SetSTDIN(const FileSpec &file_spec) { @@ -2619,6 +2595,9 @@ bool GDBRemoteCommunicationClient::LaunchGDBServer( if (SendPacketAndWaitForResponse(stream.GetString(), response) == PacketResult::Success) { + if (response.IsErrorResponse()) + return false; + llvm::StringRef name; llvm::StringRef value; while (response.GetNameColonValue(name, value)) { @@ -2646,7 +2625,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer( return 0; StructuredData::ObjectSP data = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + StructuredData::ParseJSON(response.GetStringRef()); if (!data) return 0; @@ -2662,7 +2641,7 @@ size_t GDBRemoteCommunicationClient::QueryGDBServer( uint16_t port = 0; if (StructuredData::ObjectSP port_osp = element->GetValueForKey(llvm::StringRef("port"))) - port = port_osp->GetIntegerValue(0); + port = port_osp->GetUnsignedIntegerValue(0); std::string socket_name; if (StructuredData::ObjectSP socket_name_osp = @@ -3894,7 +3873,7 @@ GDBRemoteCommunicationClient::GetModulesInfo( } StructuredData::ObjectSP response_object_sp = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + StructuredData::ParseJSON(response.GetStringRef()); if (!response_object_sp) return std::nullopt; @@ -4057,52 +4036,45 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups( lldb_private::SymbolContextList sc_list; process->GetTarget().GetImages().FindSymbolsWithNameAndType( ConstString(symbol_name), eSymbolTypeAny, sc_list); - if (!sc_list.IsEmpty()) { - const size_t num_scs = sc_list.GetSize(); - for (size_t sc_idx = 0; - sc_idx < num_scs && - symbol_load_addr == LLDB_INVALID_ADDRESS; - ++sc_idx) { - SymbolContext sc; - if (sc_list.GetContextAtIndex(sc_idx, sc)) { - if (sc.symbol) { - switch (sc.symbol->GetType()) { - case eSymbolTypeInvalid: - case eSymbolTypeAbsolute: - case eSymbolTypeUndefined: - case eSymbolTypeSourceFile: - case eSymbolTypeHeaderFile: - case eSymbolTypeObjectFile: - case eSymbolTypeCommonBlock: - case eSymbolTypeBlock: - case eSymbolTypeLocal: - case eSymbolTypeParam: - case eSymbolTypeVariable: - case eSymbolTypeVariableType: - case eSymbolTypeLineEntry: - case eSymbolTypeLineHeader: - case eSymbolTypeScopeBegin: - case eSymbolTypeScopeEnd: - case eSymbolTypeAdditional: - case eSymbolTypeCompiler: - case eSymbolTypeInstrumentation: - case eSymbolTypeTrampoline: - break; - - case eSymbolTypeCode: - case eSymbolTypeResolver: - case eSymbolTypeData: - case eSymbolTypeRuntime: - case eSymbolTypeException: - case eSymbolTypeObjCClass: - case eSymbolTypeObjCMetaClass: - case eSymbolTypeObjCIVar: - case eSymbolTypeReExported: - symbol_load_addr = - sc.symbol->GetLoadAddress(&process->GetTarget()); - break; - } - } + for (const SymbolContext &sc : sc_list) { + if (symbol_load_addr != LLDB_INVALID_ADDRESS) + break; + if (sc.symbol) { + switch (sc.symbol->GetType()) { + case eSymbolTypeInvalid: + case eSymbolTypeAbsolute: + case eSymbolTypeUndefined: + case eSymbolTypeSourceFile: + case eSymbolTypeHeaderFile: + case eSymbolTypeObjectFile: + case eSymbolTypeCommonBlock: + case eSymbolTypeBlock: + case eSymbolTypeLocal: + case eSymbolTypeParam: + case eSymbolTypeVariable: + case eSymbolTypeVariableType: + case eSymbolTypeLineEntry: + case eSymbolTypeLineHeader: + case eSymbolTypeScopeBegin: + case eSymbolTypeScopeEnd: + case eSymbolTypeAdditional: + case eSymbolTypeCompiler: + case eSymbolTypeInstrumentation: + case eSymbolTypeTrampoline: + break; + + case eSymbolTypeCode: + case eSymbolTypeResolver: + case eSymbolTypeData: + case eSymbolTypeRuntime: + case eSymbolTypeException: + case eSymbolTypeObjCClass: + case eSymbolTypeObjCMetaClass: + case eSymbolTypeObjCIVar: + case eSymbolTypeReExported: + symbol_load_addr = + sc.symbol->GetLoadAddress(&process->GetTarget()); + break; } } } @@ -4152,7 +4124,7 @@ GDBRemoteCommunicationClient::GetSupportedStructuredDataPlugins() { if (SendPacketAndWaitForResponse("qStructuredDataPlugins", response) == PacketResult::Success) { m_supported_async_json_packets_sp = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + StructuredData::ParseJSON(response.GetStringRef()); if (m_supported_async_json_packets_sp && !m_supported_async_json_packets_sp->GetAsArray()) { // We were returned something other than a JSON array. This is @@ -4207,10 +4179,10 @@ Status GDBRemoteCommunicationClient::SendSignalsToIgnore( } Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( - ConstString type_name, const StructuredData::ObjectSP &config_sp) { + llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) { Status error; - if (type_name.GetLength() == 0) { + if (type_name.empty()) { error.SetErrorString("invalid type_name argument"); return error; } @@ -4218,7 +4190,7 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( // Build command: Configure{type_name}: serialized config data. StreamGDBRemote stream; stream.PutCString("QConfigure"); - stream.PutCString(type_name.GetStringRef()); + stream.PutCString(type_name); stream.PutChar(':'); if (config_sp) { // Gather the plain-text version of the configuration data. @@ -4237,21 +4209,20 @@ Status GDBRemoteCommunicationClient::ConfigureRemoteStructuredData( auto result = SendPacketAndWaitForResponse(stream.GetString(), response); if (result == PacketResult::Success) { // We failed if the config result comes back other than OK. - if (strcmp(response.GetStringRef().data(), "OK") == 0) { + if (response.GetStringRef() == "OK") { // Okay! error.Clear(); } else { - error.SetErrorStringWithFormat("configuring StructuredData feature " - "%s failed with error %s", - type_name.AsCString(), - response.GetStringRef().data()); + error.SetErrorStringWithFormatv( + "configuring StructuredData feature {0} failed with error {1}", + type_name, response.GetStringRef()); } } else { // Can we get more data here on the failure? - error.SetErrorStringWithFormat("configuring StructuredData feature %s " - "failed when sending packet: " - "PacketResult=%d", - type_name.AsCString(), (int)result); + error.SetErrorStringWithFormatv( + "configuring StructuredData feature {0} failed when sending packet: " + "PacketResult={1}", + type_name, (int)result); } return error; } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index 45ea2f2589c1..6cf5de68911b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -194,13 +194,9 @@ public: Status GetMemoryRegionInfo(lldb::addr_t addr, MemoryRegionInfo &range_info); - Status GetWatchpointSupportInfo(uint32_t &num); + std::optional<uint32_t> GetWatchpointSlotCount(); - Status GetWatchpointSupportInfo(uint32_t &num, bool &after, - const ArchSpec &arch); - - Status GetWatchpointsTriggerAfterInstruction(bool &after, - const ArchSpec &arch); + std::optional<bool> GetWatchpointReportedAfter(); const ArchSpec &GetHostArchitecture(); @@ -496,7 +492,7 @@ public: /// /// \see \b Process::ConfigureStructuredData(...) for details. Status - ConfigureRemoteStructuredData(ConstString type_name, + ConfigureRemoteStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp); llvm::Expected<TraceSupportedResponse> @@ -587,6 +583,7 @@ protected: uint32_t m_addressing_bits = 0; ArchSpec m_host_arch; + std::string m_host_distribution_id; ArchSpec m_process_arch; UUID m_process_standalone_uuid; lldb::addr_t m_process_standalone_value = LLDB_INVALID_ADDRESS; 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 f71240672bcc..b4fb5b68dd41 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 @@ -36,17 +36,17 @@ #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/JSON.h" +#include "llvm/TargetParser/Triple.h" #include "ProcessGDBRemoteLog.h" #include "lldb/Utility/StringExtractorGDBRemote.h" #ifdef __ANDROID__ #include "lldb/Host/android/HostInfoAndroid.h" +#include "lldb/Host/common/ZipFileResolver.h" #endif - using namespace lldb; using namespace lldb_private::process_gdb_remote; using namespace lldb_private; @@ -187,8 +187,8 @@ GDBRemoteCommunicationServerCommon::Handle_qHostInfo( response.PutStringAsRawHex8(host_triple.getTriple()); response.Printf(";ptrsize:%u;", host_arch.GetAddressByteSize()); - const char *distribution_id = host_arch.GetDistributionId().AsCString(); - if (distribution_id) { + llvm::StringRef distribution_id = HostInfo::GetDistributionId(); + if (!distribution_id.empty()) { response.PutCString("distribution_id:"); response.PutStringAsRawHex8(distribution_id); response.PutCString(";"); @@ -1138,7 +1138,7 @@ GDBRemoteCommunicationServerCommon::Handle_qModuleInfo( response.PutCString("file_path:"); response.PutStringAsRawHex8( - matched_module_spec.GetFileSpec().GetPath().c_str()); + matched_module_spec.GetFileSpec().GetPath().c_str()); response.PutChar(';'); response.PutCString("file_offset:"); response.PutHex64(file_offset); @@ -1326,17 +1326,50 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch); - const ModuleSpec module_spec(module_path_spec, arch); + + lldb::offset_t file_offset = 0; + lldb::offset_t file_size = 0; +#ifdef __ANDROID__ + // In Android API level 23 and above, dynamic loader is able to load .so file + // directly from zip file. In that case, module_path will be + // "zip_path!/so_path". Resolve the zip file path, .so file offset and size. + ZipFileResolver::FileKind file_kind = ZipFileResolver::eFileKindInvalid; + std::string file_path; + if (!ZipFileResolver::ResolveSharedLibraryPath( + module_path_spec, file_kind, file_path, file_offset, file_size)) { + return ModuleSpec(); + } + lldbassert(file_kind != ZipFileResolver::eFileKindInvalid); + // For zip .so file, this file_path will contain only the actual zip file + // path for the object file processing. Otherwise it is the same as + // module_path. + const FileSpec actual_module_path_spec(file_path); +#else + // It is just module_path_spec reference for other platforms. + const FileSpec &actual_module_path_spec = module_path_spec; +#endif + + const ModuleSpec module_spec(actual_module_path_spec, arch); ModuleSpecList module_specs; - if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, - module_specs)) + if (!ObjectFile::GetModuleSpecifications(actual_module_path_spec, file_offset, + file_size, module_specs)) return ModuleSpec(); ModuleSpec matched_module_spec; if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) return ModuleSpec(); +#ifdef __ANDROID__ + if (file_kind == ZipFileResolver::eFileKindZip) { + // For zip .so file, matched_module_spec contains only the actual zip file + // path for the object file processing. Overwrite the matched_module_spec + // file spec with the original module_path_spec to pass "zip_path!/so_path" + // through to PlatformAndroid::DownloadModuleSlice. + *matched_module_spec.GetFileSpecPtr() = module_path_spec; + } +#endif + return matched_module_spec; } 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 921c149b9762..4efc454967a1 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 @@ -37,14 +37,13 @@ #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" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UnimplementedError.h" #include "lldb/Utility/UriParser.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/JSON.h" #include "llvm/Support/ScopedPrinter.h" +#include "llvm/TargetParser/Triple.h" #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" @@ -69,9 +68,9 @@ enum GDBRemoteServerError { // GDBRemoteCommunicationServerLLGS constructor GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS( - MainLoop &mainloop, const NativeProcessProtocol::Factory &process_factory) + MainLoop &mainloop, NativeProcessProtocol::Manager &process_manager) : GDBRemoteCommunicationServerCommon(), m_mainloop(mainloop), - m_process_factory(process_factory), m_current_process(nullptr), + m_process_manager(process_manager), m_current_process(nullptr), m_continue_process(nullptr), m_stdio_communication() { RegisterPacketHandlers(); } @@ -286,8 +285,7 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex); assert(m_debugged_processes.empty() && "lldb-server creating debugged " "process but one already exists"); - auto process_or = - m_process_factory.Launch(m_process_launch_info, *this, m_mainloop); + auto process_or = m_process_manager.Launch(m_process_launch_info, *this); if (!process_or) return Status(process_or.takeError()); m_continue_process = m_current_process = process_or->get(); @@ -356,7 +354,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) { pid, m_current_process->GetID()); // Try to attach. - auto process_or = m_process_factory.Attach(pid, *this, m_mainloop); + auto process_or = m_process_manager.Attach(pid, *this); if (!process_or) { Status status(process_or.takeError()); llvm::errs() << llvm::formatv("failed to attach to process {0}: {1}\n", pid, @@ -2267,8 +2265,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { packet, "P packet missing '=' char after register number"); // Parse out the value. - uint8_t reg_bytes[RegisterValue::kMaxRegisterByteSize]; - size_t reg_size = packet.GetHexBytesAvail(reg_bytes); + size_t reg_size = packet.GetHexBytesAvail(m_reg_bytes); // Get the thread to use. NativeThreadProtocol *thread = GetThreadFromSuffix(packet); @@ -2307,7 +2304,7 @@ GDBRemoteCommunicationServerLLGS::Handle_P(StringExtractorGDBRemote &packet) { // Build the reginfos response. StreamGDBRemote response; - RegisterValue reg_value(ArrayRef(reg_bytes, reg_size), + RegisterValue reg_value(ArrayRef(m_reg_bytes, reg_size), m_current_process->GetArchitecture().GetByteOrder()); Status error = reg_context.WriteRegister(reg_info, reg_value); if (error.Fail()) { @@ -4209,7 +4206,7 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures( // report server-only features using Extension = NativeProcessProtocol::Extension; - Extension plugin_features = m_process_factory.GetSupportedExtensions(); + Extension plugin_features = m_process_manager.GetSupportedExtensions(); if (bool(plugin_features & Extension::pass_signals)) ret.push_back("QPassSignals+"); if (bool(plugin_features & Extension::auxv)) @@ -4255,7 +4252,7 @@ std::vector<std::string> GDBRemoteCommunicationServerLLGS::HandleFeatures( void GDBRemoteCommunicationServerLLGS::SetEnabledExtensions( NativeProcessProtocol &process) { NativeProcessProtocol::Extension flags = m_extensions_supported; - assert(!bool(flags & ~m_process_factory.GetSupportedExtensions())); + assert(!bool(flags & ~m_process_manager.GetSupportedExtensions())); process.SetEnabledExtensions(flags); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 1165b60ac762..646b6a102abf 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 @@ -16,6 +16,7 @@ #include "lldb/Core/Communication.h" #include "lldb/Host/MainLoop.h" #include "lldb/Host/common/NativeProcessProtocol.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private-forward.h" #include "GDBRemoteCommunicationServerCommon.h" @@ -35,7 +36,7 @@ public: // Constructors and Destructors GDBRemoteCommunicationServerLLGS( MainLoop &mainloop, - const NativeProcessProtocol::Factory &process_factory); + NativeProcessProtocol::Manager &process_manager); void SetLaunchInfo(const ProcessLaunchInfo &info); @@ -99,7 +100,7 @@ public: protected: MainLoop &m_mainloop; MainLoop::ReadHandleUP m_network_handle_up; - const NativeProcessProtocol::Factory &m_process_factory; + NativeProcessProtocol::Manager &m_process_manager; lldb::tid_t m_current_tid = LLDB_INVALID_THREAD_ID; lldb::tid_t m_continue_tid = LLDB_INVALID_THREAD_ID; NativeProcessProtocol *m_current_process; @@ -123,6 +124,11 @@ protected: NativeProcessProtocol::Extension m_extensions_supported = {}; + // Typically we would use a SmallVector for this data but in this context we + // don't know how much data we're recieving so we would have to heap allocate + // a lot, or have a very large stack frame. So it's a member instead. + uint8_t m_reg_bytes[RegisterValue::kMaxRegisterByteSize]; + PacketResult SendONotification(const char *buffer, uint32_t len); PacketResult SendWResponse(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 bdb6480ff4d9..4ffa7faa4942 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 @@ -559,7 +559,7 @@ Status GDBRemoteCommunicationServerPlatform::LaunchProcess() { } void GDBRemoteCommunicationServerPlatform::SetPortMap(PortMap &&port_map) { - m_port_map = port_map; + m_port_map = std::move(port_map); } const FileSpec &GDBRemoteCommunicationServerPlatform::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 8ea93655d6bb..e8606ddae567 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 @@ -457,7 +457,7 @@ bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, if (log) { if (log->GetVerbose()) { StreamString strm; - gdb_comm.DumpHistory(strm); + process->DumpPluginHistory(strm); LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending " "write register for \"%s\":\n%s", @@ -566,7 +566,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues( if (log) { if (log->GetVerbose()) { StreamString strm; - gdb_comm.DumpHistory(strm); + process->DumpPluginHistory(strm); LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending " "read all registers:\n%s", @@ -741,7 +741,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues( if (log) { if (log->GetVerbose()) { StreamString strm; - gdb_comm.DumpHistory(strm); + process->DumpPluginHistory(strm); LLDB_LOGF(log, "error: failed to get packet sequence mutex, not sending " "write all registers:\n%s", diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp index b391edced695..8068614c9350 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterFallback.cpp @@ -19,6 +19,7 @@ namespace process_gdb_remote { } #define R64(name) REG(name, 8) #define R32(name) REG(name, 4) +#define R16(name) REG(name, 2) static std::vector<DynamicRegisterInfo::Register> GetRegisters_aarch64() { ConstString empty_alt_name; @@ -35,6 +36,18 @@ static std::vector<DynamicRegisterInfo::Register> GetRegisters_aarch64() { return registers; } +static std::vector<DynamicRegisterInfo::Register> GetRegisters_msp430() { + ConstString empty_alt_name; + ConstString reg_set{"general purpose registers"}; + + std::vector<DynamicRegisterInfo::Register> registers{ + R16(pc), R16(sp), R16(r2), R16(r3), R16(fp), R16(r5), + R16(r6), R16(r7), R16(r8), R16(r9), R16(r10), R16(r11), + R16(r12), R16(r13), R16(r14), R16(r15)}; + + return registers; +} + static std::vector<DynamicRegisterInfo::Register> GetRegisters_x86() { ConstString empty_alt_name; ConstString reg_set{"general purpose registers"}; @@ -71,6 +84,8 @@ GetFallbackRegisters(const ArchSpec &arch_to_use) { switch (arch_to_use.GetMachine()) { case llvm::Triple::aarch64: return GetRegisters_aarch64(); + case llvm::Triple::msp430: + return GetRegisters_msp430(); case llvm::Triple::x86: return GetRegisters_x86(); case llvm::Triple::x86_64: 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 de8f2df52f23..b6f146fd872e 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 @@ -53,6 +53,7 @@ #include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Target/RegisterFlags.h" #include "lldb/Target/SystemRuntime.h" #include "lldb/Target/Target.h" #include "lldb/Target/TargetList.h" @@ -84,6 +85,7 @@ #include "lldb/Utility/StringExtractorGDBRemote.h" #include "llvm/ADT/ScopeExit.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/Threading.h" @@ -111,7 +113,7 @@ void DumpProcessGDBRemotePacketHistory(void *p, const char *path) { return; } StreamFile stream(std::move(file.get())); - ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(stream); + ((Process *)p)->DumpPluginHistory(stream); } } // namespace lldb @@ -140,30 +142,29 @@ public: uint64_t GetPacketTimeout() { const uint32_t idx = ePropertyPacketTimeout; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_processgdbremote_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_processgdbremote_properties[idx].default_uint_value); } bool SetPacketTimeout(uint64_t timeout) { const uint32_t idx = ePropertyPacketTimeout; - return m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, timeout); + return SetPropertyAtIndex(idx, timeout); } FileSpec GetTargetDefinitionFile() const { const uint32_t idx = ePropertyTargetDefinitionFile; - return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } bool GetUseSVR4() const { const uint32_t idx = ePropertyUseSVR4; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, - g_processgdbremote_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_processgdbremote_properties[idx].default_uint_value != 0); } bool GetUseGPacketForReading() const { const uint32_t idx = ePropertyUseGPacketForReading; - return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, true); + return GetPropertyAtIndexAs<bool>(idx, true); } }; @@ -204,6 +205,11 @@ lldb::ProcessSP ProcessGDBRemote::CreateInstance( return process_sp; } +void ProcessGDBRemote::DumpPluginHistory(Stream &s) { + GDBRemoteCommunicationClient &gdb_comm(GetGDBRemote()); + gdb_comm.DumpHistory(s); +} + std::chrono::seconds ProcessGDBRemote::GetPacketTimeout() { return std::chrono::seconds(GetGlobalPluginProperties().GetPacketTimeout()); } @@ -341,7 +347,7 @@ bool ProcessGDBRemote::ParsePythonTargetDefinition( target_definition_sp->GetValueForKey("breakpoint-pc-offset"); if (breakpoint_pc_offset_value) { if (auto breakpoint_pc_int_value = - breakpoint_pc_offset_value->GetAsInteger()) + breakpoint_pc_offset_value->GetAsSignedInteger()) m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue(); } @@ -994,9 +1000,11 @@ void ProcessGDBRemote::LoadStubBinaries() { if (standalone_uuid.IsValid()) { const bool force_symbol_search = true; const bool notify = true; + const bool set_address_in_target = true; DynamicLoader::LoadBinaryWithUUIDAndAddress( this, "", standalone_uuid, standalone_value, - standalone_value_is_offset, force_symbol_search, notify); + standalone_value_is_offset, force_symbol_search, notify, + set_address_in_target); } } @@ -1024,10 +1032,11 @@ void ProcessGDBRemote::LoadStubBinaries() { continue; const bool force_symbol_search = true; + const bool set_address_in_target = true; // Second manually load this binary into the Target. - DynamicLoader::LoadBinaryWithUUIDAndAddress(this, llvm::StringRef(), uuid, - addr, value_is_slide, - force_symbol_search, notify); + DynamicLoader::LoadBinaryWithUUIDAndAddress( + this, llvm::StringRef(), uuid, addr, value_is_slide, + force_symbol_search, notify, set_address_in_target); } } } @@ -1749,33 +1758,60 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( } else if (reason == "trap") { // Let the trap just use the standard signal stop reason below... } else if (reason == "watchpoint") { + // We will have between 1 and 3 fields in the description. + // + // \a wp_addr which is the original start address that + // lldb requested be watched, or an address that the + // hardware reported. This address should be within the + // range of a currently active watchpoint region - lldb + // should be able to find a watchpoint with this address. + // + // \a wp_index is the hardware watchpoint register number. + // + // \a wp_hit_addr is the actual address reported by the hardware, + // which may be outside the range of a region we are watching. + // + // On MIPS, we may get a false watchpoint exception where an + // access to the same 8 byte granule as a watchpoint will trigger, + // even if the access was not within the range of the watched + // region. When we get a \a wp_hit_addr outside the range of any + // set watchpoint, continue execution without making it visible to + // the user. + // + // On ARM, a related issue where a large access that starts + // before the watched region (and extends into the watched + // region) may report a hit address before the watched region. + // lldb will not find the "nearest" watchpoint to + // disable/step/re-enable it, so one of the valid watchpoint + // addresses should be provided as \a wp_addr. StringExtractor desc_extractor(description.c_str()); addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS); uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32); addr_t wp_hit_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS); watch_id_t watch_id = LLDB_INVALID_WATCH_ID; - if (wp_addr != LLDB_INVALID_ADDRESS) { - WatchpointSP wp_sp; + bool silently_continue = false; + WatchpointSP wp_sp; + if (wp_hit_addr != LLDB_INVALID_ADDRESS) { + wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr); + // On MIPS, \a wp_hit_addr outside the range of a watched + // region means we should silently continue, it is a false hit. ArchSpec::Core core = GetTarget().GetArchitecture().GetCore(); - if ((core >= ArchSpec::kCore_mips_first && - core <= ArchSpec::kCore_mips_last) || - (core >= ArchSpec::eCore_arm_generic && - core <= ArchSpec::eCore_arm_aarch64)) - wp_sp = - GetTarget().GetWatchpointList().FindByAddress(wp_hit_addr); - if (!wp_sp) - wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr); - if (wp_sp) { - wp_sp->SetHardwareIndex(wp_index); - watch_id = wp_sp->GetID(); - } + if (!wp_sp && core >= ArchSpec::kCore_mips_first && + core <= ArchSpec::kCore_mips_last) + silently_continue = true; + } + if (!wp_sp && wp_addr != LLDB_INVALID_ADDRESS) + wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr); + if (wp_sp) { + wp_sp->SetHardwareIndex(wp_index); + watch_id = wp_sp->GetID(); } if (watch_id == LLDB_INVALID_WATCH_ID) { Log *log(GetLog(GDBRLog::Watchpoints)); LLDB_LOGF(log, "failed to find watchpoint"); } thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID( - *thread_sp, watch_id, wp_hit_addr)); + *thread_sp, watch_id, silently_continue)); handled = true; } else if (reason == "exception") { thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException( @@ -1939,23 +1975,24 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { StructuredData::Object *object) -> bool { if (key == g_key_tid) { // thread in big endian hex - tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID); + tid = object->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID); } else if (key == g_key_metype) { // exception type in big endian hex - exc_type = object->GetIntegerValue(0); + exc_type = object->GetUnsignedIntegerValue(0); } else if (key == g_key_medata) { // exception data in big endian hex StructuredData::Array *array = object->GetAsArray(); if (array) { array->ForEach([&exc_data](StructuredData::Object *object) -> bool { - exc_data.push_back(object->GetIntegerValue()); + exc_data.push_back(object->GetUnsignedIntegerValue()); return true; // Keep iterating through all array items }); } } else if (key == g_key_name) { thread_name = std::string(object->GetStringValue()); } else if (key == g_key_qaddr) { - thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS); + thread_dispatch_qaddr = + object->GetUnsignedIntegerValue(LLDB_INVALID_ADDRESS); } else if (key == g_key_queue_name) { queue_vars_valid = true; queue_name = std::string(object->GetStringValue()); @@ -1969,11 +2006,11 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { queue_kind = eQueueKindConcurrent; } } else if (key == g_key_queue_serial_number) { - queue_serial_number = object->GetIntegerValue(0); + queue_serial_number = object->GetUnsignedIntegerValue(0); if (queue_serial_number != 0) queue_vars_valid = true; } else if (key == g_key_dispatch_queue_t) { - dispatch_queue_t = object->GetIntegerValue(0); + dispatch_queue_t = object->GetUnsignedIntegerValue(0); if (dispatch_queue_t != 0 && dispatch_queue_t != LLDB_INVALID_ADDRESS) queue_vars_valid = true; } else if (key == g_key_associated_with_dispatch_queue) { @@ -2034,7 +2071,7 @@ ProcessGDBRemote::SetThreadStopInfo(StructuredData::Dictionary *thread_dict) { } } else if (key == g_key_signal) - signo = object->GetIntegerValue(LLDB_INVALID_SIGNAL_NUMBER); + signo = object->GetUnsignedIntegerValue(LLDB_INVALID_SIGNAL_NUMBER); return true; // Keep iterating through all dictionary key/value pairs }); @@ -2202,6 +2239,9 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { if (wp_sp) wp_index = wp_sp->GetHardwareIndex(); + // Rewrite gdb standard watch/rwatch/awatch to + // "reason:watchpoint" + "description:ADDR", + // which is parsed in SetThreadStopInfo. reason = "watchpoint"; StreamString ostr; ostr.Printf("%" PRIu64 " %" PRIu32, wp_addr, wp_index); @@ -2226,6 +2266,13 @@ StateType ProcessGDBRemote::SetThreadStopInfo(StringExtractor &stop_packet) { StreamString ostr; ostr.Printf("%" PRIu64 " %" PRIu64, pid_tid->first, pid_tid->second); description = std::string(ostr.GetString()); + } else if (key.compare("addressing_bits") == 0) { + uint64_t addressing_bits; + if (!value.getAsInteger(0, addressing_bits)) { + addr_t address_mask = ~((1ULL << addressing_bits) - 1); + SetCodeAddressMask(address_mask); + SetDataAddressMask(address_mask); + } } else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1])) { uint32_t reg = UINT32_MAX; if (!key.getAsInteger(16, reg)) @@ -2818,16 +2865,12 @@ Status ProcessGDBRemote::DoGetMemoryRegionInfo(addr_t load_addr, return error; } -Status ProcessGDBRemote::GetWatchpointSupportInfo(uint32_t &num) { - - Status error(m_gdb_comm.GetWatchpointSupportInfo(num)); - return error; +std::optional<uint32_t> ProcessGDBRemote::GetWatchpointSlotCount() { + return m_gdb_comm.GetWatchpointSlotCount(); } -Status ProcessGDBRemote::GetWatchpointSupportInfo(uint32_t &num, bool &after) { - Status error(m_gdb_comm.GetWatchpointSupportInfo( - num, after, GetTarget().GetArchitecture())); - return error; +std::optional<bool> ProcessGDBRemote::DoGetWatchpointReportedAfter() { + return m_gdb_comm.GetWatchpointReportedAfter(); } Status ProcessGDBRemote::DoDeallocateMemory(lldb::addr_t addr) { @@ -3372,8 +3415,7 @@ void ProcessGDBRemote::DebuggerInitialize(Debugger &debugger) { const bool is_global_setting = true; PluginManager::CreateSettingForProcessPlugin( debugger, GetGlobalPluginProperties().GetValueProperties(), - ConstString("Properties for the gdb-remote process plug-in."), - is_global_setting); + "Properties for the gdb-remote process plug-in.", is_global_setting); } } @@ -3393,7 +3435,7 @@ bool ProcessGDBRemote::StartAsyncThread() { }); if (!async_thread) { LLDB_LOG_ERROR(GetLog(LLDBLog::Host), async_thread.takeError(), - "failed to launch host thread: {}"); + "failed to launch host thread: {0}"); return false; } m_async_thread = *async_thread; @@ -3753,8 +3795,7 @@ ProcessGDBRemote::GetExtendedInfoForThread(lldb::tid_t tid) { response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + object_sp = StructuredData::ParseJSON(response.GetStringRef()); } } } @@ -3786,10 +3827,8 @@ StructuredData::ObjectSP ProcessGDBRemote::GetLoadedDynamicLibrariesInfos( StructuredData::ObjectSP args_dict(new StructuredData::Dictionary()); StructuredData::ArraySP addresses(new StructuredData::Array); - for (auto addr : load_addresses) { - StructuredData::ObjectSP addr_sp(new StructuredData::Integer(addr)); - addresses->AddItem(addr_sp); - } + for (auto addr : load_addresses) + addresses->AddIntegerItem(addr); args_dict->GetAsDictionary()->AddItem("solib_addresses", addresses); @@ -3825,8 +3864,7 @@ ProcessGDBRemote::GetLoadedDynamicLibrariesInfos_sender( response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + object_sp = StructuredData::ParseJSON(response.GetStringRef()); } } } @@ -3848,8 +3886,7 @@ StructuredData::ObjectSP ProcessGDBRemote::GetDynamicLoaderProcessState() { response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + object_sp = StructuredData::ParseJSON(response.GetStringRef()); } } } @@ -3881,8 +3918,7 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() { response.GetResponseType(); if (response_type == StringExtractorGDBRemote::eResponse) { if (!response.Empty()) { - object_sp = - StructuredData::ParseJSON(std::string(response.GetStringRef())); + object_sp = StructuredData::ParseJSON(response.GetStringRef()); } } } @@ -3891,7 +3927,7 @@ StructuredData::ObjectSP ProcessGDBRemote::GetSharedCacheInfo() { } Status ProcessGDBRemote::ConfigureStructuredData( - ConstString type_name, const StructuredData::ObjectSP &config_sp) { + llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) { return m_gdb_comm.ConfigureRemoteStructuredData(type_name, config_sp); } @@ -4033,15 +4069,212 @@ struct GdbServerTargetInfo { RegisterSetMap reg_set_map; }; -bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, - std::vector<DynamicRegisterInfo::Register> ®isters) { +static std::vector<RegisterFlags::Field> ParseFlagsFields(XMLNode flags_node, + unsigned size) { + Log *log(GetLog(GDBRLog::Process)); + const unsigned max_start_bit = size * 8 - 1; + + // Process the fields of this set of flags. + std::vector<RegisterFlags::Field> fields; + flags_node.ForEachChildElementWithName("field", [&fields, max_start_bit, + &log](const XMLNode + &field_node) { + std::optional<llvm::StringRef> name; + std::optional<unsigned> start; + std::optional<unsigned> end; + + field_node.ForEachAttribute([&name, &start, &end, max_start_bit, + &log](const llvm::StringRef &attr_name, + const llvm::StringRef &attr_value) { + // Note that XML in general requires that each of these attributes only + // appears once, so we don't have to handle that here. + if (attr_name == "name") { + LLDB_LOG(log, + "ProcessGDBRemote::ParseFlags Found field node name \"{0}\"", + attr_value.data()); + name = attr_value; + } else if (attr_name == "start") { + unsigned parsed_start = 0; + if (llvm::to_integer(attr_value, parsed_start)) { + if (parsed_start > max_start_bit) { + LLDB_LOG( + log, + "ProcessGDBRemote::ParseFlags Invalid start {0} in field node, " + "cannot be > {1}", + parsed_start, max_start_bit); + } else + start = parsed_start; + } else { + LLDB_LOG(log, + "ProcessGDBRemote::ParseFlags Invalid start \"{0}\" in " + "field node", + attr_value.data()); + } + } else if (attr_name == "end") { + unsigned parsed_end = 0; + if (llvm::to_integer(attr_value, parsed_end)) + if (parsed_end > max_start_bit) { + LLDB_LOG( + log, + "ProcessGDBRemote::ParseFlags Invalid end {0} in field node, " + "cannot be > {1}", + parsed_end, max_start_bit); + } else + end = parsed_end; + else { + LLDB_LOG( + log, + "ProcessGDBRemote::ParseFlags Invalid end \"{0}\" in field node", + attr_value.data()); + } + } else if (attr_name == "type") { + // Type is a known attribute but we do not currently use it and it is + // not required. + } else { + LLDB_LOG(log, + "ProcessGDBRemote::ParseFlags Ignoring unknown attribute " + "\"{0}\" in field node", + attr_name.data()); + } + + return true; // Walk all attributes of the field. + }); + + if (name && start && end) { + if (*start > *end) { + LLDB_LOG(log, + "ProcessGDBRemote::ParseFlags Start {0} > end {1} in field " + "\"{2}\", ignoring", + *start, *end, name->data()); + } else { + fields.push_back(RegisterFlags::Field(name->str(), *start, *end)); + } + } + + return true; // Iterate all "field" nodes. + }); + return fields; +} + +void ParseFlags( + XMLNode feature_node, + llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types) { + Log *log(GetLog(GDBRLog::Process)); + + feature_node.ForEachChildElementWithName( + "flags", + [&log, ®isters_flags_types](const XMLNode &flags_node) -> bool { + LLDB_LOG(log, "ProcessGDBRemote::ParseFlags Found flags node \"{0}\"", + flags_node.GetAttributeValue("id").c_str()); + + std::optional<llvm::StringRef> id; + std::optional<unsigned> size; + flags_node.ForEachAttribute( + [&id, &size, &log](const llvm::StringRef &name, + const llvm::StringRef &value) { + if (name == "id") { + id = value; + } else if (name == "size") { + unsigned parsed_size = 0; + if (llvm::to_integer(value, parsed_size)) + size = parsed_size; + else { + LLDB_LOG(log, + "ProcessGDBRemote::ParseFlags Invalid size \"{0}\" " + "in flags node", + value.data()); + } + } else { + LLDB_LOG(log, + "ProcessGDBRemote::ParseFlags Ignoring unknown " + "attribute \"{0}\" in flags node", + name.data()); + } + return true; // Walk all attributes. + }); + + if (id && size) { + // Process the fields of this set of flags. + std::vector<RegisterFlags::Field> fields = + ParseFlagsFields(flags_node, *size); + if (fields.size()) { + // Sort so that the fields with the MSBs are first. + std::sort(fields.rbegin(), fields.rend()); + std::vector<RegisterFlags::Field>::const_iterator overlap = + std::adjacent_find(fields.begin(), fields.end(), + [](const RegisterFlags::Field &lhs, + const RegisterFlags::Field &rhs) { + return lhs.Overlaps(rhs); + }); + + // If no fields overlap, use them. + if (overlap == fields.end()) { + if (registers_flags_types.contains(*id)) { + // In theory you could define some flag set, use it with a + // register then redefine it. We do not know if anyone does + // that, or what they would expect to happen in that case. + // + // LLDB chooses to take the first definition and ignore the rest + // as waiting until everything has been processed is more + // expensive and difficult. This means that pointers to flag + // sets in the register info remain valid if later the flag set + // is redefined. If we allowed redefinitions, LLDB would crash + // when you tried to print a register that used the original + // definition. + LLDB_LOG( + log, + "ProcessGDBRemote::ParseFlags Definition of flags " + "\"{0}\" shadows " + "previous definition, using original definition instead.", + id->data()); + } else { + registers_flags_types.insert_or_assign( + *id, std::make_unique<RegisterFlags>(id->str(), *size, + std::move(fields))); + } + } else { + // If any fields overlap, ignore the whole set of flags. + std::vector<RegisterFlags::Field>::const_iterator next = + std::next(overlap); + LLDB_LOG( + log, + "ProcessGDBRemote::ParseFlags Ignoring flags because fields " + "{0} (start: {1} end: {2}) and {3} (start: {4} end: {5}) " + "overlap.", + overlap->GetName().c_str(), overlap->GetStart(), + overlap->GetEnd(), next->GetName().c_str(), next->GetStart(), + next->GetEnd()); + } + } else { + LLDB_LOG( + log, + "ProcessGDBRemote::ParseFlags Ignoring definition of flags " + "\"{0}\" because it contains no fields.", + id->data()); + } + } + + return true; // Keep iterating through all "flags" elements. + }); +} + +bool ParseRegisters( + XMLNode feature_node, GdbServerTargetInfo &target_info, + std::vector<DynamicRegisterInfo::Register> ®isters, + llvm::StringMap<std::unique_ptr<RegisterFlags>> ®isters_flags_types) { if (!feature_node) return false; Log *log(GetLog(GDBRLog::Process)); + ParseFlags(feature_node, registers_flags_types); + for (const auto &flags : registers_flags_types) + flags.second->log(log); + feature_node.ForEachChildElementWithName( - "reg", [&target_info, ®isters, log](const XMLNode ®_node) -> bool { + "reg", + [&target_info, ®isters, ®isters_flags_types, + log](const XMLNode ®_node) -> bool { std::string gdb_group; std::string gdb_type; DynamicRegisterInfo::Register reg_info; @@ -4117,29 +4350,51 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, return true; // Keep iterating through all attributes }); - if (!gdb_type.empty() && !(encoding_set || format_set)) { - if (llvm::StringRef(gdb_type).startswith("int")) { - reg_info.format = eFormatHex; - reg_info.encoding = eEncodingUint; - } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") { - reg_info.format = eFormatAddressInfo; - reg_info.encoding = eEncodingUint; - } else if (gdb_type == "float") { - reg_info.format = eFormatFloat; - reg_info.encoding = eEncodingIEEE754; - } else if (gdb_type == "aarch64v" || - llvm::StringRef(gdb_type).startswith("vec") || - gdb_type == "i387_ext" || gdb_type == "uint128") { - // lldb doesn't handle 128-bit uints correctly (for ymm*h), so treat - // them as vector (similarly to xmm/ymm) - reg_info.format = eFormatVectorOfUInt8; - reg_info.encoding = eEncodingVector; - } else { - LLDB_LOGF( - log, - "ProcessGDBRemote::ParseRegisters Could not determine lldb" - "format and encoding for gdb type %s", - gdb_type.c_str()); + if (!gdb_type.empty()) { + // gdb_type could reference some flags type defined in XML. + llvm::StringMap<std::unique_ptr<RegisterFlags>>::iterator it = + registers_flags_types.find(gdb_type); + if (it != registers_flags_types.end()) { + auto flags_type = it->second.get(); + if (reg_info.byte_size == flags_type->GetSize()) + reg_info.flags_type = flags_type; + else + LLDB_LOGF(log, + "ProcessGDBRemote::ParseRegisters Size of register " + "flags %s (%d bytes) for " + "register %s does not match the register size (%d " + "bytes). Ignoring this set of flags.", + flags_type->GetID().c_str(), flags_type->GetSize(), + reg_info.name.AsCString(), reg_info.byte_size); + } + + // There's a slim chance that the gdb_type name is both a flags type + // and a simple type. Just in case, look for that too (setting both + // does no harm). + if (!gdb_type.empty() && !(encoding_set || format_set)) { + if (llvm::StringRef(gdb_type).startswith("int")) { + reg_info.format = eFormatHex; + reg_info.encoding = eEncodingUint; + } else if (gdb_type == "data_ptr" || gdb_type == "code_ptr") { + reg_info.format = eFormatAddressInfo; + reg_info.encoding = eEncodingUint; + } else if (gdb_type == "float") { + reg_info.format = eFormatFloat; + reg_info.encoding = eEncodingIEEE754; + } else if (gdb_type == "aarch64v" || + llvm::StringRef(gdb_type).startswith("vec") || + gdb_type == "i387_ext" || gdb_type == "uint128") { + // lldb doesn't handle 128-bit uints correctly (for ymm*h), so + // treat them as vector (similarly to xmm/ymm) + reg_info.format = eFormatVectorOfUInt8; + reg_info.encoding = eEncodingVector; + } else { + LLDB_LOGF( + log, + "ProcessGDBRemote::ParseRegisters Could not determine lldb" + "format and encoding for gdb type %s", + gdb_type.c_str()); + } } } @@ -4271,8 +4526,8 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( if (arch_to_use.IsValid()) { for (auto &feature_node : feature_nodes) { - ParseRegisters(feature_node, target_info, - registers); + ParseRegisters(feature_node, target_info, registers, + m_registers_flags_types); } for (const auto &include : target_info.includes) { @@ -4337,6 +4592,13 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { if (!m_gdb_comm.GetQXferFeaturesReadSupported()) return false; + // This holds register flags information for the whole of target.xml. + // target.xml may include further documents that + // GetGDBServerRegisterInfoXMLAndProcess will recurse to fetch and process. + // That's why we clear the cache here, and not in + // GetGDBServerRegisterInfoXMLAndProcess. To prevent it being cleared on every + // include read. + m_registers_flags_types.clear(); std::vector<DynamicRegisterInfo::Register> registers; if (GetGDBServerRegisterInfoXMLAndProcess(arch_to_use, "target.xml", registers)) @@ -4844,8 +5106,7 @@ ParseStructuredDataPacket(llvm::StringRef packet) { } // This is an asynchronous JSON packet, destined for a StructuredDataPlugin. - StructuredData::ObjectSP json_sp = - StructuredData::ParseJSON(std::string(packet)); + StructuredData::ObjectSP json_sp = StructuredData::ParseJSON(packet); if (log) { if (json_sp) { StreamString json_str; @@ -4961,7 +5222,7 @@ public: ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr(); if (process) { - process->GetGDBRemote().DumpHistory(result.GetOutputStream()); + process->DumpPluginHistory(result.GetOutputStream()); result.SetStatus(eReturnStatusSuccessFinishResult); return true; } 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 83f0adfe35af..f0ead4c38c23 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 @@ -38,6 +38,7 @@ #include "GDBRemoteRegisterContext.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" namespace lldb_private { namespace repro { @@ -76,6 +77,8 @@ public: bool plugin_specified_by_name) override; CommandObject *GetPluginCommandObject() override; + + void DumpPluginHistory(Stream &s) override; // Creating a new process, or attaching to an existing one Status DoWillLaunch(Module *module) override; @@ -159,7 +162,7 @@ public: Status DisableWatchpoint(Watchpoint *wp, bool notify = true) override; - Status GetWatchpointSupportInfo(uint32_t &num) override; + std::optional<uint32_t> GetWatchpointSlotCount() override; llvm::Expected<TraceSupportedResponse> TraceSupported() override; @@ -172,7 +175,7 @@ public: llvm::Expected<std::vector<uint8_t>> TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override; - Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override; + std::optional<bool> DoGetWatchpointReportedAfter() override; bool StartNoticingNewThreads() override; @@ -210,7 +213,7 @@ public: lldb::addr_t image_count) override; Status - ConfigureStructuredData(ConstString type_name, + ConfigureStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) override; StructuredData::ObjectSP GetLoadedDynamicLibrariesInfos() override; @@ -466,6 +469,15 @@ private: // fork helpers void DidForkSwitchSoftwareBreakpoints(bool enable); void DidForkSwitchHardwareTraps(bool enable); + + // Lists of register fields generated from the remote's target XML. + // Pointers to these RegisterFlags will be set in the register info passed + // back to the upper levels of lldb. Doing so is safe because this class will + // live at least as long as the debug session. We therefore do not store the + // data directly in the map because the map may reallocate it's storage as new + // entries are added. Which would invalidate any pointers set in the register + // info up to that point. + llvm::StringMap<std::unique_ptr<RegisterFlags>> m_registers_flags_types; }; } // namespace process_gdb_remote 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 5911b137ef41..99d0b54c40f9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -34,6 +34,7 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" +#include "Plugins/ObjectFile/Placeholder/ObjectFilePlaceholder.h" #include "Plugins/Process/Utility/StopInfoMachException.h" #include <memory> @@ -47,84 +48,6 @@ LLDB_PLUGIN_DEFINE(ProcessMinidump) namespace { -/// A minimal ObjectFile implementation providing a dummy object file for the -/// cases when the real module binary is not available. This allows the module -/// to show up in "image list" and symbols to be added to it. -class PlaceholderObjectFile : public ObjectFile { -public: - PlaceholderObjectFile(const lldb::ModuleSP &module_sp, - const ModuleSpec &module_spec, lldb::addr_t base, - lldb::addr_t size) - : ObjectFile(module_sp, &module_spec.GetFileSpec(), /*file_offset*/ 0, - /*length*/ 0, /*data_sp*/ nullptr, /*data_offset*/ 0), - m_arch(module_spec.GetArchitecture()), m_uuid(module_spec.GetUUID()), - m_base(base), m_size(size) { - m_symtab_up = std::make_unique<Symtab>(this); - } - - static ConstString GetStaticPluginName() { - return ConstString("placeholder"); - } - llvm::StringRef GetPluginName() override { - return GetStaticPluginName().GetStringRef(); - } - bool ParseHeader() override { return true; } - Type CalculateType() override { return eTypeUnknown; } - Strata CalculateStrata() override { return eStrataUnknown; } - uint32_t GetDependentModules(FileSpecList &file_list) override { return 0; } - bool IsExecutable() const override { return false; } - ArchSpec GetArchitecture() override { return m_arch; } - UUID GetUUID() override { return m_uuid; } - void ParseSymtab(lldb_private::Symtab &symtab) override {} - bool IsStripped() override { return true; } - ByteOrder GetByteOrder() const override { return m_arch.GetByteOrder(); } - - uint32_t GetAddressByteSize() const override { - return m_arch.GetAddressByteSize(); - } - - Address GetBaseAddress() override { - return Address(m_sections_up->GetSectionAtIndex(0), 0); - } - - void CreateSections(SectionList &unified_section_list) override { - m_sections_up = std::make_unique<SectionList>(); - auto section_sp = std::make_shared<Section>( - GetModule(), this, /*sect_id*/ 0, ConstString(".module_image"), - eSectionTypeOther, m_base, m_size, /*file_offset*/ 0, /*file_size*/ 0, - /*log2align*/ 0, /*flags*/ 0); - section_sp->SetPermissions(ePermissionsReadable | ePermissionsExecutable); - m_sections_up->AddSection(section_sp); - unified_section_list.AddSection(std::move(section_sp)); - } - - bool SetLoadAddress(Target &target, addr_t value, - bool value_is_offset) override { - assert(!value_is_offset); - assert(value == m_base); - - // Create sections if they haven't been created already. - GetModule()->GetSectionList(); - assert(m_sections_up->GetNumSections(0) == 1); - - target.GetSectionLoadList().SetSectionLoadAddress( - m_sections_up->GetSectionAtIndex(0), m_base); - return true; - } - - void Dump(Stream *s) override { - s->Format("Placeholder object file for {0} loaded at [{1:x}-{2:x})\n", - GetFileSpec(), m_base, m_base + m_size); - } - - lldb::addr_t GetBaseImageAddress() const { return m_base; } -private: - ArchSpec m_arch; - UUID m_uuid; - lldb::addr_t m_base; - lldb::addr_t m_size; -}; - /// Duplicate the HashElfTextSection() from the breakpad sources. /// /// Breakpad, a Google crash log reporting tool suite, creates minidump files @@ -544,7 +467,7 @@ void ProcessMinidump::ReadModuleList() { // check if the process is wow64 - a 32 bit windows process running on a // 64 bit windows - if (llvm::StringRef(name).endswith_insensitive("wow64.dll")) { + if (llvm::StringRef(name).ends_with_insensitive("wow64.dll")) { m_is_wow64 = true; } @@ -578,12 +501,12 @@ void ProcessMinidump::ReadModuleList() { // Watch out for place holder modules that have different paths, but the // same UUID. If the base address is different, create a new module. If // we don't then we will end up setting the load address of a different - // PlaceholderObjectFile and an assertion will fire. + // ObjectFilePlaceholder and an assertion will fire. auto *objfile = module_sp->GetObjectFile(); if (objfile && objfile->GetPluginName() == - PlaceholderObjectFile::GetStaticPluginName().GetStringRef()) { - if (((PlaceholderObjectFile *)objfile)->GetBaseImageAddress() != + ObjectFilePlaceholder::GetPluginNameStatic()) { + if (((ObjectFilePlaceholder *)objfile)->GetBaseImageAddress() != load_addr) module_sp.reset(); } @@ -601,7 +524,7 @@ void ProcessMinidump::ReadModuleList() { "placeholder module for: {0}", name); - module_sp = Module::CreateModuleFromObjectFile<PlaceholderObjectFile>( + module_sp = Module::CreateModuleFromObjectFile<ObjectFilePlaceholder>( module_spec, load_addr, load_size); GetTarget().GetImages().Append(module_sp, true /* notify */); } diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp index 9e1e4317cd14..0004d5d8d07e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -31,6 +31,7 @@ using namespace minidump; { \ "r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ {ehframe_r##i, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, \ + nullptr, \ } #define DEF_R_ARG(i, n) \ @@ -38,27 +39,28 @@ using namespace minidump; "r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ {ehframe_r##i, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, \ reg_r##i}, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEF_D(i) \ { \ "d" #i, nullptr, 8, OFFSET(d) + i * 8, eEncodingVector, \ eFormatVectorOfUInt8, {dwarf_d##i, dwarf_d##i, INV, INV, reg_d##i}, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEF_S(i) \ { \ "s" #i, nullptr, 4, OFFSET(s) + i * 4, eEncodingIEEE754, eFormatFloat, \ {dwarf_s##i, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, \ + nullptr, \ } #define DEF_Q(i) \ { \ "q" #i, nullptr, 16, OFFSET(q) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {dwarf_q##i, dwarf_q##i, INV, INV, reg_q##i}, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } // Zero based LLDB register numbers for this register context @@ -176,6 +178,7 @@ static RegisterInfo g_reg_info_apple_fp = { {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, nullptr, nullptr, + nullptr, }; static RegisterInfo g_reg_info_fp = { @@ -188,6 +191,7 @@ static RegisterInfo g_reg_info_fp = { {ehframe_r11, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, nullptr, nullptr, + nullptr, }; // Register info definitions for this register context @@ -214,6 +218,7 @@ static RegisterInfo g_reg_infos[] = { {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, nullptr, nullptr, + nullptr, }, {"lr", "r14", @@ -224,6 +229,7 @@ static RegisterInfo g_reg_infos[] = { {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, nullptr, nullptr, + nullptr, }, {"pc", "r15", @@ -234,6 +240,7 @@ static RegisterInfo g_reg_infos[] = { {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, nullptr, nullptr, + nullptr, }, {"cpsr", "psr", @@ -244,6 +251,7 @@ static RegisterInfo g_reg_infos[] = { {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, nullptr, nullptr, + nullptr, }, {"fpscr", nullptr, @@ -254,6 +262,7 @@ static RegisterInfo g_reg_infos[] = { {INV, INV, INV, INV, reg_fpscr}, nullptr, nullptr, + nullptr, }, DEF_D(0), DEF_D(1), diff --git a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp index 78190182f548..a0476c962070 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -29,48 +29,48 @@ using namespace minidump; { \ "x" #i, nullptr, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ {arm64_dwarf::x##i, arm64_dwarf::x##i, INV, INV, reg_x##i}, \ - nullptr, nullptr, \ + nullptr, nullptr, nullptr, \ } #define DEF_W(i) \ { \ "w" #i, nullptr, 4, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ - {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, \ + {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, \ } #define DEF_X_ARG(i, n) \ { \ "x" #i, "arg" #n, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ {arm64_dwarf::x##i, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, \ - INV, reg_x##i}, nullptr, nullptr, \ + INV, reg_x##i}, nullptr, nullptr, nullptr, \ } #define DEF_V(i) \ { \ "v" #i, nullptr, 16, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {arm64_dwarf::v##i, arm64_dwarf::v##i, INV, INV, \ - reg_v##i}, nullptr, nullptr, \ + reg_v##i}, nullptr, nullptr, nullptr, \ } #define DEF_D(i) \ { \ "d" #i, nullptr, 8, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \ - nullptr, \ + nullptr, nullptr, \ } #define DEF_S(i) \ { \ "s" #i, nullptr, 4, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \ - nullptr, \ + nullptr, nullptr, \ } #define DEF_H(i) \ { \ "h" #i, nullptr, 2, OFFSET(v) + i * 16, eEncodingVector, \ eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \ - nullptr, \ + nullptr, nullptr, \ } // Zero based LLDB register numbers for this register context @@ -316,6 +316,7 @@ static RegisterInfo g_reg_infos[] = { {arm64_dwarf::x29, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp}, nullptr, nullptr, + nullptr, }, {"lr", "x30", @@ -326,6 +327,7 @@ static RegisterInfo g_reg_infos[] = { {arm64_dwarf::x30, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, nullptr, nullptr, + nullptr, }, {"sp", "x31", @@ -336,6 +338,7 @@ static RegisterInfo g_reg_infos[] = { {arm64_dwarf::x31, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, nullptr, nullptr, + nullptr, }, {"pc", nullptr, @@ -346,6 +349,7 @@ static RegisterInfo g_reg_infos[] = { {arm64_dwarf::pc, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, nullptr, nullptr, + nullptr, }, // w0 - w31 DEF_W(0), @@ -389,6 +393,7 @@ static RegisterInfo g_reg_infos[] = { {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, nullptr, nullptr, + nullptr, }, {"fpsr", nullptr, @@ -399,6 +404,7 @@ static RegisterInfo g_reg_infos[] = { {INV, INV, INV, INV, reg_fpsr}, nullptr, nullptr, + nullptr, }, {"fpcr", nullptr, @@ -409,6 +415,7 @@ static RegisterInfo g_reg_infos[] = { {INV, INV, INV, INV, reg_fpcr}, nullptr, nullptr, + nullptr, }, // v0 - v31 DEF_V(0), 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 58629a5406f6..e99a2a08bd50 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -18,11 +18,11 @@ #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Interpreter/OptionGroupBoolean.h" #include "lldb/Interpreter/ScriptInterpreter.h" -#include "lldb/Interpreter/ScriptedMetadata.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Queue.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/ScriptedMetadata.h" #include "lldb/Utility/State.h" #include <mutex> @@ -47,11 +47,6 @@ bool ScriptedProcess::IsScriptLanguageSupported(lldb::ScriptLanguage language) { return llvm::is_contained(supported_languages, language); } -void ScriptedProcess::CheckInterpreterAndScriptObject() const { - lldbassert(m_interpreter && "Invalid Script Interpreter."); - lldbassert(m_script_object_sp && "Invalid Script Object."); -} - lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *file, @@ -66,8 +61,7 @@ lldb::ProcessSP ScriptedProcess::CreateInstance(lldb::TargetSP target_sp, auto process_sp = std::shared_ptr<ScriptedProcess>( new ScriptedProcess(target_sp, listener_sp, scripted_metadata, error)); - if (error.Fail() || !process_sp || !process_sp->m_script_object_sp || - !process_sp->m_script_object_sp->IsValid()) { + if (error.Fail() || !process_sp || !process_sp->m_interface_up) { LLDB_LOGF(GetLog(LLDBLog::Process), "%s", error.AsCString()); return nullptr; } @@ -92,17 +86,28 @@ ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp, return; } - m_interpreter = target_sp->GetDebugger().GetScriptInterpreter(); + ScriptInterpreter *interpreter = + target_sp->GetDebugger().GetScriptInterpreter(); - if (!m_interpreter) { + if (!interpreter) { error.SetErrorStringWithFormat("ScriptedProcess::%s () - ERROR: %s", __FUNCTION__, "Debugger has no Script Interpreter"); return; } + // Create process instance interface + m_interface_up = interpreter->CreateScriptedProcessInterface(); + if (!m_interface_up) { + error.SetErrorStringWithFormat( + "ScriptedProcess::%s () - ERROR: %s", __FUNCTION__, + "Script interpreter couldn't create Scripted Process Interface"); + return; + } + ExecutionContext exe_ctx(target_sp, /*get_process=*/false); + // Create process script object StructuredData::GenericSP object_sp = GetInterface().CreatePluginObject( m_scripted_metadata.GetClassName(), exe_ctx, m_scripted_metadata.GetArgsSP()); @@ -113,8 +118,6 @@ ScriptedProcess::ScriptedProcess(lldb::TargetSP target_sp, "Failed to create valid script object"); return; } - - m_script_object_sp = object_sp; } ScriptedProcess::~ScriptedProcess() { @@ -147,85 +150,64 @@ Status ScriptedProcess::DoLoadCore() { Status ScriptedProcess::DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) { - CheckInterpreterAndScriptObject(); - - /* FIXME: This doesn't reflect how lldb actually launches a process. - In reality, it attaches to debugserver, then resume the process. */ + LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s launching process", __FUNCTION__); + + /* MARK: This doesn't reflect how lldb actually launches a process. + In reality, it attaches to debugserver, then resume the process. + That's not true in all cases. If debugserver is remote, lldb + asks debugserver to launch the process for it. */ Status error = GetInterface().Launch(); - SetPrivateState(eStateRunning); - - if (error.Fail()) - return error; - - // TODO: Fetch next state from stopped event queue then send stop event - // const StateType state = SetThreadStopInfo(response); - // if (state != eStateInvalid) { - // SetPrivateState(state); - SetPrivateState(eStateStopped); - - return {}; + return error; } -void ScriptedProcess::DidLaunch() { - CheckInterpreterAndScriptObject(); +void ScriptedProcess::DidLaunch() { m_pid = GetInterface().GetProcessID(); } + +void ScriptedProcess::DidResume() { + // Update the PID again, in case the user provided a placeholder pid at launch m_pid = GetInterface().GetProcessID(); - GetLoadedDynamicLibrariesInfos(); } Status ScriptedProcess::DoResume() { - CheckInterpreterAndScriptObject(); + LLDB_LOGF(GetLog(LLDBLog::Process), "ScriptedProcess::%s resuming process", __FUNCTION__); - 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__, - StateAsCString(thread_resume_state)); - - bool resume = (thread_resume_state == eStateRunning); - assert(thread_resume_state == eStateRunning && "invalid thread resume state"); - - Status error; - if (resume) { - LLDB_LOGF(log, "ScriptedProcess::%s sending resume", __FUNCTION__); + return GetInterface().Resume(); +} - SetPrivateState(eStateRunning); - SetPrivateState(eStateStopped); - error = GetInterface().Resume(); - } +Status ScriptedProcess::DoAttach(const ProcessAttachInfo &attach_info) { + Status error = GetInterface().Attach(attach_info); + SetPrivateState(eStateRunning); + SetPrivateState(eStateStopped); + if (error.Fail()) + return error; + // NOTE: We need to set the PID before finishing to attach otherwise we will + // hit an assert when calling the attach completion handler. + DidLaunch(); - return error; + return {}; } -Status ScriptedProcess::DoStop() { - CheckInterpreterAndScriptObject(); - - Log *log = GetLog(LLDBLog::Process); +Status +ScriptedProcess::DoAttachToProcessWithID(lldb::pid_t pid, + const ProcessAttachInfo &attach_info) { + return DoAttach(attach_info); +} - if (GetInterface().ShouldStop()) { - SetPrivateState(eStateStopped); - LLDB_LOGF(log, "ScriptedProcess::%s Immediate stop", __FUNCTION__); - return {}; - } +Status ScriptedProcess::DoAttachToProcessWithName( + const char *process_name, const ProcessAttachInfo &attach_info) { + return DoAttach(attach_info); +} - LLDB_LOGF(log, "ScriptedProcess::%s Delayed stop", __FUNCTION__); - return GetInterface().Stop(); +void ScriptedProcess::DidAttach(ArchSpec &process_arch) { + process_arch = GetArchitecture(); } Status ScriptedProcess::DoDestroy() { return Status(); } -bool ScriptedProcess::IsAlive() { - if (m_interpreter && m_script_object_sp) - return GetInterface().IsAlive(); - return false; -} +bool ScriptedProcess::IsAlive() { return GetInterface().IsAlive(); } size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) { - if (!m_interpreter) - return ScriptedInterface::ErrorWithMessage<size_t>( - LLVM_PRETTY_FUNCTION, "No interpreter.", error); - lldb::DataExtractorSP data_extractor_sp = GetInterface().ReadMemoryAtAddress(addr, size, error); @@ -239,7 +221,48 @@ size_t ScriptedProcess::DoReadMemory(lldb::addr_t addr, void *buf, size_t size, return ScriptedInterface::ErrorWithMessage<size_t>( LLVM_PRETTY_FUNCTION, "Failed to copy read memory to buffer.", error); - return size; + // FIXME: We should use the diagnostic system to report a warning if the + // `bytes_copied` is different from `size`. + + return bytes_copied; +} + +size_t ScriptedProcess::DoWriteMemory(lldb::addr_t vm_addr, const void *buf, + size_t size, Status &error) { + lldb::DataExtractorSP data_extractor_sp = std::make_shared<DataExtractor>( + buf, size, GetByteOrder(), GetAddressByteSize()); + + if (!data_extractor_sp || !data_extractor_sp->GetByteSize()) + return 0; + + lldb::offset_t bytes_written = + GetInterface().WriteMemoryAtAddress(vm_addr, data_extractor_sp, error); + + if (!bytes_written || bytes_written == LLDB_INVALID_OFFSET) + return ScriptedInterface::ErrorWithMessage<size_t>( + LLVM_PRETTY_FUNCTION, "Failed to copy write buffer to memory.", error); + + // FIXME: We should use the diagnostic system to report a warning if the + // `bytes_written` is different from `size`. + + return bytes_written; +} + +Status ScriptedProcess::EnableBreakpointSite(BreakpointSite *bp_site) { + assert(bp_site != nullptr); + + if (bp_site->IsEnabled()) { + return {}; + } + + if (bp_site->HardwareRequired()) { + return Status("Scripted Processes don't support hardware breakpoints"); + } + + Status error; + GetInterface().CreateBreakpoint(bp_site->GetLoadAddress(), error); + + return error; } ArchSpec ScriptedProcess::GetArchitecture() { @@ -248,8 +271,6 @@ ArchSpec ScriptedProcess::GetArchitecture() { Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo ®ion) { - CheckInterpreterAndScriptObject(); - Status error; if (auto region_or_err = GetInterface().GetMemoryRegionContainingAddress(load_addr, error)) @@ -259,8 +280,6 @@ Status ScriptedProcess::DoGetMemoryRegionInfo(lldb::addr_t load_addr, } Status ScriptedProcess::GetMemoryRegions(MemoryRegionInfos ®ion_list) { - CheckInterpreterAndScriptObject(); - Status error; lldb::addr_t address = 0; @@ -286,22 +305,9 @@ bool ScriptedProcess::DoUpdateThreadList(ThreadList &old_thread_list, // This is supposed to get the current set of threads, if any of them are in // old_thread_list then they get copied to new_thread_list, and then any // actually new threads will get added to new_thread_list. - - CheckInterpreterAndScriptObject(); m_thread_plans.ClearThreadCache(); Status error; - ScriptLanguage language = m_interpreter->GetLanguage(); - - if (language != eScriptLanguagePython) - return ScriptedInterface::ErrorWithMessage<bool>( - LLVM_PRETTY_FUNCTION, - llvm::Twine("ScriptInterpreter language (" + - llvm::Twine(m_interpreter->LanguageToString(language)) + - llvm::Twine(") not supported.")) - .str(), - error); - StructuredData::DictionarySP thread_info_sp = GetInterface().GetThreadsInfo(); if (!thread_info_sp) @@ -400,8 +406,6 @@ bool ScriptedProcess::GetProcessInfo(ProcessInstanceInfo &info) { lldb_private::StructuredData::ObjectSP ScriptedProcess::GetLoadedDynamicLibrariesInfos() { - CheckInterpreterAndScriptObject(); - Status error; auto error_with_message = [&error](llvm::StringRef message) { return ScriptedInterface::ErrorWithMessage<bool>(LLVM_PRETTY_FUNCTION, @@ -452,7 +456,7 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { 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; + lldb::offset_t slide = LLDB_INVALID_OFFSET; dict->GetValueForKeyAsInteger("load_addr", load_addr); dict->GetValueForKeyAsInteger("slide", slide); if (load_addr == LLDB_INVALID_ADDRESS) @@ -486,8 +490,6 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() { } lldb_private::StructuredData::DictionarySP ScriptedProcess::GetMetadata() { - CheckInterpreterAndScriptObject(); - StructuredData::DictionarySP metadata_sp = GetInterface().GetMetadata(); Status error; @@ -499,7 +501,7 @@ lldb_private::StructuredData::DictionarySP ScriptedProcess::GetMetadata() { } void ScriptedProcess::UpdateQueueListIfNeeded() { - CheckInterpreterAndScriptObject(); + CheckScriptedInterface(); for (ThreadSP thread_sp : Threads()) { if (const char *queue_name = thread_sp->GetQueueName()) { QueueSP queue_sp = std::make_shared<Queue>( @@ -510,5 +512,15 @@ void ScriptedProcess::UpdateQueueListIfNeeded() { } ScriptedProcessInterface &ScriptedProcess::GetInterface() const { - return m_interpreter->GetScriptedProcessInterface(); + CheckScriptedInterface(); + return *m_interface_up; +} + +void *ScriptedProcess::GetImplementation() { + StructuredData::GenericSP object_instance_sp = + GetInterface().GetScriptObjectInstance(); + if (object_instance_sp && + object_instance_sp->GetType() == eStructuredDataTypeGeneric) + return object_instance_sp->GetAsGeneric()->GetValue(); + return nullptr; } 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 6e13e68c4828..0335364b4010 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -9,9 +9,10 @@ #ifndef LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H #define LLDB_SOURCE_PLUGINS_SCRIPTED_PROCESS_H -#include "lldb/Interpreter/ScriptedMetadata.h" #include "lldb/Target/Process.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/ScriptedMetadata.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "ScriptedThread.h" @@ -49,8 +50,19 @@ public: void DidLaunch() override; + void DidResume() override; + Status DoResume() override; + Status DoAttachToProcessWithID(lldb::pid_t pid, + const ProcessAttachInfo &attach_info) override; + + Status + DoAttachToProcessWithName(const char *process_name, + const ProcessAttachInfo &attach_info) override; + + void DidAttach(ArchSpec &process_arch) override; + Status DoDestroy() override; void RefreshStateAfterStop() override; @@ -60,6 +72,11 @@ public: size_t DoReadMemory(lldb::addr_t addr, void *buf, size_t size, Status &error) override; + size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, + Status &error) override; + + Status EnableBreakpointSite(BreakpointSite *bp_site) override; + ArchSpec GetArchitecture(); Status @@ -74,12 +91,21 @@ public: void UpdateQueueListIfNeeded() override; + void *GetImplementation() override; + + void ForceScriptedState(lldb::StateType state) override { + // If we're about to stop, we should fetch the loaded dynamic libraries + // dictionary before emitting the private stop event to avoid having the + // module loading happen while the process state is changing. + if (StateIsStoppedState(state, true)) + GetLoadedDynamicLibrariesInfos(); + SetPrivateState(state); + } + protected: ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const ScriptedMetadata &scripted_metadata, Status &error); - Status DoStop(); - void Clear(); bool DoUpdateThreadList(ThreadList &old_thread_list, @@ -88,18 +114,21 @@ protected: Status DoGetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override; + Status DoAttach(const ProcessAttachInfo &attach_info); + private: friend class ScriptedThread; - void CheckInterpreterAndScriptObject() const; + inline void CheckScriptedInterface() const { + lldbassert(m_interface_up && "Invalid scripted process interface."); + } + ScriptedProcessInterface &GetInterface() const; static bool IsScriptLanguageSupported(lldb::ScriptLanguage language); // Member variables. const ScriptedMetadata m_scripted_metadata; - lldb_private::ScriptInterpreter *m_interpreter = nullptr; - lldb_private::StructuredData::ObjectSP m_script_object_sp = nullptr; - //@} + lldb::ScriptedProcessInterfaceUP m_interface_up; }; } // namespace lldb_private 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 ad0d26af8879..684375957d24 100644 --- a/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp @@ -35,7 +35,7 @@ ScriptedThread::Create(ScriptedProcess &process, return llvm::createStringError(llvm::inconvertibleErrorCode(), "Invalid scripted process."); - process.CheckInterpreterAndScriptObject(); + process.CheckScriptedInterface(); auto scripted_thread_interface = process.GetInterface().CreateScriptedThreadInterface(); @@ -250,14 +250,19 @@ bool ScriptedThread::CalculateStopInfo() { StopInfo::CreateStopReasonWithBreakpointSiteID(*this, break_id); } break; case lldb::eStopReasonSignal: { - int signal; + uint32_t signal; llvm::StringRef description; - data_dict->GetValueForKeyAsInteger("signal", signal, - LLDB_INVALID_SIGNAL_NUMBER); + if (!data_dict->GetValueForKeyAsInteger("signal", signal)) { + signal = LLDB_INVALID_SIGNAL_NUMBER; + return false; + } data_dict->GetValueForKeyAsString("desc", description); stop_info_sp = StopInfo::CreateStopReasonWithSignal(*this, signal, description.data()); } break; + case lldb::eStopReasonTrace: { + stop_info_sp = StopInfo::CreateStopReasonToTrace(*this); + } break; case lldb::eStopReasonException: { #if defined(__APPLE__) StructuredData::Dictionary *mach_exception; @@ -280,7 +285,7 @@ bool ScriptedThread::CalculateStopInfo() { auto fetch_data = [&raw_codes](StructuredData::Object *obj) { if (!obj) return false; - raw_codes.push_back(obj->GetIntegerValue()); + raw_codes.push_back(obj->GetUnsignedIntegerValue()); return true; }; @@ -338,7 +343,7 @@ std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() { LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers info.", error, LLDBLog::Thread); - m_register_info_sp = std::make_shared<DynamicRegisterInfo>( + m_register_info_sp = DynamicRegisterInfo::Create( *reg_info, m_scripted_process.GetTarget().GetArchitecture()); } 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 2bd38f81786b..0aaddad53126 100644 --- a/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.cpp @@ -15,8 +15,10 @@ using namespace lldb_private; LLDB_PLUGIN_DEFINE(ClangREPL) +char ClangREPL::ID; + ClangREPL::ClangREPL(lldb::LanguageType language, Target &target) - : REPL(eKindClang, target), m_language(language), + : llvm::RTTIExtends<ClangREPL, REPL>(target), m_language(language), m_implicit_expr_result_regex("\\$[0-9]+") {} ClangREPL::~ClangREPL() = default; @@ -60,8 +62,9 @@ lldb::REPLSP ClangREPL::CreateInstance(Status &error, Status ClangREPL::DoInitialization() { return Status(); } -ConstString ClangREPL::GetSourceFileBasename() { - return ConstString("repl.c"); +llvm::StringRef ClangREPL::GetSourceFileBasename() { + static constexpr llvm::StringLiteral g_repl("repl.c"); + return g_repl; } const char *ClangREPL::GetAutoIndentCharacters() { return " "; } diff --git a/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.h b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.h index 07b7f73b1faf..7d219c46189e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.h +++ b/contrib/llvm-project/lldb/source/Plugins/REPL/Clang/ClangREPL.h @@ -14,8 +14,11 @@ namespace lldb_private { /// Implements a Clang-based REPL for C languages on top of LLDB's REPL /// framework. -class ClangREPL : public REPL { +class ClangREPL : public llvm::RTTIExtends<ClangREPL, REPL> { public: + // LLVM RTTI support + static char ID; + ClangREPL(lldb::LanguageType language, Target &target); ~ClangREPL() override; @@ -33,7 +36,7 @@ public: protected: Status DoInitialization() override; - ConstString GetSourceFileBasename() override; + llvm::StringRef GetSourceFileBasename() override; const char *GetAutoIndentCharacters() override; diff --git a/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp b/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp new file mode 100644 index 000000000000..aeb54ef9ee24 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.cpp @@ -0,0 +1,83 @@ +//===-- RegisterTypeBuilderClang.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 "clang/AST/DeclCXX.h" + +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "RegisterTypeBuilderClang.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Target/RegisterFlags.h" +#include "lldb/lldb-enumerations.h" + +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(RegisterTypeBuilderClang) + +void RegisterTypeBuilderClang::Initialize() { + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); + }); +} + +void RegisterTypeBuilderClang::Terminate() {} + +lldb::RegisterTypeBuilderSP +RegisterTypeBuilderClang::CreateInstance(Target &target) { + return std::make_shared<RegisterTypeBuilderClang>(target); +} + +RegisterTypeBuilderClang::RegisterTypeBuilderClang(Target &target) + : m_target(target) {} + +CompilerType RegisterTypeBuilderClang::GetRegisterType( + const std::string &name, const lldb_private::RegisterFlags &flags, + uint32_t byte_size) { + lldb::TypeSystemClangSP type_system = + ScratchTypeSystemClang::GetForTarget(m_target); + assert(type_system); + + std::string register_type_name = "__lldb_register_fields_"; + register_type_name += name; + // See if we have made this type before and can reuse it. + CompilerType fields_type = + type_system->GetTypeForIdentifier<clang::CXXRecordDecl>( + register_type_name); + + if (!fields_type) { + // In most ABI, a change of field type means a change in storage unit. + // We want it all in one unit, so we use a field type the same as the + // register's size. + CompilerType field_uint_type = + type_system->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint, + byte_size * 8); + + fields_type = type_system->CreateRecordType( + nullptr, OptionalClangModuleID(), lldb::eAccessPublic, + register_type_name, clang::TTK_Struct, lldb::eLanguageTypeC); + type_system->StartTagDeclarationDefinition(fields_type); + + // We assume that RegisterFlags has padded and sorted the fields + // already. + for (const RegisterFlags::Field &field : flags.GetFields()) { + type_system->AddFieldToRecordType(fields_type, field.GetName(), + field_uint_type, lldb::eAccessPublic, + field.GetSizeInBits()); + } + + type_system->CompleteTagDeclarationDefinition(fields_type); + // So that the size of the type matches the size of the register. + type_system->SetIsPacked(fields_type); + + // This should be true if RegisterFlags padded correctly. + assert(*fields_type.GetByteSize(nullptr) == flags.GetSize()); + } + + return fields_type; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.h b/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.h new file mode 100644 index 000000000000..a094b22d85c8 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/RegisterTypeBuilder/RegisterTypeBuilderClang.h @@ -0,0 +1,40 @@ +//===-- RegisterTypeBuilderClang.h ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_REGISTERTYPEBUILDER_REGISTERTYPEBUILDERCLANG_H +#define LLDB_PLUGINS_REGISTERTYPEBUILDER_REGISTERTYPEBUILDERCLANG_H + +#include "lldb/Target/RegisterTypeBuilder.h" +#include "lldb/Target/Target.h" + +namespace lldb_private { +class RegisterTypeBuilderClang : public RegisterTypeBuilder { +public: + RegisterTypeBuilderClang(Target &target); + + static void Initialize(); + static void Terminate(); + static llvm::StringRef GetPluginNameStatic() { + return "register-types-clang"; + } + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + static llvm::StringRef GetPluginDescriptionStatic() { + return "Create register types using TypeSystemClang"; + } + static lldb::RegisterTypeBuilderSP CreateInstance(Target &target); + + CompilerType GetRegisterType(const std::string &name, + const lldb_private::RegisterFlags &flags, + uint32_t byte_size) override; + +private: + Target &m_target; +}; +} // namespace lldb_private + +#endif // LLDB_PLUGINS_REGISTERTYPEBUILDER_REGISTERTYPEBUILDERCLANG_H diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp index b82a2647e9a0..8dad22d077be 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp @@ -83,8 +83,8 @@ Lua::CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp, lua_pushlightuserdata(m_lua_state, baton); lua_gettable(m_lua_state, LUA_REGISTRYINDEX); StructuredDataImpl extra_args_impl(std::move(extra_args_sp)); - return LLDBSwigLuaBreakpointCallbackFunction(m_lua_state, stop_frame_sp, - bp_loc_sp, extra_args_impl); + return lua::SWIGBridge::LLDBSwigLuaBreakpointCallbackFunction( + m_lua_state, stop_frame_sp, bp_loc_sp, extra_args_impl); } llvm::Error Lua::RegisterWatchpointCallback(void *baton, const char *body) { @@ -109,8 +109,8 @@ Lua::CallWatchpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp, lua_pushlightuserdata(m_lua_state, baton); lua_gettable(m_lua_state, LUA_REGISTRYINDEX); - return LLDBSwigLuaWatchpointCallbackFunction(m_lua_state, stop_frame_sp, - wp_sp); + return lua::SWIGBridge::LLDBSwigLuaWatchpointCallbackFunction( + m_lua_state, stop_frame_sp, wp_sp); } llvm::Error Lua::CheckSyntax(llvm::StringRef buffer) { @@ -131,14 +131,13 @@ llvm::Error Lua::CheckSyntax(llvm::StringRef buffer) { } llvm::Error Lua::LoadModule(llvm::StringRef filename) { - FileSpec file(filename); + const FileSpec file(filename); if (!FileSystem::Instance().Exists(file)) { return llvm::make_error<llvm::StringError>("invalid path", llvm::inconvertibleErrorCode()); } - ConstString module_extension = file.GetFileNameExtension(); - if (module_extension != ".lua") { + if (file.GetFileNameExtension() != ".lua") { return llvm::make_error<llvm::StringError>("invalid extension", llvm::inconvertibleErrorCode()); } diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h index 5fca18f2dd6d..27263c3b634b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/SWIGLuaBridge.h @@ -15,13 +15,20 @@ namespace lldb_private { -llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction( - lua_State *L, lldb::StackFrameSP stop_frame_sp, - lldb::BreakpointLocationSP bp_loc_sp, - const StructuredDataImpl &extra_args_impl); +namespace lua { -llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction( - lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp); +class SWIGBridge { +public: + static llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction( + lua_State *L, lldb::StackFrameSP stop_frame_sp, + lldb::BreakpointLocationSP bp_loc_sp, + const StructuredDataImpl &extra_args_impl); + + static llvm::Expected<bool> LLDBSwigLuaWatchpointCallbackFunction( + lua_State *L, lldb::StackFrameSP stop_frame_sp, lldb::WatchpointSP wp_sp); +}; + +} // namespace lua } // namespace lldb_private 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 ec0992583145..be573cfba610 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp @@ -111,7 +111,7 @@ public: io_handler.GetUserData()); for (BreakpointOptions &bp_options : *bp_options_vec) { Status error = m_script_interpreter.SetBreakpointCommandCallback( - bp_options, data.c_str()); + bp_options, data.c_str(), /*is_callback=*/false); if (error.Fail()) *io_handler.GetErrorStreamFileSP() << error.AsCString() << '\n'; } @@ -121,7 +121,8 @@ public: auto *wp_options = static_cast<WatchpointOptions *>(io_handler.GetUserData()); m_script_interpreter.SetWatchpointCommandCallback(wp_options, - data.c_str()); + data.c_str(), + /*is_callback=*/false); io_handler.SetIsDone(true); } break; case eIOHandlerNone: @@ -348,7 +349,8 @@ Status ScriptInterpreterLua::SetBreakpointCommandCallbackFunction( } Status ScriptInterpreterLua::SetBreakpointCommandCallback( - BreakpointOptions &bp_options, const char *command_body_text) { + BreakpointOptions &bp_options, const char *command_body_text, + bool is_callback) { return RegisterBreakpointCallback(bp_options, command_body_text, {}); } @@ -368,7 +370,8 @@ Status ScriptInterpreterLua::RegisterBreakpointCallback( } void ScriptInterpreterLua::SetWatchpointCommandCallback( - WatchpointOptions *wp_options, const char *command_body_text) { + WatchpointOptions *wp_options, const char *command_body_text, + bool is_callback) { RegisterWatchpointCallback(wp_options, command_body_text, {}); } diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h index b601779ff301..ca14e189acd8 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h @@ -88,10 +88,12 @@ public: CommandReturnObject &result) override; Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, - const char *command_body_text) override; + const char *command_body_text, + bool is_callback) override; void SetWatchpointCommandCallback(WatchpointOptions *wp_options, - const char *command_body_text) override; + const char *command_body_text, + bool is_callback) override; Status SetBreakpointCommandCallbackFunction( BreakpointOptions &bp_options, const char *function_name, 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 22918561692c..eee2f6f5d43f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -25,6 +25,7 @@ #include "llvm/Support/Errno.h" #include <cstdio> +#include <variant> using namespace lldb_private; using namespace lldb; @@ -101,7 +102,7 @@ Expected<long long> PythonObject::AsLongLong() const { return r; } -Expected<long long> PythonObject::AsUnsignedLongLong() const { +Expected<unsigned long long> PythonObject::AsUnsignedLongLong() const { if (!m_py_obj) return nullDeref(); assert(!PyErr_Occurred()); @@ -117,6 +118,7 @@ Expected<unsigned long long> PythonObject::AsModuloUnsignedLongLong() const { return nullDeref(); assert(!PyErr_Occurred()); unsigned long long r = PyLong_AsUnsignedLongLongMask(m_py_obj); + // FIXME: We should fetch the exception message and hoist it. if (PyErr_Occurred()) return exception(); return r; @@ -267,9 +269,15 @@ StructuredData::ObjectSP PythonObject::CreateStructuredObject() const { case PyObjectType::Boolean: return PythonBoolean(PyRefType::Borrowed, m_py_obj) .CreateStructuredBoolean(); - case PyObjectType::Integer: - return PythonInteger(PyRefType::Borrowed, m_py_obj) - .CreateStructuredInteger(); + case PyObjectType::Integer: { + StructuredData::IntegerSP int_sp = + PythonInteger(PyRefType::Borrowed, m_py_obj).CreateStructuredInteger(); + if (std::holds_alternative<StructuredData::UnsignedIntegerSP>(int_sp)) + return std::get<StructuredData::UnsignedIntegerSP>(int_sp); + if (std::holds_alternative<StructuredData::SignedIntegerSP>(int_sp)) + return std::get<StructuredData::SignedIntegerSP>(int_sp); + return nullptr; + }; case PyObjectType::List: return PythonList(PyRefType::Borrowed, m_py_obj).CreateStructuredArray(); case PyObjectType::String: @@ -459,17 +467,32 @@ void PythonInteger::SetInteger(int64_t value) { } StructuredData::IntegerSP PythonInteger::CreateStructuredInteger() const { - StructuredData::IntegerSP result(new StructuredData::Integer); - // FIXME this is really not ideal. Errors are silently converted to 0 - // and overflows are silently wrapped. But we'd need larger changes - // to StructuredData to fix it, so that's how it is for now. - llvm::Expected<unsigned long long> value = AsModuloUnsignedLongLong(); - if (!value) { + StructuredData::UnsignedIntegerSP uint_sp = CreateStructuredUnsignedInteger(); + return uint_sp ? StructuredData::IntegerSP(uint_sp) + : CreateStructuredSignedInteger(); +} + +StructuredData::UnsignedIntegerSP +PythonInteger::CreateStructuredUnsignedInteger() const { + StructuredData::UnsignedIntegerSP result = nullptr; + llvm::Expected<unsigned long long> value = AsUnsignedLongLong(); + if (!value) llvm::consumeError(value.takeError()); - result->SetValue(0); - } else { - result->SetValue(value.get()); - } + else + result = std::make_shared<StructuredData::UnsignedInteger>(value.get()); + + return result; +} + +StructuredData::SignedIntegerSP +PythonInteger::CreateStructuredSignedInteger() const { + StructuredData::SignedIntegerSP result = nullptr; + llvm::Expected<long long> value = AsLongLong(); + if (!value) + llvm::consumeError(value.takeError()); + else + result = std::make_shared<StructuredData::SignedInteger>(value.get()); + return result; } 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 365d499bead8..012f16e95e77 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -201,6 +201,7 @@ template <> struct PythonFormat<short> : PassthroughFormat<short, 'h'> {}; template <> struct PythonFormat<unsigned short> : PassthroughFormat<unsigned short, 'H'> {}; template <> struct PythonFormat<int> : PassthroughFormat<int, 'i'> {}; +template <> struct PythonFormat<bool> : PassthroughFormat<bool, 'p'> {}; template <> struct PythonFormat<unsigned int> : PassthroughFormat<unsigned int, 'I'> {}; template <> struct PythonFormat<long> : PassthroughFormat<long, 'l'> {}; @@ -342,6 +343,15 @@ public: return python::Take<PythonObject>(obj); } + llvm::Expected<PythonObject> GetType() const { + if (!m_py_obj) + return nullDeref(); + PyObject *obj = PyObject_Type(m_py_obj); + if (!obj) + return exception(); + return python::Take<PythonObject>(obj); + } + llvm::Expected<bool> IsTrue() { if (!m_py_obj) return nullDeref(); @@ -353,7 +363,7 @@ public: llvm::Expected<long long> AsLongLong() const; - llvm::Expected<long long> AsUnsignedLongLong() const; + llvm::Expected<unsigned long long> AsUnsignedLongLong() const; // wraps on overflow, instead of raising an error. llvm::Expected<unsigned long long> AsModuloUnsignedLongLong() const; @@ -479,6 +489,10 @@ public: void SetInteger(int64_t value); StructuredData::IntegerSP CreateStructuredInteger() const; + + StructuredData::UnsignedIntegerSP CreateStructuredUnsignedInteger() const; + + StructuredData::SignedIntegerSP CreateStructuredSignedInteger() const; }; class PythonBoolean : public TypedPythonObject<PythonBoolean> { diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h index 3dc2864f8d42..630ab293cf93 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/SWIGPythonBridge.h @@ -30,6 +30,8 @@ class SBCommandReturnObject; class SBValue; class SBStream; class SBStructuredData; +class SBFileSpec; +class SBModuleSpec; } // namespace lldb namespace lldb_private { @@ -61,175 +63,214 @@ private: T *m_sb; }; -PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp); -PythonObject ToSWIGWrapper(lldb::TargetSP target_sp); -PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp); -PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp); -PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp); -PythonObject ToSWIGWrapper(const Status &status); -PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl); -PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp); -PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp); -PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp); -PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp); -PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp); -PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); -PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); -PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); - -PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb); -PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb); -PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb); - -python::ScopedPythonObject<lldb::SBCommandReturnObject> -ToSWIGWrapper(CommandReturnObject &cmd_retobj); -python::ScopedPythonObject<lldb::SBEvent> ToSWIGWrapper(Event *event); +// TODO: We may want to support other languages in the future w/ SWIG (we +// already support Lua right now, for example). We could create a generic +// SWIGBridge class and have this one specialize it, something like this: +// +// <typename T> +// class SWIGBridge { +// static T ToSWIGWrapper(...); +// }; +// +// class SWIGPythonBridge : public SWIGBridge<PythonObject> { +// template<> static PythonObject ToSWIGWrapper(...); +// }; +// +// And we should be able to more easily support things like Lua +class SWIGBridge { +public: + static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBValue> value_sb); + static PythonObject ToSWIGWrapper(lldb::ValueObjectSP value_sp); + static PythonObject ToSWIGWrapper(lldb::TargetSP target_sp); + static PythonObject ToSWIGWrapper(lldb::ProcessSP process_sp); + static PythonObject ToSWIGWrapper(lldb::ThreadPlanSP thread_plan_sp); + static PythonObject ToSWIGWrapper(lldb::BreakpointSP breakpoint_sp); + static PythonObject ToSWIGWrapper(const Status &status); + static PythonObject ToSWIGWrapper(const StructuredDataImpl &data_impl); + static PythonObject ToSWIGWrapper(lldb::ThreadSP thread_sp); + static PythonObject ToSWIGWrapper(lldb::StackFrameSP frame_sp); + static PythonObject ToSWIGWrapper(lldb::DebuggerSP debugger_sp); + static PythonObject ToSWIGWrapper(lldb::WatchpointSP watchpoint_sp); + static PythonObject ToSWIGWrapper(lldb::BreakpointLocationSP bp_loc_sp); + static PythonObject ToSWIGWrapper(lldb::TypeImplSP type_impl_sp); + static PythonObject ToSWIGWrapper(lldb::ExecutionContextRefSP ctx_sp); + static PythonObject ToSWIGWrapper(const TypeSummaryOptions &summary_options); + static PythonObject ToSWIGWrapper(const SymbolContext &sym_ctx); + + static PythonObject ToSWIGWrapper(lldb::ProcessAttachInfoSP attach_info_sp); + static PythonObject ToSWIGWrapper(lldb::ProcessLaunchInfoSP launch_info_sp); + static PythonObject ToSWIGWrapper(lldb::DataExtractorSP data_extractor_sp); + + static PythonObject ToSWIGWrapper(std::unique_ptr<lldb::SBStream> stream_sb); + static PythonObject + ToSWIGWrapper(std::unique_ptr<lldb::SBStructuredData> data_sb); + static PythonObject + ToSWIGWrapper(std::unique_ptr<lldb::SBFileSpec> file_spec_sb); + static PythonObject + ToSWIGWrapper(std::unique_ptr<lldb::SBModuleSpec> module_spec_sb); + + static python::ScopedPythonObject<lldb::SBCommandReturnObject> + ToSWIGWrapper(CommandReturnObject &cmd_retobj); + static python::ScopedPythonObject<lldb::SBEvent> ToSWIGWrapper(Event *event); + // These prototypes are the Pythonic implementations of the required + // callbacks. Although these are scripting-language specific, their definition + // depends on the public API. + + static python::PythonObject LLDBSwigPythonCreateScriptedObject( + const char *python_class_name, const char *session_dictionary_name, + lldb::ExecutionContextRefSP exe_ctx_sp, + const lldb_private::StructuredDataImpl &args_impl, + std::string &error_string); + + static llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( + const char *python_function_name, const char *session_dictionary_name, + const lldb::StackFrameSP &sb_frame, + const lldb::BreakpointLocationSP &sb_bp_loc, + const lldb_private::StructuredDataImpl &args_impl); + + static bool LLDBSwigPythonWatchpointCallbackFunction( + const char *python_function_name, const char *session_dictionary_name, + const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); + + static bool + LLDBSwigPythonFormatterCallbackFunction(const char *python_function_name, + const char *session_dictionary_name, + lldb::TypeImplSP type_impl_sp); -} // namespace python + static bool LLDBSwigPythonCallTypeScript( + const char *python_function_name, const void *session_dictionary, + const lldb::ValueObjectSP &valobj_sp, void **pyfunct_wrapper, + const lldb::TypeSummaryOptionsSP &options_sp, std::string &retval); -void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data); -void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); -void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); -void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); + static python::PythonObject + LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, + const char *session_dictionary_name, + const lldb::ValueObjectSP &valobj_sp); -// These prototypes are the Pythonic implementations of the required callbacks. -// Although these are scripting-language specific, their definition depends on -// the public API. - -python::PythonObject LLDBSwigPythonCreateScriptedObject( - const char *python_class_name, const char *session_dictionary_name, - lldb::ExecutionContextRefSP exe_ctx_sp, - const lldb_private::StructuredDataImpl &args_impl, - std::string &error_string); - -llvm::Expected<bool> LLDBSwigPythonBreakpointCallbackFunction( - const char *python_function_name, const char *session_dictionary_name, - const lldb::StackFrameSP &sb_frame, - const lldb::BreakpointLocationSP &sb_bp_loc, - const lldb_private::StructuredDataImpl &args_impl); - -bool LLDBSwigPythonWatchpointCallbackFunction( - const char *python_function_name, const char *session_dictionary_name, - const lldb::StackFrameSP &sb_frame, const lldb::WatchpointSP &sb_wp); - -bool LLDBSwigPythonFormatterCallbackFunction( - const char *python_function_name, const char *session_dictionary_name, - lldb::TypeImplSP type_impl_sp); - -bool LLDBSwigPythonCallTypeScript(const char *python_function_name, - const void *session_dictionary, - const lldb::ValueObjectSP &valobj_sp, - void **pyfunct_wrapper, - const lldb::TypeSummaryOptionsSP &options_sp, - std::string &retval); - -python::PythonObject -LLDBSwigPythonCreateSyntheticProvider(const char *python_class_name, - const char *session_dictionary_name, - const lldb::ValueObjectSP &valobj_sp); + static python::PythonObject + LLDBSwigPythonCreateCommandObject(const char *python_class_name, + const char *session_dictionary_name, + lldb::DebuggerSP debugger_sp); -python::PythonObject -LLDBSwigPythonCreateCommandObject(const char *python_class_name, - const char *session_dictionary_name, - lldb::DebuggerSP debugger_sp); + static python::PythonObject LLDBSwigPythonCreateScriptedThreadPlan( + const char *python_class_name, const char *session_dictionary_name, + const StructuredDataImpl &args_data, std::string &error_string, + const lldb::ThreadPlanSP &thread_plan_sp); -python::PythonObject LLDBSwigPythonCreateScriptedThreadPlan( - const char *python_class_name, const char *session_dictionary_name, - const StructuredDataImpl &args_data, std::string &error_string, - const lldb::ThreadPlanSP &thread_plan_sp); + static bool LLDBSWIGPythonCallThreadPlan(void *implementor, + const char *method_name, + lldb_private::Event *event_sp, + bool &got_error); -bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name, - lldb_private::Event *event_sp, - bool &got_error); + static bool LLDBSWIGPythonCallThreadPlan(void *implementor, + const char *method_name, + lldb_private::Stream *stream, + bool &got_error); -python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver( - const char *python_class_name, const char *session_dictionary_name, - const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp); + static python::PythonObject LLDBSwigPythonCreateScriptedBreakpointResolver( + const char *python_class_name, const char *session_dictionary_name, + const StructuredDataImpl &args, const lldb::BreakpointSP &bkpt_sp); -unsigned int -LLDBSwigPythonCallBreakpointResolver(void *implementor, const char *method_name, - lldb_private::SymbolContext *sym_ctx); + static unsigned int + LLDBSwigPythonCallBreakpointResolver(void *implementor, + const char *method_name, + lldb_private::SymbolContext *sym_ctx); -python::PythonObject LLDBSwigPythonCreateScriptedStopHook( - lldb::TargetSP target_sp, const char *python_class_name, - const char *session_dictionary_name, const StructuredDataImpl &args, - lldb_private::Status &error); + static python::PythonObject LLDBSwigPythonCreateScriptedStopHook( + lldb::TargetSP target_sp, const char *python_class_name, + const char *session_dictionary_name, const StructuredDataImpl &args, + lldb_private::Status &error); -bool LLDBSwigPythonStopHookCallHandleStop(void *implementor, - lldb::ExecutionContextRefSP exc_ctx, - lldb::StreamSP stream); + static bool + LLDBSwigPythonStopHookCallHandleStop(void *implementor, + lldb::ExecutionContextRefSP exc_ctx, + lldb::StreamSP stream); -size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, uint32_t max); + static size_t LLDBSwigPython_CalculateNumChildren(PyObject *implementor, + uint32_t max); -PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, uint32_t idx); + static PyObject *LLDBSwigPython_GetChildAtIndex(PyObject *implementor, + uint32_t idx); -int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, - const char *child_name); + static int LLDBSwigPython_GetIndexOfChildWithName(PyObject *implementor, + const char *child_name); -lldb::ValueObjectSP LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); + static lldb::ValueObjectSP + LLDBSWIGPython_GetValueObjectSPFromSBValue(void *data); -bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor); + static bool LLDBSwigPython_UpdateSynthProviderInstance(PyObject *implementor); -bool LLDBSwigPython_MightHaveChildrenSynthProviderInstance( - PyObject *implementor); + static bool + LLDBSwigPython_MightHaveChildrenSynthProviderInstance(PyObject *implementor); -PyObject *LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor); + static PyObject * + LLDBSwigPython_GetValueSynthProviderInstance(PyObject *implementor); -bool LLDBSwigPythonCallCommand(const char *python_function_name, - const char *session_dictionary_name, - lldb::DebuggerSP debugger, const char *args, - lldb_private::CommandReturnObject &cmd_retobj, - lldb::ExecutionContextRefSP exe_ctx_ref_sp); + static bool + LLDBSwigPythonCallCommand(const char *python_function_name, + const char *session_dictionary_name, + lldb::DebuggerSP debugger, const char *args, + lldb_private::CommandReturnObject &cmd_retobj, + lldb::ExecutionContextRefSP exe_ctx_ref_sp); -bool LLDBSwigPythonCallCommandObject( - PyObject *implementor, lldb::DebuggerSP debugger, const char *args, - lldb_private::CommandReturnObject &cmd_retobj, - lldb::ExecutionContextRefSP exe_ctx_ref_sp); + static bool + LLDBSwigPythonCallCommandObject(PyObject *implementor, + lldb::DebuggerSP debugger, const char *args, + lldb_private::CommandReturnObject &cmd_retobj, + lldb::ExecutionContextRefSP exe_ctx_ref_sp); -bool LLDBSwigPythonCallModuleInit(const char *python_module_name, - const char *session_dictionary_name, - lldb::DebuggerSP debugger); + static bool LLDBSwigPythonCallModuleInit(const char *python_module_name, + const char *session_dictionary_name, + lldb::DebuggerSP debugger); -python::PythonObject -LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, - const char *session_dictionary_name, - const lldb::ProcessSP &process_sp); + static python::PythonObject + LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, + const char *session_dictionary_name, + const lldb::ProcessSP &process_sp); -python::PythonObject -LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, - const char *session_dictionary_name); + static python::PythonObject + LLDBSWIGPython_CreateFrameRecognizer(const char *python_class_name, + const char *session_dictionary_name); -PyObject * -LLDBSwigPython_GetRecognizedArguments(PyObject *implementor, - const lldb::StackFrameSP &frame_sp); + static PyObject * + LLDBSwigPython_GetRecognizedArguments(PyObject *implementor, + const lldb::StackFrameSP &frame_sp); -bool LLDBSWIGPythonRunScriptKeywordProcess(const char *python_function_name, - const char *session_dictionary_name, - const lldb::ProcessSP &process, - std::string &output); + static bool LLDBSWIGPythonRunScriptKeywordProcess( + const char *python_function_name, const char *session_dictionary_name, + const lldb::ProcessSP &process, std::string &output); -std::optional<std::string> -LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, - const char *session_dictionary_name, - lldb::ThreadSP thread); + static std::optional<std::string> + LLDBSWIGPythonRunScriptKeywordThread(const char *python_function_name, + const char *session_dictionary_name, + lldb::ThreadSP thread); -bool LLDBSWIGPythonRunScriptKeywordTarget(const char *python_function_name, - const char *session_dictionary_name, - const lldb::TargetSP &target, - std::string &output); + static bool LLDBSWIGPythonRunScriptKeywordTarget( + const char *python_function_name, const char *session_dictionary_name, + const lldb::TargetSP &target, std::string &output); -std::optional<std::string> -LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, - const char *session_dictionary_name, - lldb::StackFrameSP frame); + static std::optional<std::string> + LLDBSWIGPythonRunScriptKeywordFrame(const char *python_function_name, + const char *session_dictionary_name, + lldb::StackFrameSP frame); -bool LLDBSWIGPythonRunScriptKeywordValue(const char *python_function_name, - const char *session_dictionary_name, - const lldb::ValueObjectSP &value, - std::string &output); + static bool LLDBSWIGPythonRunScriptKeywordValue( + const char *python_function_name, const char *session_dictionary_name, + const lldb::ValueObjectSP &value, std::string &output); -void *LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, - const lldb::TargetSP &target_sp); + static void * + LLDBSWIGPython_GetDynamicSetting(void *module, const char *setting, + const lldb::TargetSP &target_sp); +}; + +void *LLDBSWIGPython_CastPyObjectToSBData(PyObject *data); +void *LLDBSWIGPython_CastPyObjectToSBBreakpoint(PyObject *data); +void *LLDBSWIGPython_CastPyObjectToSBAttachInfo(PyObject *data); +void *LLDBSWIGPython_CastPyObjectToSBLaunchInfo(PyObject *data); +void *LLDBSWIGPython_CastPyObjectToSBError(PyObject *data); +void *LLDBSWIGPython_CastPyObjectToSBValue(PyObject *data); +void *LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(PyObject *data); +} // namespace python } // namespace lldb_private 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 7026815e120d..55b7a73712c4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -306,7 +306,7 @@ void ScriptInterpreterPython::SharedLibraryDirectoryHelper( // On windows, we need to manually back out of the python tree, and go into // the bin directory. This is pretty much the inverse of what ComputePythonDir // does. - if (this_file.GetFileNameExtension() == ConstString(".pyd")) { + if (this_file.GetFileNameExtension() == ".pyd") { this_file.RemoveLastPathComponent(); // _lldb.pyd or _lldb_d.pyd this_file.RemoveLastPathComponent(); // lldb llvm::StringRef libdir = LLDB_PYTHON_RELATIVE_LIBDIR; @@ -408,12 +408,10 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger) m_session_dict(PyInitialValue::Invalid), m_sys_module_dict(PyInitialValue::Invalid), m_run_one_line_function(), m_run_one_line_str_global(), - m_dictionary_name(m_debugger.GetInstanceName().AsCString()), + m_dictionary_name(m_debugger.GetInstanceName()), m_active_io_handler(eIOHandlerNone), m_session_is_active(false), m_pty_secondary_is_open(false), m_valid_session(true), m_lock_count(0), m_command_thread_state(nullptr) { - m_scripted_process_interface_up = - std::make_unique<ScriptedProcessPythonInterface>(*this); m_scripted_platform_interface_up = std::make_unique<ScriptedPlatformPythonInterface>(*this); @@ -443,7 +441,7 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger) // do their task run_string.Clear(); run_string.Printf( - "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", + "run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp')", m_dictionary_name.c_str()); PyRun_SimpleString(run_string.GetData()); run_string.Clear(); @@ -456,7 +454,7 @@ ScriptInterpreterPythonImpl::ScriptInterpreterPythonImpl(Debugger &debugger) run_string.Clear(); run_string.Printf("run_one_line (%s, 'lldb.debugger_unique_id = %" PRIu64 - "; pydoc.pager = pydoc.plainpager')", + "')", m_dictionary_name.c_str(), m_debugger.GetID()); PyRun_SimpleString(run_string.GetData()); } @@ -523,7 +521,8 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, StructuredData::ObjectSP empty_args_sp; if (GenerateBreakpointCommandCallbackData(data_up->user_source, data_up->script_source, - false) + /*has_extra_args=*/false, + /*is_callback=*/false) .Success()) { auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>( std::move(data_up)); @@ -546,7 +545,8 @@ void ScriptInterpreterPythonImpl::IOHandlerInputComplete(IOHandler &io_handler, data_up->user_source.SplitIntoLines(data); if (GenerateWatchpointCommandCallbackData(data_up->user_source, - data_up->script_source)) { + data_up->script_source, + /*is_callback=*/false)) { auto baton_sp = std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up)); wp_options->SetCallback( @@ -1160,8 +1160,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction( StructuredData::ObjectSP extra_args_sp) { Status error; // For now just cons up a oneliner that calls the provided function. - std::string oneliner("return "); - oneliner += function_name; + std::string function_signature = function_name; llvm::Expected<unsigned> maybe_args = GetMaxPositionalArgumentsForCallable(function_name); @@ -1176,7 +1175,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction( bool uses_extra_args = false; if (max_args >= 4) { uses_extra_args = true; - oneliner += "(frame, bp_loc, extra_args, internal_dict)"; + function_signature += "(frame, bp_loc, extra_args, internal_dict)"; } else if (max_args >= 3) { if (extra_args_sp) { error.SetErrorString("cannot pass extra_args to a three argument callback" @@ -1184,7 +1183,7 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction( return error; } uses_extra_args = false; - oneliner += "(frame, bp_loc, internal_dict)"; + function_signature += "(frame, bp_loc, internal_dict)"; } else { error.SetErrorStringWithFormat("expected 3 or 4 argument " "function, %s can only take %zu", @@ -1192,8 +1191,9 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallbackFunction( return error; } - SetBreakpointCommandCallback(bp_options, oneliner.c_str(), extra_args_sp, - uses_extra_args); + SetBreakpointCommandCallback(bp_options, function_signature.c_str(), + extra_args_sp, uses_extra_args, + /*is_callback=*/true); return error; } @@ -1203,7 +1203,8 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( Status error; error = GenerateBreakpointCommandCallbackData(cmd_data_up->user_source, cmd_data_up->script_source, - false); + /*has_extra_args=*/false, + /*is_callback=*/false); if (error.Fail()) { return error; } @@ -1215,14 +1216,17 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( } Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( - BreakpointOptions &bp_options, const char *command_body_text) { - return SetBreakpointCommandCallback(bp_options, command_body_text, {},false); + BreakpointOptions &bp_options, const char *command_body_text, + bool is_callback) { + return SetBreakpointCommandCallback(bp_options, command_body_text, {}, + /*uses_extra_args=*/false, is_callback); } // Set a Python one-liner as the callback for the breakpoint. Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( BreakpointOptions &bp_options, const char *command_body_text, - StructuredData::ObjectSP extra_args_sp, bool uses_extra_args) { + StructuredData::ObjectSP extra_args_sp, bool uses_extra_args, + bool is_callback) { auto data_up = std::make_unique<CommandDataPython>(extra_args_sp); // Split the command_body_text into lines, and pass that to // GenerateBreakpointCommandCallbackData. That will wrap the body in an @@ -1230,9 +1234,9 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( // That is what the callback will actually invoke. data_up->user_source.SplitIntoLines(command_body_text); - Status error = GenerateBreakpointCommandCallbackData(data_up->user_source, - data_up->script_source, - uses_extra_args); + Status error = GenerateBreakpointCommandCallbackData( + data_up->user_source, data_up->script_source, uses_extra_args, + is_callback); if (error.Success()) { auto baton_sp = std::make_shared<BreakpointOptions::CommandBaton>(std::move(data_up)); @@ -1245,7 +1249,8 @@ Status ScriptInterpreterPythonImpl::SetBreakpointCommandCallback( // Set a Python one-liner as the callback for the watchpoint. void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback( - WatchpointOptions *wp_options, const char *oneliner) { + WatchpointOptions *wp_options, const char *user_input, + bool is_callback) { auto data_up = std::make_unique<WatchpointOptions::CommandData>(); // It's necessary to set both user_source and script_source to the oneliner. @@ -1253,11 +1258,11 @@ void ScriptInterpreterPythonImpl::SetWatchpointCommandCallback( // command list) while the latter is used for Python to interpret during the // actual callback. - data_up->user_source.AppendString(oneliner); - data_up->script_source.assign(oneliner); + data_up->user_source.AppendString(user_input); + data_up->script_source.assign(user_input); - if (GenerateWatchpointCommandCallbackData(data_up->user_source, - data_up->script_source)) { + if (GenerateWatchpointCommandCallbackData( + data_up->user_source, data_up->script_source, is_callback)) { auto baton_sp = std::make_shared<WatchpointOptions::CommandBaton>(std::move(data_up)); wp_options->SetCallback( @@ -1277,7 +1282,8 @@ Status ScriptInterpreterPythonImpl::ExportFunctionDefinitionToInterpreter( } Status ScriptInterpreterPythonImpl::GenerateFunction(const char *signature, - const StringList &input) { + const StringList &input, + bool is_callback) { Status error; int num_lines = input.GetSize(); if (num_lines == 0) { @@ -1294,40 +1300,61 @@ Status ScriptInterpreterPythonImpl::GenerateFunction(const char *signature, StringList auto_generated_function; auto_generated_function.AppendString(signature); auto_generated_function.AppendString( - " global_dict = globals()"); // Grab the global dictionary + " global_dict = globals()"); // Grab the global dictionary auto_generated_function.AppendString( - " new_keys = internal_dict.keys()"); // Make a list of keys in the - // session dict + " new_keys = internal_dict.keys()"); // Make a list of keys in the + // session dict auto_generated_function.AppendString( - " old_keys = global_dict.keys()"); // Save list of keys in global dict + " old_keys = global_dict.keys()"); // Save list of keys in global dict auto_generated_function.AppendString( - " global_dict.update (internal_dict)"); // Add the session dictionary - // to the - // global dictionary. - - // Wrap everything up inside the function, increasing the indentation. - - auto_generated_function.AppendString(" if True:"); - for (int i = 0; i < num_lines; ++i) { - sstr.Clear(); - sstr.Printf(" %s", input.GetStringAtIndex(i)); - auto_generated_function.AppendString(sstr.GetData()); + " global_dict.update(internal_dict)"); // Add the session dictionary + // to the global dictionary. + + if (is_callback) { + // If the user input is a callback to a python function, make sure the input + // is only 1 line, otherwise appending the user input would break the + // generated wrapped function + if (num_lines == 1) { + sstr.Clear(); + sstr.Printf(" __return_val = %s", input.GetStringAtIndex(0)); + auto_generated_function.AppendString(sstr.GetData()); + } else { + return Status("ScriptInterpreterPythonImpl::GenerateFunction(is_callback=" + "true) = ERROR: python function is multiline."); + } + } else { + auto_generated_function.AppendString( + " __return_val = None"); // Initialize user callback return value. + auto_generated_function.AppendString( + " def __user_code():"); // Create a nested function that will wrap + // the user input. This is necessary to + // capture the return value of the user input + // and prevent early returns. + for (int i = 0; i < num_lines; ++i) { + sstr.Clear(); + sstr.Printf(" %s", input.GetStringAtIndex(i)); + auto_generated_function.AppendString(sstr.GetData()); + } + auto_generated_function.AppendString( + " __return_val = __user_code()"); // Call user code and capture + // return value } auto_generated_function.AppendString( - " for key in new_keys:"); // Iterate over all the keys from session - // dict + " for key in new_keys:"); // Iterate over all the keys from session + // dict + auto_generated_function.AppendString( + " internal_dict[key] = global_dict[key]"); // Update session dict + // values auto_generated_function.AppendString( - " internal_dict[key] = global_dict[key]"); // Update session dict - // values + " if key not in old_keys:"); // If key was not originally in + // global dict auto_generated_function.AppendString( - " if key not in old_keys:"); // If key was not originally in - // global dict + " del global_dict[key]"); // ...then remove key/value from + // global dict auto_generated_function.AppendString( - " del global_dict[key]"); // ...then remove key/value from - // global dict + " return __return_val"); // Return the user callback return value. // Verify that the results are valid Python. - error = ExportFunctionDefinitionToInterpreter(auto_generated_function); return error; @@ -1352,7 +1379,8 @@ bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction( sstr.Printf("def %s (valobj, internal_dict):", auto_generated_function_name.c_str()); - if (!GenerateFunction(sstr.GetData(), user_input).Success()) + if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/false) + .Success()) return false; // Store the name of the auto-generated function to be called. @@ -1376,7 +1404,8 @@ bool ScriptInterpreterPythonImpl::GenerateScriptAliasFunction( sstr.Printf("def %s (debugger, args, exe_ctx, result, internal_dict):", auto_generated_function_name.c_str()); - if (!GenerateFunction(sstr.GetData(), user_input).Success()) + if (!GenerateFunction(sstr.GetData(), user_input, /*is_callback=*/true) + .Success()) return false; // Store the name of the auto-generated function to be called. @@ -1434,7 +1463,7 @@ ScriptInterpreterPythonImpl::CreateFrameRecognizer(const char *class_name) { return StructuredData::GenericSP(); Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); - PythonObject ret_val = LLDBSWIGPython_CreateFrameRecognizer( + PythonObject ret_val = SWIGBridge::LLDBSWIGPython_CreateFrameRecognizer( class_name, m_dictionary_name.c_str()); return StructuredData::GenericSP( @@ -1459,9 +1488,9 @@ lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments( if (!implementor.IsAllocated()) return ValueObjectListSP(); - PythonObject py_return( - PyRefType::Owned, - LLDBSwigPython_GetRecognizedArguments(implementor.get(), frame_sp)); + PythonObject py_return(PyRefType::Owned, + SWIGBridge::LLDBSwigPython_GetRecognizedArguments( + implementor.get(), frame_sp)); // if it fails, print the error but otherwise go on if (PyErr_Occurred()) { @@ -1475,7 +1504,8 @@ lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments( PyObject *item = result_list.GetItemAtIndex(i).get(); lldb::SBValue *sb_value_ptr = (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(item); - auto valobj_sp = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr); + auto valobj_sp = + SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr); if (valobj_sp) result->Append(valobj_sp); } @@ -1484,6 +1514,22 @@ lldb::ValueObjectListSP ScriptInterpreterPythonImpl::GetRecognizedArguments( return ValueObjectListSP(); } +ScriptedProcessInterfaceUP +ScriptInterpreterPythonImpl::CreateScriptedProcessInterface() { + return std::make_unique<ScriptedProcessPythonInterface>(*this); +} + +StructuredData::ObjectSP +ScriptInterpreterPythonImpl::CreateStructuredDataFromScriptObject( + ScriptObject obj) { + void *ptr = const_cast<void *>(obj.GetPointer()); + PythonObject py_obj(PyRefType::Borrowed, static_cast<PyObject *>(ptr)); + if (!py_obj.IsValid() || py_obj.IsNone()) + return {}; + Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + return py_obj.CreateStructuredObject(); +} + StructuredData::GenericSP ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject( const char *class_name, lldb::ProcessSP process_sp) { @@ -1494,7 +1540,7 @@ ScriptInterpreterPythonImpl::OSPlugin_CreatePluginObject( return StructuredData::GenericSP(); Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); - PythonObject ret_val = LLDBSWIGPythonCreateOSPlugin( + PythonObject ret_val = SWIGBridge::LLDBSWIGPythonCreateOSPlugin( class_name, m_dictionary_name.c_str(), process_sp); return StructuredData::GenericSP( @@ -1655,7 +1701,7 @@ StructuredData::ObjectSP ScriptInterpreterPythonImpl::CreateScriptedThreadPlan( Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - PythonObject ret_val = LLDBSwigPythonCreateScriptedThreadPlan( + PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedThreadPlan( class_name, python_interpreter->m_dictionary_name.c_str(), args_data, error_str, thread_plan_sp); if (!ret_val) @@ -1674,7 +1720,7 @@ bool ScriptInterpreterPythonImpl::ScriptedThreadPlanExplainsStop( if (generic) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - explains_stop = LLDBSWIGPythonCallThreadPlan( + explains_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan( generic->GetValue(), "explains_stop", event, script_error); if (script_error) return true; @@ -1691,7 +1737,7 @@ bool ScriptInterpreterPythonImpl::ScriptedThreadPlanShouldStop( if (generic) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - should_stop = LLDBSWIGPythonCallThreadPlan( + should_stop = SWIGBridge::LLDBSWIGPythonCallThreadPlan( generic->GetValue(), "should_stop", event, script_error); if (script_error) return true; @@ -1708,8 +1754,8 @@ bool ScriptInterpreterPythonImpl::ScriptedThreadPlanIsStale( if (generic) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - is_stale = LLDBSWIGPythonCallThreadPlan(generic->GetValue(), "is_stale", - nullptr, script_error); + is_stale = SWIGBridge::LLDBSWIGPythonCallThreadPlan( + generic->GetValue(), "is_stale", (Event *)nullptr, script_error); if (script_error) return true; } @@ -1725,8 +1771,8 @@ lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState( if (generic) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - should_step = LLDBSWIGPythonCallThreadPlan( - generic->GetValue(), "should_step", nullptr, script_error); + should_step = SWIGBridge::LLDBSWIGPythonCallThreadPlan( + generic->GetValue(), "should_step", (Event *)nullptr, script_error); if (script_error) should_step = true; } @@ -1735,6 +1781,24 @@ lldb::StateType ScriptInterpreterPythonImpl::ScriptedThreadPlanGetRunState( return lldb::eStateRunning; } +bool +ScriptInterpreterPythonImpl::ScriptedThreadPlanGetStopDescription( + StructuredData::ObjectSP implementor_sp, lldb_private::Stream *stream, + bool &script_error) { + StructuredData::Generic *generic = nullptr; + if (implementor_sp) + generic = implementor_sp->GetAsGeneric(); + if (!generic) { + script_error = true; + return false; + } + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + return SWIGBridge::LLDBSWIGPythonCallThreadPlan( + generic->GetValue(), "stop_description", stream, script_error); +} + + StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver( const char *class_name, const StructuredDataImpl &args_data, @@ -1756,9 +1820,10 @@ ScriptInterpreterPythonImpl::CreateScriptedBreakpointResolver( Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - PythonObject ret_val = LLDBSwigPythonCreateScriptedBreakpointResolver( - class_name, python_interpreter->m_dictionary_name.c_str(), args_data, - bkpt_sp); + PythonObject ret_val = + SWIGBridge::LLDBSwigPythonCreateScriptedBreakpointResolver( + class_name, python_interpreter->m_dictionary_name.c_str(), args_data, + bkpt_sp); return StructuredData::GenericSP( new StructuredPythonObject(std::move(ret_val))); @@ -1771,7 +1836,7 @@ bool ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchCallback( if (implementor_sp) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - should_continue = LLDBSwigPythonCallBreakpointResolver( + should_continue = SWIGBridge::LLDBSwigPythonCallBreakpointResolver( implementor_sp->GetValue(), "__callback__", sym_ctx); if (PyErr_Occurred()) { PyErr_Print(); @@ -1788,7 +1853,7 @@ ScriptInterpreterPythonImpl::ScriptedBreakpointResolverSearchDepth( if (implementor_sp) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - depth_as_int = LLDBSwigPythonCallBreakpointResolver( + depth_as_int = SWIGBridge::LLDBSwigPythonCallBreakpointResolver( implementor_sp->GetValue(), "__get_depth__", nullptr); if (PyErr_Occurred()) { PyErr_Print(); @@ -1828,7 +1893,7 @@ StructuredData::GenericSP ScriptInterpreterPythonImpl::CreateScriptedStopHook( Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - PythonObject ret_val = LLDBSwigPythonCreateScriptedStopHook( + PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedStopHook( target_sp, class_name, python_interpreter->m_dictionary_name.c_str(), args_data, error); @@ -1848,7 +1913,7 @@ bool ScriptInterpreterPythonImpl::ScriptedStopHookHandleStop( lldb::ExecutionContextRefSP exc_ctx_ref_sp(new ExecutionContextRef(exc_ctx)); - bool ret_val = LLDBSwigPythonStopHookCallHandleStop( + bool ret_val = SWIGBridge::LLDBSwigPythonStopHookCallHandleStop( implementor_sp->GetValue(), exc_ctx_ref_sp, stream_sp); return ret_val; } @@ -1885,7 +1950,7 @@ StructuredData::DictionarySP ScriptInterpreterPythonImpl::GetDynamicSettings( Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); TargetSP target_sp(target->shared_from_this()); - auto setting = (PyObject *)LLDBSWIGPython_GetDynamicSetting( + auto setting = (PyObject *)SWIGBridge::LLDBSWIGPython_GetDynamicSetting( generic->GetValue(), setting_name, target_sp); if (!setting) @@ -1924,7 +1989,7 @@ ScriptInterpreterPythonImpl::CreateSyntheticScriptedProvider( Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - PythonObject ret_val = LLDBSwigPythonCreateSyntheticProvider( + PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateSyntheticProvider( class_name, python_interpreter->m_dictionary_name.c_str(), valobj); return StructuredData::ObjectSP( @@ -1943,11 +2008,14 @@ ScriptInterpreterPythonImpl::CreateScriptCommandObject(const char *class_name) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - PythonObject ret_val = LLDBSwigPythonCreateCommandObject( + PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateCommandObject( class_name, m_dictionary_name.c_str(), debugger_sp); - return StructuredData::GenericSP( - new StructuredPythonObject(std::move(ret_val))); + if (ret_val.IsValid()) + return StructuredData::GenericSP( + new StructuredPythonObject(std::move(ret_val))); + else + return {}; } bool ScriptInterpreterPythonImpl::GenerateTypeScriptFunction( @@ -1965,8 +2033,8 @@ bool ScriptInterpreterPythonImpl::GenerateTypeSynthClass( } Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData( - StringList &user_input, std::string &output, - bool has_extra_args) { + StringList &user_input, std::string &output, bool has_extra_args, + bool is_callback) { static uint32_t num_created_functions = 0; user_input.RemoveBlankLines(); StreamString sstr; @@ -1985,7 +2053,7 @@ Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData( sstr.Printf("def %s (frame, bp_loc, internal_dict):", auto_generated_function_name.c_str()); - error = GenerateFunction(sstr.GetData(), user_input); + error = GenerateFunction(sstr.GetData(), user_input, is_callback); if (!error.Success()) return error; @@ -1995,7 +2063,7 @@ Status ScriptInterpreterPythonImpl::GenerateBreakpointCommandCallbackData( } bool ScriptInterpreterPythonImpl::GenerateWatchpointCommandCallbackData( - StringList &user_input, std::string &output) { + StringList &user_input, std::string &output, bool is_callback) { static uint32_t num_created_functions = 0; user_input.RemoveBlankLines(); StreamString sstr; @@ -2008,7 +2076,7 @@ bool ScriptInterpreterPythonImpl::GenerateWatchpointCommandCallbackData( sstr.Printf("def %s (frame, wp, internal_dict):", auto_generated_function_name.c_str()); - if (!GenerateFunction(sstr.GetData(), user_input).Success()) + if (!GenerateFunction(sstr.GetData(), user_input, is_callback).Success()) return false; // Store the name of the auto-generated function to be called. @@ -2047,7 +2115,7 @@ bool ScriptInterpreterPythonImpl::GetScriptedSummary( static Timer::Category func_cat("LLDBSwigPythonCallTypeScript"); Timer scoped_timer(func_cat, "LLDBSwigPythonCallTypeScript"); - ret_val = LLDBSwigPythonCallTypeScript( + ret_val = SWIGBridge::LLDBSwigPythonCallTypeScript( python_function_name, GetSessionDictionary().get(), valobj, &new_callee, options_sp, retval); } @@ -2071,7 +2139,7 @@ bool ScriptInterpreterPythonImpl::FormatterCallbackFunction( const char *python_function_name, TypeImplSP type_impl_sp) { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - return LLDBSwigPythonFormatterCallbackFunction( + return SWIGBridge::LLDBSwigPythonFormatterCallbackFunction( python_function_name, m_dictionary_name.c_str(), type_impl_sp); } @@ -2111,7 +2179,7 @@ bool ScriptInterpreterPythonImpl::BreakpointCallbackFunction( Locker::InitSession | Locker::NoSTDIN); Expected<bool> maybe_ret_val = - LLDBSwigPythonBreakpointCallbackFunction( + SWIGBridge::LLDBSwigPythonBreakpointCallbackFunction( python_function_name, python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, bp_loc_sp, bp_option_data->m_extra_args); @@ -2172,7 +2240,7 @@ bool ScriptInterpreterPythonImpl::WatchpointCallbackFunction( Locker py_lock(python_interpreter, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSwigPythonWatchpointCallbackFunction( + ret_val = SWIGBridge::LLDBSwigPythonWatchpointCallbackFunction( python_function_name, python_interpreter->m_dictionary_name.c_str(), stop_frame_sp, wp_sp); @@ -2202,7 +2270,7 @@ size_t ScriptInterpreterPythonImpl::CalculateNumChildren( { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSwigPython_CalculateNumChildren(implementor, max); + ret_val = SWIGBridge::LLDBSwigPython_CalculateNumChildren(implementor, max); } return ret_val; @@ -2224,14 +2292,16 @@ lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetChildAtIndex( { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - PyObject *child_ptr = LLDBSwigPython_GetChildAtIndex(implementor, idx); + PyObject *child_ptr = + SWIGBridge::LLDBSwigPython_GetChildAtIndex(implementor, idx); if (child_ptr != nullptr && child_ptr != Py_None) { lldb::SBValue *sb_value_ptr = (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr); if (sb_value_ptr == nullptr) Py_XDECREF(child_ptr); else - ret_val = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr); + ret_val = SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue( + sb_value_ptr); } else { Py_XDECREF(child_ptr); } @@ -2257,7 +2327,7 @@ int ScriptInterpreterPythonImpl::GetIndexOfChildWithName( { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSwigPython_GetIndexOfChildWithName(implementor, child_name); + ret_val = SWIGBridge::LLDBSwigPython_GetIndexOfChildWithName(implementor, child_name); } return ret_val; @@ -2280,7 +2350,8 @@ bool ScriptInterpreterPythonImpl::UpdateSynthProviderInstance( { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSwigPython_UpdateSynthProviderInstance(implementor); + ret_val = + SWIGBridge::LLDBSwigPython_UpdateSynthProviderInstance(implementor); } return ret_val; @@ -2303,8 +2374,8 @@ bool ScriptInterpreterPythonImpl::MightHaveChildrenSynthProviderInstance( { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = - LLDBSwigPython_MightHaveChildrenSynthProviderInstance(implementor); + ret_val = SWIGBridge::LLDBSwigPython_MightHaveChildrenSynthProviderInstance( + implementor); } return ret_val; @@ -2328,14 +2399,15 @@ lldb::ValueObjectSP ScriptInterpreterPythonImpl::GetSyntheticValue( Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); PyObject *child_ptr = - LLDBSwigPython_GetValueSynthProviderInstance(implementor); + SWIGBridge::LLDBSwigPython_GetValueSynthProviderInstance(implementor); if (child_ptr != nullptr && child_ptr != Py_None) { lldb::SBValue *sb_value_ptr = (lldb::SBValue *)LLDBSWIGPython_CastPyObjectToSBValue(child_ptr); if (sb_value_ptr == nullptr) Py_XDECREF(child_ptr); else - ret_val = LLDBSWIGPython_GetValueObjectSPFromSBValue(sb_value_ptr); + ret_val = SWIGBridge::LLDBSWIGPython_GetValueObjectSPFromSBValue( + sb_value_ptr); } else { Py_XDECREF(child_ptr); } @@ -2406,7 +2478,7 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSWIGPythonRunScriptKeywordProcess( + ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordProcess( impl_function, m_dictionary_name.c_str(), process->shared_from_this(), output); if (!ret_val) @@ -2429,9 +2501,10 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - if (std::optional<std::string> result = LLDBSWIGPythonRunScriptKeywordThread( - impl_function, m_dictionary_name.c_str(), - thread->shared_from_this())) { + if (std::optional<std::string> result = + SWIGBridge::LLDBSWIGPythonRunScriptKeywordThread( + impl_function, m_dictionary_name.c_str(), + thread->shared_from_this())) { output = std::move(*result); return true; } @@ -2456,7 +2529,7 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( TargetSP target_sp(target->shared_from_this()); Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSWIGPythonRunScriptKeywordTarget( + ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordTarget( impl_function, m_dictionary_name.c_str(), target_sp, output); if (!ret_val) error.SetErrorString("python script evaluation failed"); @@ -2478,9 +2551,10 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - if (std::optional<std::string> result = LLDBSWIGPythonRunScriptKeywordFrame( - impl_function, m_dictionary_name.c_str(), - frame->shared_from_this())) { + if (std::optional<std::string> result = + SWIGBridge::LLDBSWIGPythonRunScriptKeywordFrame( + impl_function, m_dictionary_name.c_str(), + frame->shared_from_this())) { output = std::move(*result); return true; } @@ -2504,7 +2578,7 @@ bool ScriptInterpreterPythonImpl::RunScriptFormatKeyword( { Locker py_lock(this, Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); - ret_val = LLDBSWIGPythonRunScriptKeywordValue( + ret_val = SWIGBridge::LLDBSWIGPythonRunScriptKeywordValue( impl_function, m_dictionary_name.c_str(), value->GetSP(), output); if (!ret_val) error.SetErrorString("python script evaluation failed"); @@ -2684,9 +2758,9 @@ bool ScriptInterpreterPythonImpl::LoadScriptingModule( // if we are here, everything worked // call __lldb_init_module(debugger,dict) - if (!LLDBSwigPythonCallModuleInit(module_name.c_str(), - m_dictionary_name.c_str(), - m_debugger.shared_from_this())) { + if (!SWIGBridge::LLDBSwigPythonCallModuleInit( + module_name.c_str(), m_dictionary_name.c_str(), + m_debugger.shared_from_this())) { error.SetErrorString("calling __lldb_init_module failed"); return false; } @@ -2780,7 +2854,7 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand( SynchronicityHandler synch_handler(debugger_sp, synchronicity); std::string args_str = args.str(); - ret_val = LLDBSwigPythonCallCommand( + ret_val = SWIGBridge::LLDBSwigPythonCallCommand( impl_function, m_dictionary_name.c_str(), debugger_sp, args_str.c_str(), cmd_retobj, exe_ctx_ref_sp); } @@ -2825,7 +2899,7 @@ bool ScriptInterpreterPythonImpl::RunScriptBasedCommand( SynchronicityHandler synch_handler(debugger_sp, synchronicity); std::string args_str = args.str(); - ret_val = LLDBSwigPythonCallCommandObject( + ret_val = SWIGBridge::LLDBSwigPythonCallCommandObject( static_cast<PyObject *>(impl_obj_sp->GetValue()), debugger_sp, args_str.c_str(), cmd_retobj, exe_ctx_ref_sp); } diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h index f4875bfb8d18..01db6c520300 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPythonImpl.h @@ -83,6 +83,9 @@ public: std::string &error_str, lldb::ThreadPlanSP thread_plan) override; + StructuredData::ObjectSP + CreateStructuredDataFromScriptObject(ScriptObject obj) override; + bool ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp, Event *event, bool &script_error) override; @@ -97,6 +100,11 @@ public: ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error) override; + bool + ScriptedThreadPlanGetStopDescription(StructuredData::ObjectSP implementor_sp, + lldb_private::Stream *s, + bool &script_error) override; + StructuredData::GenericSP CreateScriptedBreakpointResolver(const char *class_name, const StructuredDataImpl &args_data, @@ -124,6 +132,8 @@ public: GetRecognizedArguments(const StructuredData::ObjectSP &implementor, lldb::StackFrameSP frame_sp) override; + lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override; + StructuredData::GenericSP OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp) override; @@ -186,16 +196,17 @@ public: lldb_private::CommandReturnObject &cmd_retobj, Status &error, const lldb_private::ExecutionContext &exe_ctx) override; - Status GenerateFunction(const char *signature, - const StringList &input) override; + Status GenerateFunction(const char *signature, const StringList &input, + bool is_callback) override; - Status GenerateBreakpointCommandCallbackData( - StringList &input, - std::string &output, - bool has_extra_args) override; + Status GenerateBreakpointCommandCallbackData(StringList &input, + std::string &output, + bool has_extra_args, + bool is_callback) override; bool GenerateWatchpointCommandCallbackData(StringList &input, - std::string &output) override; + std::string &output, + bool is_callback) override; bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, @@ -258,7 +269,8 @@ public: /// Set the callback body text into the callback for the breakpoint. Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, - const char *callback_body) override; + const char *callback_body, + bool is_callback) override; Status SetBreakpointCommandCallbackFunction( BreakpointOptions &bp_options, const char *function_name, @@ -272,11 +284,13 @@ public: Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *command_body_text, StructuredData::ObjectSP extra_args_sp, - bool uses_extra_args); + bool uses_extra_args, + bool is_callback); /// Set a one-liner as the callback for the watchpoint. void SetWatchpointCommandCallback(WatchpointOptions *wp_options, - const char *oneliner) override; + const char *user_input, + bool is_callback) override; const char *GetDictionaryName() { return m_dictionary_name.c_str(); } @@ -367,11 +381,18 @@ public: void LeaveSession(); - uint32_t IsExecutingPython() const { return m_lock_count > 0; } + uint32_t IsExecutingPython() { + std::lock_guard<std::mutex> guard(m_mutex); + return m_lock_count > 0; + } - uint32_t IncrementLockCount() { return ++m_lock_count; } + uint32_t IncrementLockCount() { + std::lock_guard<std::mutex> guard(m_mutex); + return ++m_lock_count; + } uint32_t DecrementLockCount() { + std::lock_guard<std::mutex> guard(m_mutex); if (m_lock_count > 0) --m_lock_count; return m_lock_count; @@ -411,6 +432,7 @@ public: bool m_pty_secondary_is_open; bool m_valid_session; uint32_t m_lock_count; + std::mutex m_mutex; PyThreadState *m_command_thread_state; }; @@ -423,10 +445,11 @@ public: ~IOHandlerPythonInterpreter() override = default; - ConstString GetControlSequence(char ch) override { + llvm::StringRef GetControlSequence(char ch) override { + static constexpr llvm::StringLiteral control_sequence("quit()\n"); if (ch == 'd') - return ConstString("quit()\n"); - return ConstString(); + return control_sequence; + return {}; } void Run() override { diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp index 9fbf50114694..a0c55874c70a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPlatformPythonInterface.cpp @@ -44,7 +44,7 @@ StructuredData::GenericSP ScriptedPlatformPythonInterface::CreatePluginObject( lldb::ExecutionContextRefSP exe_ctx_ref_sp = std::make_shared<ExecutionContextRef>(exe_ctx); - PythonObject ret_val = LLDBSwigPythonCreateScriptedObject( + PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject( class_name.str().c_str(), m_interpreter.GetDictionaryName(), exe_ctx_ref_sp, args_impl, error_string); 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 6f087e8390ce..019924fa1971 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -7,15 +7,17 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/Config.h" +#if LLDB_ENABLE_PYTHON +// LLDB Python header must be included first +#include "lldb-python.h" +#endif +#include "lldb/Target/Process.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" #if LLDB_ENABLE_PYTHON -// LLDB Python header must be included first -#include "lldb-python.h" - #include "SWIGPythonBridge.h" #include "ScriptInterpreterPythonImpl.h" #include "ScriptedProcessPythonInterface.h" @@ -46,7 +48,7 @@ StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( lldb::ExecutionContextRefSP exe_ctx_ref_sp = std::make_shared<ExecutionContextRef>(exe_ctx); - PythonObject ret_val = LLDBSwigPythonCreateScriptedObject( + PythonObject ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject( class_name.str().c_str(), m_interpreter.GetDictionaryName(), exe_ctx_ref_sp, args_impl, error_string); @@ -56,26 +58,31 @@ StructuredData::GenericSP ScriptedProcessPythonInterface::CreatePluginObject( return m_object_instance_sp; } -Status ScriptedProcessPythonInterface::Launch() { - return GetStatusFromMethod("launch"); -} - -Status ScriptedProcessPythonInterface::Resume() { - return GetStatusFromMethod("resume"); -} - -bool ScriptedProcessPythonInterface::ShouldStop() { +StructuredData::DictionarySP ScriptedProcessPythonInterface::GetCapabilities() { Status error; - StructuredData::ObjectSP obj = Dispatch("is_alive", error); + StructuredData::DictionarySP dict = + Dispatch<StructuredData::DictionarySP>("get_capabilities", error); - if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) return {}; - return obj->GetBooleanValue(); + return dict; +} + +Status +ScriptedProcessPythonInterface::Attach(const ProcessAttachInfo &attach_info) { + lldb::ProcessAttachInfoSP attach_info_sp = + std::make_shared<ProcessAttachInfo>(attach_info); + return GetStatusFromMethod("attach", attach_info_sp); +} + +Status ScriptedProcessPythonInterface::Launch() { + return GetStatusFromMethod("launch"); } -Status ScriptedProcessPythonInterface::Stop() { - return GetStatusFromMethod("stop"); +Status ScriptedProcessPythonInterface::Resume() { + // When calling ScriptedProcess.Resume from lldb we should always stop. + return GetStatusFromMethod("resume", /*should_stop=*/true); } std::optional<MemoryRegionInfo> @@ -103,23 +110,20 @@ StructuredData::DictionarySP ScriptedProcessPythonInterface::GetThreadsInfo() { return dict; } -StructuredData::DictionarySP -ScriptedProcessPythonInterface::GetThreadWithID(lldb::tid_t tid) { - Status error; - StructuredData::ObjectSP obj = Dispatch("get_thread_with_id", error, tid); +bool ScriptedProcessPythonInterface::CreateBreakpoint(lldb::addr_t addr, + Status &error) { + Status py_error; + StructuredData::ObjectSP obj = + Dispatch("create_breakpoint", py_error, addr, error); + + // If there was an error on the python call, surface it to the user. + if (py_error.Fail()) + error = py_error; if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return {}; - StructuredData::DictionarySP dict{obj->GetAsDictionary()}; - - return dict; -} - -StructuredData::DictionarySP -ScriptedProcessPythonInterface::GetRegistersForThread(lldb::tid_t tid) { - // TODO: Implement - return {}; + return obj->GetBooleanValue(); } lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( @@ -135,19 +139,29 @@ lldb::DataExtractorSP ScriptedProcessPythonInterface::ReadMemoryAtAddress( return data_sp; } +lldb::offset_t ScriptedProcessPythonInterface::WriteMemoryAtAddress( + lldb::addr_t addr, lldb::DataExtractorSP data_sp, Status &error) { + Status py_error; + StructuredData::ObjectSP obj = + Dispatch("write_memory_at_address", py_error, addr, data_sp, error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) + return LLDB_INVALID_OFFSET; + + // If there was an error on the python call, surface it to the user. + if (py_error.Fail()) + error = py_error; + + return obj->GetUnsignedIntegerValue(LLDB_INVALID_OFFSET); +} + 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); - } + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, array, error)) + return {}; return array; } @@ -159,7 +173,7 @@ lldb::pid_t ScriptedProcessPythonInterface::GetProcessID() { if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_PROCESS_ID; - return obj->GetIntegerValue(LLDB_INVALID_PROCESS_ID); + return obj->GetUnsignedIntegerValue(LLDB_INVALID_PROCESS_ID); } bool ScriptedProcessPythonInterface::IsAlive() { 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 6b4ee3021cfa..ff03eab07648 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h @@ -29,13 +29,13 @@ public: StructuredData::DictionarySP args_sp, StructuredData::Generic *script_obj = nullptr) override; - Status Launch() override; + StructuredData::DictionarySP GetCapabilities() override; - Status Resume() override; + Status Attach(const ProcessAttachInfo &attach_info) override; - bool ShouldStop() override; + Status Launch() override; - Status Stop() override; + Status Resume() override; std::optional<MemoryRegionInfo> GetMemoryRegionContainingAddress(lldb::addr_t address, @@ -43,13 +43,15 @@ public: StructuredData::DictionarySP GetThreadsInfo() override; - StructuredData::DictionarySP GetThreadWithID(lldb::tid_t tid) override; - - StructuredData::DictionarySP GetRegistersForThread(lldb::tid_t tid) override; + bool CreateBreakpoint(lldb::addr_t addr, Status &error) override; lldb::DataExtractorSP ReadMemoryAtAddress(lldb::addr_t address, size_t size, Status &error) override; + lldb::offset_t WriteMemoryAtAddress(lldb::addr_t addr, + lldb::DataExtractorSP data_sp, + Status &error) 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 789b39abf587..1e36a81fde54 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.cpp @@ -15,7 +15,6 @@ // LLDB Python header must be included first #include "lldb-python.h" -#include "SWIGPythonBridge.h" #include "ScriptInterpreterPythonImpl.h" #include "ScriptedPythonInterface.h" #include <optional> @@ -47,7 +46,7 @@ template <> Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>( python::PythonObject &p, Status &error) { if (lldb::SBError *sb_error = reinterpret_cast<lldb::SBError *>( - LLDBSWIGPython_CastPyObjectToSBError(p.get()))) + python::LLDBSWIGPython_CastPyObjectToSBError(p.get()))) return m_interpreter.GetStatusFromSBError(*sb_error); else error.SetErrorString("Couldn't cast lldb::SBError to lldb::Status."); @@ -60,7 +59,7 @@ lldb::DataExtractorSP ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>( python::PythonObject &p, Status &error) { lldb::SBData *sb_data = reinterpret_cast<lldb::SBData *>( - LLDBSWIGPython_CastPyObjectToSBData(p.get())); + python::LLDBSWIGPython_CastPyObjectToSBData(p.get())); if (!sb_data) { error.SetErrorString( @@ -72,13 +71,59 @@ ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>( } template <> +lldb::BreakpointSP +ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>( + python::PythonObject &p, Status &error) { + lldb::SBBreakpoint *sb_breakpoint = reinterpret_cast<lldb::SBBreakpoint *>( + python::LLDBSWIGPython_CastPyObjectToSBBreakpoint(p.get())); + + if (!sb_breakpoint) { + error.SetErrorString( + "Couldn't cast lldb::SBBreakpoint to lldb::BreakpointSP."); + return nullptr; + } + + return m_interpreter.GetOpaqueTypeFromSBBreakpoint(*sb_breakpoint); +} + +template <> +lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject< + lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error) { + lldb::SBAttachInfo *sb_attach_info = reinterpret_cast<lldb::SBAttachInfo *>( + python::LLDBSWIGPython_CastPyObjectToSBAttachInfo(p.get())); + + if (!sb_attach_info) { + error.SetErrorString( + "Couldn't cast lldb::SBAttachInfo to lldb::ProcessAttachInfoSP."); + return nullptr; + } + + return m_interpreter.GetOpaqueTypeFromSBAttachInfo(*sb_attach_info); +} + +template <> +lldb::ProcessLaunchInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject< + lldb::ProcessLaunchInfoSP>(python::PythonObject &p, Status &error) { + lldb::SBLaunchInfo *sb_launch_info = reinterpret_cast<lldb::SBLaunchInfo *>( + python::LLDBSWIGPython_CastPyObjectToSBLaunchInfo(p.get())); + + if (!sb_launch_info) { + error.SetErrorString( + "Couldn't cast lldb::SBLaunchInfo to lldb::ProcessLaunchInfoSP."); + return nullptr; + } + + return m_interpreter.GetOpaqueTypeFromSBLaunchInfo(*sb_launch_info); +} + +template <> std::optional<MemoryRegionInfo> ScriptedPythonInterface::ExtractValueFromPythonObject< std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error) { lldb::SBMemoryRegionInfo *sb_mem_reg_info = reinterpret_cast<lldb::SBMemoryRegionInfo *>( - LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(p.get())); + python::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(p.get())); if (!sb_mem_reg_info) { error.SetErrorString( 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 01dc07b49737..4d0645d18aca 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedPythonInterface.h @@ -113,8 +113,25 @@ protected: return {object}; } + python::PythonObject Transform(bool arg) { + // Boolean arguments need to be turned into python objects. + return python::PythonBoolean(arg); + } + python::PythonObject Transform(Status arg) { - return python::ToSWIGWrapper(arg); + return python::SWIGBridge::ToSWIGWrapper(arg); + } + + python::PythonObject Transform(lldb::ProcessAttachInfoSP arg) { + return python::SWIGBridge::ToSWIGWrapper(arg); + } + + python::PythonObject Transform(lldb::ProcessLaunchInfoSP arg) { + return python::SWIGBridge::ToSWIGWrapper(arg); + } + + python::PythonObject Transform(lldb::DataExtractorSP arg) { + return python::SWIGBridge::ToSWIGWrapper(arg); } template <typename T, typename U> @@ -129,6 +146,19 @@ protected: original_arg = ExtractValueFromPythonObject<T>(transformed_arg, error); } + + void ReverseTransform(bool &original_arg, + python::PythonObject transformed_arg, Status &error) { + python::PythonBoolean boolean_arg = python::PythonBoolean( + python::PyRefType::Borrowed, transformed_arg.get()); + if (boolean_arg.IsValid()) + original_arg = boolean_arg.GetValue(); + else + error.SetErrorString( + llvm::formatv("{}: Invalid boolean argument.", LLVM_PRETTY_FUNCTION) + .str()); + } + template <std::size_t... I, typename... Args> auto TransformTuple(const std::tuple<Args...> &args, std::index_sequence<I...>) { @@ -199,6 +229,19 @@ Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>( python::PythonObject &p, Status &error); template <> +lldb::BreakpointSP +ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>( + python::PythonObject &p, Status &error); + +template <> +lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject< + lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error); + +template <> +lldb::ProcessLaunchInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject< + lldb::ProcessLaunchInfoSP>(python::PythonObject &p, Status &error); + +template <> lldb::DataExtractorSP ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>( 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 1b31ed2e5881..5603a1541314 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp @@ -46,7 +46,7 @@ StructuredData::GenericSP ScriptedThreadPythonInterface::CreatePluginObject( if (!script_obj) { lldb::ExecutionContextRefSP exe_ctx_ref_sp = std::make_shared<ExecutionContextRef>(exe_ctx); - ret_val = LLDBSwigPythonCreateScriptedObject( + ret_val = SWIGBridge::LLDBSwigPythonCreateScriptedObject( class_name.str().c_str(), m_interpreter.GetDictionaryName(), exe_ctx_ref_sp, args_impl, error_string); } else @@ -69,7 +69,7 @@ lldb::tid_t ScriptedThreadPythonInterface::GetThreadID() { if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return LLDB_INVALID_THREAD_ID; - return obj->GetIntegerValue(LLDB_INVALID_THREAD_ID); + return obj->GetUnsignedIntegerValue(LLDB_INVALID_THREAD_ID); } std::optional<std::string> ScriptedThreadPythonInterface::GetName() { @@ -89,7 +89,7 @@ lldb::StateType ScriptedThreadPythonInterface::GetState() { if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj, error)) return eStateInvalid; - return static_cast<StateType>(obj->GetIntegerValue(eStateInvalid)); + return static_cast<StateType>(obj->GetUnsignedIntegerValue(eStateInvalid)); } std::optional<std::string> ScriptedThreadPythonInterface::GetQueue() { 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 95182c97baff..a5818915773c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp @@ -131,14 +131,14 @@ public: bool GetEnableOnStartup() const { const uint32_t idx = ePropertyEnableOnStartup; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_darwinlog_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_darwinlog_properties[idx].default_uint_value != 0); } llvm::StringRef GetAutoEnableOptions() const { const uint32_t idx = ePropertyAutoEnableOptions; - return m_collection_sp->GetPropertyAtIndexAsString( - nullptr, idx, g_darwinlog_properties[idx].default_cstr_value); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_darwinlog_properties[idx].default_cstr_value); } const char *GetLoggingModuleName() const { return "libsystem_trace.dylib"; } @@ -162,13 +162,13 @@ const char *const s_filter_attributes[] = { // used to format message text }; -static ConstString GetDarwinLogTypeName() { - static const ConstString s_key_name("DarwinLog"); +static llvm::StringRef GetDarwinLogTypeName() { + static constexpr llvm::StringLiteral s_key_name("DarwinLog"); return s_key_name; } -static ConstString GetLogEventType() { - static const ConstString s_event_type("log"); +static llvm::StringRef GetLogEventType() { + static constexpr llvm::StringLiteral s_event_type("log"); return s_event_type; } @@ -875,9 +875,10 @@ protected: process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName()); stream.Printf("Availability: %s\n", plugin_sp ? "available" : "unavailable"); - llvm::StringRef plugin_name = StructuredDataDarwinLog::GetStaticPluginName(); const bool enabled = - plugin_sp ? plugin_sp->GetEnabled(ConstString(plugin_name)) : false; + plugin_sp ? plugin_sp->GetEnabled( + StructuredDataDarwinLog::GetStaticPluginName()) + : false; stream.Printf("Enabled: %s\n", enabled ? "true" : "false"); } @@ -975,9 +976,10 @@ EnableOptionsSP ParseAutoEnableOptions(Status &error, Debugger &debugger) { // Parse the arguments. auto options_property_sp = - debugger.GetPropertyValue(nullptr, "plugin.structured-data.darwin-log." - "auto-enable-options", - false, error); + debugger.GetPropertyValue(nullptr, + "plugin.structured-data.darwin-log." + "auto-enable-options", + error); if (!error.Success()) return EnableOptionsSP(); if (!options_property_sp) { @@ -1056,12 +1058,12 @@ void StructuredDataDarwinLog::Terminate() { // StructuredDataPlugin API bool StructuredDataDarwinLog::SupportsStructuredDataType( - ConstString type_name) { + llvm::StringRef type_name) { return type_name == GetDarwinLogTypeName(); } void StructuredDataDarwinLog::HandleArrivalOfStructuredData( - Process &process, ConstString type_name, + Process &process, llvm::StringRef type_name, const StructuredData::ObjectSP &object_sp) { Log *log = GetLog(LLDBLog::Process); if (log) { @@ -1085,11 +1087,9 @@ void StructuredDataDarwinLog::HandleArrivalOfStructuredData( // Ignore any data that isn't for us. if (type_name != GetDarwinLogTypeName()) { - LLDB_LOGF(log, - "StructuredDataDarwinLog::%s() StructuredData type " - "expected to be %s but was %s, ignoring", - __FUNCTION__, GetDarwinLogTypeName().AsCString(), - type_name.AsCString()); + LLDB_LOG(log, + "StructuredData type expected to be {0} but was {1}, ignoring", + GetDarwinLogTypeName(), type_name); return; } @@ -1141,7 +1141,7 @@ Status StructuredDataDarwinLog::GetDescription( } // Validate this is really a message for our plugin. - ConstString type_name; + llvm::StringRef type_name; if (!dictionary->GetValueForKeyAsString("type", type_name)) { SetErrorWithJSON(error, "Structured data doesn't contain mandatory " "type field", @@ -1199,11 +1199,10 @@ Status StructuredDataDarwinLog::GetDescription( return error; } -bool StructuredDataDarwinLog::GetEnabled(ConstString type_name) const { - if (type_name.GetStringRef() == GetStaticPluginName()) +bool StructuredDataDarwinLog::GetEnabled(llvm::StringRef type_name) const { + if (type_name == GetStaticPluginName()) return m_is_enabled; - else - return false; + return false; } void StructuredDataDarwinLog::SetEnabled(bool enabled) { @@ -1267,7 +1266,7 @@ void StructuredDataDarwinLog::ModulesDidLoad(Process &process, auto &file_spec = module_sp->GetFileSpec(); found_logging_support_module = - (file_spec.GetLastPathComponent() == logging_module_name); + (file_spec.GetFilename() == logging_module_name); if (found_logging_support_module) break; } @@ -1365,9 +1364,7 @@ void StructuredDataDarwinLog::DebuggerInitialize(Debugger &debugger) { const bool is_global_setting = true; PluginManager::CreateSettingForStructuredDataPlugin( debugger, GetGlobalProperties().GetValueProperties(), - ConstString("Properties for the darwin-log" - " plug-in."), - is_global_setting); + "Properties for the darwin-log plug-in.", is_global_setting); } } @@ -1493,11 +1490,8 @@ bool StructuredDataDarwinLog::InitCompletionHookCallback( auto plugin_sp = process_sp->GetStructuredDataPlugin(GetDarwinLogTypeName()); if (!plugin_sp) { - LLDB_LOGF(log, - "StructuredDataDarwinLog::%s() warning: no plugin for " - "feature %s in process uid %u", - __FUNCTION__, GetDarwinLogTypeName().AsCString(), - process_sp->GetUniqueID()); + LLDB_LOG(log, "warning: no plugin for feature {0} in process uid {1}", + GetDarwinLogTypeName(), process_sp->GetUniqueID()); return false; } @@ -1737,7 +1731,7 @@ StructuredDataDarwinLog::DumpHeader(Stream &output_stream, size_t StructuredDataDarwinLog::HandleDisplayOfEvent( const StructuredData::Dictionary &event, Stream &stream) { // Check the type of the event. - ConstString event_type; + llvm::StringRef event_type; if (!event.GetValueForKeyAsString("type", event_type)) { // Hmm, we expected to get events that describe what they are. Continue // anyway. diff --git a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h index 308fd82e9b12..5b9abf3e603f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h +++ b/contrib/llvm-project/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.h @@ -50,16 +50,16 @@ public: // StructuredDataPlugin API - bool SupportsStructuredDataType(ConstString type_name) override; + bool SupportsStructuredDataType(llvm::StringRef type_name) override; void HandleArrivalOfStructuredData( - Process &process, ConstString type_name, + Process &process, llvm::StringRef type_name, const StructuredData::ObjectSP &object_sp) override; Status GetDescription(const StructuredData::ObjectSP &object_sp, lldb_private::Stream &stream) override; - bool GetEnabled(ConstString type_name) const override; + bool GetEnabled(llvm::StringRef type_name) const override; void ModulesDidLoad(Process &process, ModuleList &module_list) override; 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 6d916df65b9d..cd52233cc8cc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -246,7 +246,7 @@ FunctionSP SymbolFileBreakpad::GetOrCreateFunction(CompileUnit &comp_unit) { if (auto record = FuncRecord::parse(*It)) { Mangled func_name; - func_name.SetValue(ConstString(record->Name), false); + func_name.SetValue(ConstString(record->Name)); addr_t address = record->Address + base; SectionSP section_sp = list->FindSectionContainingFileAddress(address); if (section_sp) { 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 6d9336966517..4a01a64202ee 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -10,11 +10,11 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H #include "Plugins/ObjectFile/Breakpad/BreakpadRecords.h" -#include "lldb/Core/FileSpecList.h" #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/PostfixExpression.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Utility/FileSpecList.h" #include <optional> namespace lldb_private { @@ -134,9 +134,9 @@ public: llvm::inconvertibleErrorCode()); } - CompilerDeclContext - FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) override { + CompilerDeclContext FindNamespace(ConstString name, + const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override { return CompilerDeclContext(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp new file mode 100644 index 000000000000..88926baa7a6e --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp @@ -0,0 +1,1025 @@ +//===-- SymbolFileCTF.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 "SymbolFileCTF.h" + +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamBuffer.h" +#include "lldb/Host/Config.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Symtab.h" +#include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/TypeMap.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/Timer.h" +#include "llvm/Support/MemoryBuffer.h" + +#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" +#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" + +#include <memory> +#include <optional> + +#if LLVM_ENABLE_ZLIB +#include <zlib.h> +#endif + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(SymbolFileCTF) + +char SymbolFileCTF::ID; + +SymbolFileCTF::SymbolFileCTF(lldb::ObjectFileSP objfile_sp) + : SymbolFileCommon(std::move(objfile_sp)) {} + +void SymbolFileCTF::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); +} + +void SymbolFileCTF::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +llvm::StringRef SymbolFileCTF::GetPluginDescriptionStatic() { + return "Compact C Type Format Symbol Reader"; +} + +SymbolFile *SymbolFileCTF::CreateInstance(ObjectFileSP objfile_sp) { + return new SymbolFileCTF(std::move(objfile_sp)); +} + +bool SymbolFileCTF::ParseHeader() { + if (m_header) + return true; + + Log *log = GetLog(LLDBLog::Symbols); + + ModuleSP module_sp(m_objfile_sp->GetModule()); + const SectionList *section_list = module_sp->GetSectionList(); + if (!section_list) + return false; + + SectionSP section_sp( + section_list->FindSectionByType(lldb::eSectionTypeCTF, true)); + if (!section_sp) + return false; + + m_objfile_sp->ReadSectionData(section_sp.get(), m_data); + + if (m_data.GetByteSize() == 0) + return false; + + StreamString module_desc; + GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(), + lldb::eDescriptionLevelBrief); + LLDB_LOG(log, "Parsing Compact C Type format for {0}", module_desc.GetData()); + + lldb::offset_t offset = 0; + + // Parse CTF header. + constexpr size_t ctf_header_size = sizeof(ctf_header_t); + if (!m_data.ValidOffsetForDataOfSize(offset, ctf_header_size)) { + LLDB_LOG(log, "CTF parsing failed: insufficient data for CTF header"); + return false; + } + + m_header.emplace(); + + ctf_header_t &ctf_header = *m_header; + ctf_header.preamble.magic = m_data.GetU16(&offset); + ctf_header.preamble.version = m_data.GetU8(&offset); + ctf_header.preamble.flags = m_data.GetU8(&offset); + ctf_header.parlabel = m_data.GetU32(&offset); + ctf_header.parname = m_data.GetU32(&offset); + ctf_header.lbloff = m_data.GetU32(&offset); + ctf_header.objtoff = m_data.GetU32(&offset); + ctf_header.funcoff = m_data.GetU32(&offset); + ctf_header.typeoff = m_data.GetU32(&offset); + ctf_header.stroff = m_data.GetU32(&offset); + ctf_header.strlen = m_data.GetU32(&offset); + + // Validate the preamble. + if (ctf_header.preamble.magic != g_ctf_magic) { + LLDB_LOG(log, "CTF parsing failed: invalid magic: {0:x}", + ctf_header.preamble.magic); + return false; + } + + if (ctf_header.preamble.version != g_ctf_version) { + LLDB_LOG(log, "CTF parsing failed: unsupported version: {0}", + ctf_header.preamble.version); + return false; + } + + LLDB_LOG(log, "Parsed valid CTF preamble: version {0}, flags {1:x}", + ctf_header.preamble.version, ctf_header.preamble.flags); + + m_body_offset = offset; + + if (ctf_header.preamble.flags & eFlagCompress) { + // The body has been compressed with zlib deflate. Header offsets point into + // the decompressed data. +#if LLVM_ENABLE_ZLIB + const std::size_t decompressed_size = ctf_header.stroff + ctf_header.strlen; + DataBufferSP decompressed_data = + std::make_shared<DataBufferHeap>(decompressed_size, 0x0); + + z_stream zstr; + memset(&zstr, 0, sizeof(zstr)); + zstr.next_in = (Bytef *)const_cast<uint8_t *>(m_data.GetDataStart() + + sizeof(ctf_header_t)); + zstr.avail_in = m_data.BytesLeft(offset); + zstr.next_out = + (Bytef *)const_cast<uint8_t *>(decompressed_data->GetBytes()); + zstr.avail_out = decompressed_size; + + int rc = inflateInit(&zstr); + if (rc != Z_OK) { + LLDB_LOG(log, "CTF parsing failed: inflate initialization error: {0}", + zError(rc)); + return false; + } + + rc = inflate(&zstr, Z_FINISH); + if (rc != Z_STREAM_END) { + LLDB_LOG(log, "CTF parsing failed: inflate error: {0}", zError(rc)); + return false; + } + + rc = inflateEnd(&zstr); + if (rc != Z_OK) { + LLDB_LOG(log, "CTF parsing failed: inflate end error: {0}", zError(rc)); + return false; + } + + if (zstr.total_out != decompressed_size) { + LLDB_LOG(log, + "CTF parsing failed: decompressed size ({0}) doesn't match " + "expected size ([1})", + zstr.total_out, decompressed_size); + return false; + } + + m_data = DataExtractor(decompressed_data, m_data.GetByteOrder(), + m_data.GetAddressByteSize()); + m_body_offset = 0; +#else + LLDB_LOG( + log, + "CTF parsing failed: data is compressed but no zlib inflate support"); + return false; +#endif + } + + // Validate the header. + if (!m_data.ValidOffset(m_body_offset + ctf_header.lbloff)) { + LLDB_LOG(log, + "CTF parsing failed: invalid label section offset in header: {0}", + ctf_header.lbloff); + return false; + } + + if (!m_data.ValidOffset(m_body_offset + ctf_header.objtoff)) { + LLDB_LOG(log, + "CTF parsing failed: invalid object section offset in header: {0}", + ctf_header.objtoff); + return false; + } + + if (!m_data.ValidOffset(m_body_offset + ctf_header.funcoff)) { + LLDB_LOG( + log, + "CTF parsing failed: invalid function section offset in header: {0}", + ctf_header.funcoff); + return false; + } + + if (!m_data.ValidOffset(m_body_offset + ctf_header.typeoff)) { + LLDB_LOG(log, + "CTF parsing failed: invalid type section offset in header: {0}", + ctf_header.typeoff); + return false; + } + + if (!m_data.ValidOffset(m_body_offset + ctf_header.stroff)) { + LLDB_LOG(log, + "CTF parsing failed: invalid string section offset in header: {0}", + ctf_header.stroff); + return false; + } + + const lldb::offset_t str_end_offset = + m_body_offset + ctf_header.stroff + ctf_header.strlen; + if (!m_data.ValidOffset(str_end_offset - 1)) { + LLDB_LOG(log, + "CTF parsing failed: invalid string section length in header: {0}", + ctf_header.strlen); + return false; + } + + if (m_body_offset + ctf_header.stroff + ctf_header.parlabel > + str_end_offset) { + LLDB_LOG(log, + "CTF parsing failed: invalid parent label offset: {0} exceeds end " + "of string section ({1})", + ctf_header.parlabel, str_end_offset); + return false; + } + + if (m_body_offset + ctf_header.stroff + ctf_header.parname > str_end_offset) { + LLDB_LOG(log, + "CTF parsing failed: invalid parent name offset: {0} exceeds end " + "of string section ({1})", + ctf_header.parname, str_end_offset); + return false; + } + + LLDB_LOG(log, + "Parsed valid CTF header: lbloff = {0}, objtoff = {1}, funcoff = " + "{2}, typeoff = {3}, stroff = {4}, strlen = {5}", + ctf_header.lbloff, ctf_header.objtoff, ctf_header.funcoff, + ctf_header.typeoff, ctf_header.stroff, ctf_header.strlen); + + return true; +} + +void SymbolFileCTF::InitializeObject() { + Log *log = GetLog(LLDBLog::Symbols); + + auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC); + if (auto err = type_system_or_err.takeError()) { + LLDB_LOG_ERROR(log, std::move(err), "Unable to get type system: {0}"); + return; + } + + auto ts = *type_system_or_err; + m_ast = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get()); + LazyBool optimized = eLazyBoolNo; + m_comp_unit_sp = std::make_shared<CompileUnit>( + m_objfile_sp->GetModule(), nullptr, "", 0, eLanguageTypeC, optimized); + + ParseTypes(*m_comp_unit_sp); +} + +llvm::StringRef SymbolFileCTF::ReadString(lldb::offset_t str_offset) const { + lldb::offset_t offset = m_body_offset + m_header->stroff + str_offset; + if (!m_data.ValidOffset(offset)) + return "(invalid)"; + const char *str = m_data.GetCStr(&offset); + if (str && !*str) + return "(anon)"; + return llvm::StringRef(str); +} + +/// Return the integer display representation encoded in the given data. +static uint32_t GetEncoding(uint32_t data) { + // Mask bits 24–31. + return ((data)&0xff000000) >> 24; +} + +/// Return the integral width in bits encoded in the given data. +static uint32_t GetBits(uint32_t data) { + // Mask bits 0-15. + return (data)&0x0000ffff; +} + +/// Return the type kind encoded in the given data. +uint32_t GetKind(uint32_t data) { + // Mask bits 26–31. + return ((data)&0xf800) >> 11; +} + +/// Return the variable length encoded in the given data. +uint32_t GetVLen(uint32_t data) { + // Mask bits 0–24. + return (data)&0x3ff; +} + +static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); } + +static clang::TagTypeKind TranslateRecordKind(SymbolFileCTF::TypeKind type) { + switch (type) { + case SymbolFileCTF::TypeKind::eStruct: + return clang::TTK_Struct; + case SymbolFileCTF::TypeKind::eUnion: + return clang::TTK_Union; + default: + lldbassert(false && "Invalid record kind!"); + return clang::TTK_Struct; + } +} + +llvm::Expected<TypeSP> SymbolFileCTF::ParseInteger(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name) { + const uint32_t vdata = m_data.GetU32(&offset); + const uint32_t bits = GetBits(vdata); + const uint32_t encoding = GetEncoding(vdata); + + lldb::BasicType basic_type = TypeSystemClang::GetBasicTypeEnumeration(name); + if (basic_type == eBasicTypeInvalid) + return llvm::make_error<llvm::StringError>( + llvm::formatv("unsupported integer type: no corresponding basic clang " + "type for '{0}'", + name), + llvm::inconvertibleErrorCode()); + + CompilerType compiler_type = m_ast->GetBasicType(basic_type); + + if (basic_type != eBasicTypeVoid) { + // Make sure the type we got is an integer type. + bool compiler_type_is_signed = false; + if (!compiler_type.IsIntegerType(compiler_type_is_signed)) + return llvm::make_error<llvm::StringError>( + llvm::formatv( + "Found compiler type for '{0}' but it's not an integer type: {1}", + name, compiler_type.GetDisplayTypeName().GetStringRef()), + llvm::inconvertibleErrorCode()); + + // Make sure the signing matches between the CTF and the compiler type. + const bool type_is_signed = (encoding & IntEncoding::eSigned); + if (compiler_type_is_signed != type_is_signed) + return llvm::make_error<llvm::StringError>( + llvm::formatv("Found integer compiler type for {0} but compiler type " + "is {1} and {0} is {2}", + name, compiler_type_is_signed ? "signed" : "unsigned", + type_is_signed ? "signed" : "unsigned"), + llvm::inconvertibleErrorCode()); + } + + Declaration decl; + return MakeType(uid, ConstString(name), GetBytes(bits), nullptr, + LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, + compiler_type, lldb_private::Type::ResolveState::Full); +} + +llvm::Expected<lldb::TypeSP> +SymbolFileCTF::ParseModifierType(lldb::offset_t &offset, lldb::user_id_t uid, + uint32_t kind, uint32_t type) { + TypeSP ref_type = GetTypeForUID(type); + if (!ref_type) + return llvm::make_error<llvm::StringError>( + llvm::formatv("Could not find modified type: {0}", type), + llvm::inconvertibleErrorCode()); + + CompilerType compiler_type; + + switch (kind) { + case TypeKind::ePointer: + compiler_type = ref_type->GetFullCompilerType().GetPointerType(); + break; + case TypeKind::eConst: + compiler_type = ref_type->GetFullCompilerType().AddConstModifier(); + break; + case TypeKind::eVolatile: + compiler_type = ref_type->GetFullCompilerType().AddVolatileModifier(); + break; + case TypeKind::eRestrict: + compiler_type = ref_type->GetFullCompilerType().AddRestrictModifier(); + break; + default: + return llvm::make_error<llvm::StringError>( + llvm::formatv("ParseModifierType called with unsupported kind: {0}", + kind), + llvm::inconvertibleErrorCode()); + } + + Declaration decl; + return MakeType(uid, ConstString(), 0, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, compiler_type, + lldb_private::Type::ResolveState::Full); +} + +llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseTypedef(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name, + uint32_t type) { + TypeSP underlying_type = GetTypeForUID(type); + if (!underlying_type) + return llvm::make_error<llvm::StringError>( + llvm::formatv("Could not find typedef underlying type: {0}", type), + llvm::inconvertibleErrorCode()); + + CompilerType target_ast_type = underlying_type->GetFullCompilerType(); + clang::DeclContext *decl_ctx = m_ast->GetTranslationUnitDecl(); + CompilerType ast_typedef = target_ast_type.CreateTypedef( + name.data(), m_ast->CreateDeclContext(decl_ctx), 0); + + Declaration decl; + return MakeType(uid, ConstString(name), 0, nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, decl, ast_typedef, + lldb_private::Type::ResolveState::Full); +} + +llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseArray(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name) { + ctf_array_t ctf_array; + ctf_array.contents = m_data.GetU32(&offset); + ctf_array.index = m_data.GetU32(&offset); + ctf_array.nelems = m_data.GetU32(&offset); + + TypeSP element_type = GetTypeForUID(ctf_array.contents); + if (!element_type) + return llvm::make_error<llvm::StringError>( + llvm::formatv("Could not find array element type: {0}", + ctf_array.contents), + llvm::inconvertibleErrorCode()); + + std::optional<uint64_t> element_size = element_type->GetByteSize(nullptr); + if (!element_size) + return llvm::make_error<llvm::StringError>( + llvm::formatv("could not get element size of type: {0}", + ctf_array.contents), + llvm::inconvertibleErrorCode()); + + uint64_t size = ctf_array.nelems * *element_size; + + CompilerType compiler_type = m_ast->CreateArrayType( + element_type->GetFullCompilerType(), ctf_array.nelems, + /*is_gnu_vector*/ false); + + Declaration decl; + return MakeType(uid, ConstString(), size, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, compiler_type, + lldb_private::Type::ResolveState::Full); +} + +llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseEnum(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name, + uint32_t elements, + uint32_t size) { + Declaration decl; + CompilerType enum_type = m_ast->CreateEnumerationType( + name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl, + m_ast->GetBasicType(eBasicTypeInt), + /*is_scoped=*/false); + + for (uint32_t i = 0; i < elements; ++i) { + ctf_enum_t ctf_enum; + ctf_enum.name = m_data.GetU32(&offset); + ctf_enum.value = m_data.GetU32(&offset); + + llvm::StringRef value_name = ReadString(ctf_enum.name); + const uint32_t value = ctf_enum.value; + + Declaration value_decl; + m_ast->AddEnumerationValueToEnumerationType(enum_type, value_decl, + value_name.data(), value, size); + } + + return MakeType(uid, ConstString(), 0, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, enum_type, + lldb_private::Type::ResolveState::Full); +} + +llvm::Expected<lldb::TypeSP> +SymbolFileCTF::ParseFunction(lldb::offset_t &offset, lldb::user_id_t uid, + llvm::StringRef name, uint32_t num_args, + uint32_t type) { + std::vector<CompilerType> arg_types; + arg_types.reserve(num_args); + + bool is_variadic = false; + for (uint32_t i = 0; i < num_args; ++i) { + const uint32_t arg_uid = m_data.GetU32(&offset); + + // If the last argument is 0, this is a variadic function. + if (arg_uid == 0) { + is_variadic = true; + break; + } + + if (TypeSP arg_type = GetTypeForUID(arg_uid)) + arg_types.push_back(arg_type->GetFullCompilerType()); + } + + // If the number of arguments is odd, a single uint32_t of padding is inserted + // to maintain alignment. + if (num_args % 2 == 1) + m_data.GetU32(&offset); + + TypeSP ret_type = GetTypeForUID(type); + if (!ret_type) + return llvm::make_error<llvm::StringError>( + llvm::formatv("Could not find function return type: {0}", type), + llvm::inconvertibleErrorCode()); + + CompilerType func_type = m_ast->CreateFunctionType( + ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(), + is_variadic, 0, clang::CallingConv::CC_C); + + Declaration decl; + return MakeType(uid, ConstString(name), 0, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, func_type, + lldb_private::Type::ResolveState::Full); +} + +llvm::Expected<lldb::TypeSP> +SymbolFileCTF::ParseRecord(lldb::offset_t &offset, lldb::user_id_t uid, + llvm::StringRef name, uint32_t kind, uint32_t fields, + uint32_t size) { + const clang::TagTypeKind tag_kind = + TranslateRecordKind(static_cast<TypeKind>(kind)); + + CompilerType union_type = + m_ast->CreateRecordType(nullptr, OptionalClangModuleID(), eAccessPublic, + name.data(), tag_kind, eLanguageTypeC); + + m_ast->StartTagDeclarationDefinition(union_type); + for (uint32_t i = 0; i < fields; ++i) { + ctf_member_t ctf_member; + ctf_member.name = m_data.GetU32(&offset); + ctf_member.type = m_data.GetU32(&offset); + ctf_member.offset = m_data.GetU16(&offset); + ctf_member.padding = m_data.GetU16(&offset); + + llvm::StringRef member_name = ReadString(ctf_member.name); + const uint32_t member_type_uid = ctf_member.type; + + if (TypeSP member_type = GetTypeForUID(member_type_uid)) { + const uint32_t member_size = + member_type->GetByteSize(nullptr).value_or(0); + TypeSystemClang::AddFieldToRecordType(union_type, member_name, + member_type->GetFullCompilerType(), + eAccessPublic, member_size); + } + } + m_ast->CompleteTagDeclarationDefinition(union_type); + + Declaration decl; + return MakeType(uid, ConstString(name), size, nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, decl, union_type, + lldb_private::Type::ResolveState::Full); +} + +llvm::Expected<TypeSP> SymbolFileCTF::ParseType( + lldb::offset_t &offset, lldb::user_id_t uid, llvm::StringRef name, + uint32_t kind, uint32_t variable_length, uint32_t type, uint32_t size) { + switch (kind) { + case TypeKind::eInteger: + return ParseInteger(offset, uid, name); + case TypeKind::eConst: + case TypeKind::ePointer: + case TypeKind::eRestrict: + case TypeKind::eVolatile: + return ParseModifierType(offset, uid, kind, type); + case TypeKind::eTypedef: + return ParseTypedef(offset, uid, name, type); + case TypeKind::eArray: + return ParseArray(offset, uid, name); + case TypeKind::eEnum: + return ParseEnum(offset, uid, name, variable_length, size); + case TypeKind::eFunction: + return ParseFunction(offset, uid, name, variable_length, size); + case TypeKind::eStruct: + case TypeKind::eUnion: + return ParseRecord(offset, uid, name, kind, variable_length, size); + case TypeKind::eFloat: + case TypeKind::eForward: + case TypeKind::eSlice: + case TypeKind::eUnknown: + offset += (variable_length * sizeof(uint32_t)); + break; + } + return llvm::make_error<llvm::StringError>( + llvm::formatv("unsupported type (name = {0}, kind = {1}, vlength = {2})", + name, kind, variable_length), + llvm::inconvertibleErrorCode()); +} + +size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) { + if (!ParseHeader()) + return 0; + + if (!m_types.empty()) + return 0; + + if (!m_ast) + return 0; + + Log *log = GetLog(LLDBLog::Symbols); + LLDB_LOG(log, "Parsing CTF types"); + + lldb::offset_t type_offset = m_body_offset + m_header->typeoff; + const lldb::offset_t type_offset_end = m_body_offset + m_header->stroff; + + lldb::user_id_t type_uid = 1; + while (type_offset < type_offset_end) { + ctf_stype_t ctf_stype; + ctf_stype.name = m_data.GetU32(&type_offset); + ctf_stype.info = m_data.GetU32(&type_offset); + ctf_stype.size = m_data.GetU32(&type_offset); + + llvm::StringRef name = ReadString(ctf_stype.name); + const uint32_t kind = GetKind(ctf_stype.info); + const uint32_t variable_length = GetVLen(ctf_stype.info); + const uint32_t type = ctf_stype.GetType(); + const uint32_t size = ctf_stype.GetSize(); + + TypeSP type_sp; + llvm::Expected<TypeSP> type_or_error = ParseType( + type_offset, type_uid, name, kind, variable_length, type, size); + if (!type_or_error) { + LLDB_LOG_ERROR(log, type_or_error.takeError(), + "Failed to parse type {1} at offset {2}: {0}", type_uid, + type_offset); + } else { + type_sp = *type_or_error; + if (log) { + StreamString ss; + type_sp->Dump(&ss, true); + LLDB_LOGV(log, "Adding type {0}: {1}", type_uid, + llvm::StringRef(ss.GetString()).rtrim()); + } + } + + AddTypeForUID(type_uid++, type_sp); + } + + if (log) { + size_t skipped_types = 0; + for (auto &type : m_types) { + if (!type) + skipped_types++; + } + LLDB_LOG(log, "Parsed {0} CTF types ({1} skipped)", m_types.size(), + skipped_types); + } + + return m_types.size(); +} + +size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) { + if (!ParseHeader()) + return 0; + + if (!m_functions.empty()) + return 0; + + if (!m_ast) + return 0; + + Symtab *symtab = GetObjectFile()->GetModule()->GetSymtab(); + if (!symtab) + return 0; + + Log *log = GetLog(LLDBLog::Symbols); + LLDB_LOG(log, "Parsing CTF functions"); + + lldb::offset_t function_offset = m_body_offset + m_header->funcoff; + const lldb::offset_t function_offset_end = m_body_offset + m_header->typeoff; + + uint32_t symbol_idx = 0; + Declaration decl; + while (function_offset < function_offset_end) { + const uint32_t info = m_data.GetU32(&function_offset); + const uint16_t kind = GetKind(info); + const uint16_t variable_length = GetVLen(info); + + Symbol *symbol = symtab->FindSymbolWithType( + eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, symbol_idx); + + // Skip padding. + if (kind == TypeKind::eUnknown && variable_length == 0) + continue; + + // Skip unexpected kinds. + if (kind != TypeKind::eFunction) + continue; + + const uint32_t ret_uid = m_data.GetU32(&function_offset); + const uint32_t num_args = variable_length; + + std::vector<CompilerType> arg_types; + arg_types.reserve(num_args); + + bool is_variadic = false; + for (uint32_t i = 0; i < variable_length; i++) { + const uint32_t arg_uid = m_data.GetU32(&function_offset); + + // If the last argument is 0, this is a variadic function. + if (arg_uid == 0) { + is_variadic = true; + break; + } + + TypeSP arg_type = GetTypeForUID(arg_uid); + arg_types.push_back(arg_type->GetFullCompilerType()); + } + + if (symbol) { + TypeSP ret_type = GetTypeForUID(ret_uid); + AddressRange func_range = + AddressRange(symbol->GetFileAddress(), symbol->GetByteSize(), + GetObjectFile()->GetModule()->GetSectionList()); + + // Create function type. + CompilerType func_type = m_ast->CreateFunctionType( + ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(), + is_variadic, 0, clang::CallingConv::CC_C); + lldb::user_id_t function_type_uid = m_types.size() + 1; + TypeSP type_sp = + MakeType(function_type_uid, symbol->GetName(), 0, nullptr, + LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type, + lldb_private::Type::ResolveState::Full); + AddTypeForUID(function_type_uid, type_sp); + + // Create function. + lldb::user_id_t func_uid = m_functions.size(); + FunctionSP function_sp = std::make_shared<Function>( + &cu, func_uid, function_type_uid, symbol->GetMangled(), type_sp.get(), + func_range); + m_functions.emplace_back(function_sp); + cu.AddFunction(function_sp); + } + } + + LLDB_LOG(log, "CTF parsed {0} functions", m_functions.size()); + + return m_functions.size(); +} + +static DWARFExpression CreateDWARFExpression(ModuleSP module_sp, + const Symbol &symbol) { + if (!module_sp) + return DWARFExpression(); + + const ArchSpec &architecture = module_sp->GetArchitecture(); + ByteOrder byte_order = architecture.GetByteOrder(); + uint32_t address_size = architecture.GetAddressByteSize(); + uint32_t byte_size = architecture.GetDataByteSize(); + + StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); + stream.PutHex8(lldb_private::dwarf::DW_OP_addr); + stream.PutMaxHex64(symbol.GetFileAddress(), address_size, byte_order); + + DataBufferSP buffer = + std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize()); + lldb_private::DataExtractor extractor(buffer, byte_order, address_size, + byte_size); + DWARFExpression result(extractor); + result.SetRegisterKind(eRegisterKindDWARF); + + return result; +} + +size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) { + if (!ParseHeader()) + return 0; + + if (!m_variables.empty()) + return 0; + + if (!m_ast) + return 0; + + ModuleSP module_sp = GetObjectFile()->GetModule(); + Symtab *symtab = module_sp->GetSymtab(); + if (!symtab) + return 0; + + Log *log = GetLog(LLDBLog::Symbols); + LLDB_LOG(log, "Parsing CTF objects"); + + lldb::offset_t object_offset = m_body_offset + m_header->objtoff; + const lldb::offset_t object_offset_end = m_body_offset + m_header->funcoff; + + uint32_t symbol_idx = 0; + Declaration decl; + while (object_offset < object_offset_end) { + const uint32_t type_uid = m_data.GetU32(&object_offset); + + if (Symbol *symbol = + symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes, + Symtab::eVisibilityAny, symbol_idx)) { + + Variable::RangeList ranges; + ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize()); + + auto type_sp = std::make_shared<SymbolFileType>(*this, type_uid); + + DWARFExpressionList location( + module_sp, CreateDWARFExpression(module_sp, *symbol), nullptr); + + lldb::user_id_t variable_type_uid = m_variables.size(); + m_variables.emplace_back(std::make_shared<Variable>( + variable_type_uid, symbol->GetName().AsCString(), + symbol->GetName().AsCString(), type_sp, eValueTypeVariableGlobal, + m_comp_unit_sp.get(), ranges, &decl, location, symbol->IsExternal(), + /*artificial=*/false, + /*location_is_constant_data*/ false)); + } + } + + LLDB_LOG(log, "Parsed {0} CTF objects", m_variables.size()); + + return m_variables.size(); +} + +uint32_t SymbolFileCTF::CalculateAbilities() { + if (!m_objfile_sp) + return 0; + + if (!ParseHeader()) + return 0; + + return VariableTypes | Functions | GlobalVariables; +} + +uint32_t SymbolFileCTF::ResolveSymbolContext(const Address &so_addr, + SymbolContextItem resolve_scope, + SymbolContext &sc) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + if (m_objfile_sp->GetSymtab() == nullptr) + return 0; + + uint32_t resolved_flags = 0; + + // Resolve symbols. + if (resolve_scope & eSymbolContextSymbol) { + sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress( + so_addr.GetFileAddress()); + if (sc.symbol) + resolved_flags |= eSymbolContextSymbol; + } + + // Resolve functions. + if (resolve_scope & eSymbolContextFunction) { + for (FunctionSP function_sp : m_functions) { + if (function_sp->GetAddressRange().ContainsFileAddress( + so_addr.GetFileAddress())) { + sc.function = function_sp.get(); + resolved_flags |= eSymbolContextFunction; + break; + } + } + } + + // Resolve variables. + if (resolve_scope & eSymbolContextVariable) { + for (VariableSP variable_sp : m_variables) { + if (variable_sp->LocationIsValidForAddress(so_addr.GetFileAddress())) { + sc.variable = variable_sp.get(); + break; + } + } + } + + return resolved_flags; +} + +CompUnitSP SymbolFileCTF::ParseCompileUnitAtIndex(uint32_t idx) { + if (idx == 0) + return m_comp_unit_sp; + return {}; +} + +size_t +SymbolFileCTF::ParseVariablesForContext(const lldb_private::SymbolContext &sc) { + return ParseObjects(*m_comp_unit_sp); +} + +void SymbolFileCTF::AddSymbols(Symtab &symtab) { + // CTF does not encode symbols. + // We rely on the existing symbol table to map symbols to type. +} + +void SymbolFileCTF::AddTypeForUID(lldb::user_id_t type_uid, lldb::TypeSP type) { + assert(type_uid == m_types.size() + 1); + m_types.emplace_back(type); +} + +TypeSP SymbolFileCTF::GetTypeForUID(lldb::user_id_t type_uid) { + if (type_uid > m_types.size()) + return {}; + + if (type_uid < 1) + return {}; + + return m_types[type_uid - 1]; +} + +lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) { + return GetTypeForUID(type_uid).get(); +} + +void SymbolFileCTF::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) { + + searched_symbol_files.clear(); + searched_symbol_files.insert(this); + + size_t matches = 0; + for (TypeSP type_sp : m_types) { + if (matches == max_matches) + break; + if (type_sp && type_sp->GetName() == name) { + types.Insert(type_sp); + matches++; + } + } +} + +void SymbolFileCTF::FindTypesByRegex( + const lldb_private::RegularExpression ®ex, uint32_t max_matches, + lldb_private::TypeMap &types) { + ParseTypes(*m_comp_unit_sp); + + size_t matches = 0; + for (TypeSP type_sp : m_types) { + if (matches == max_matches) + break; + if (type_sp && regex.Execute(type_sp->GetName())) + types.Insert(type_sp); + matches++; + } +} + +void SymbolFileCTF::FindFunctions( + const lldb_private::Module::LookupInfo &lookup_info, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + bool include_inlines, lldb_private::SymbolContextList &sc_list) { + ParseFunctions(*m_comp_unit_sp); + + ConstString name = lookup_info.GetLookupName(); + for (FunctionSP function_sp : m_functions) { + if (function_sp && function_sp->GetName() == name) { + lldb_private::SymbolContext sc; + sc.comp_unit = m_comp_unit_sp.get(); + sc.function = function_sp.get(); + sc_list.Append(sc); + } + } +} + +void SymbolFileCTF::FindFunctions(const lldb_private::RegularExpression ®ex, + bool include_inlines, + lldb_private::SymbolContextList &sc_list) { + for (FunctionSP function_sp : m_functions) { + if (function_sp && regex.Execute(function_sp->GetName())) { + lldb_private::SymbolContext sc; + sc.comp_unit = m_comp_unit_sp.get(); + sc.function = function_sp.get(); + sc_list.Append(sc); + } + } +} + +void SymbolFileCTF::FindGlobalVariables( + lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + uint32_t max_matches, lldb_private::VariableList &variables) { + ParseObjects(*m_comp_unit_sp); + + size_t matches = 0; + for (VariableSP variable_sp : m_variables) { + if (matches == max_matches) + break; + if (variable_sp && variable_sp->GetName() == name) { + variables.AddVariable(variable_sp); + matches++; + } + } +} + +void SymbolFileCTF::FindGlobalVariables( + const lldb_private::RegularExpression ®ex, uint32_t max_matches, + lldb_private::VariableList &variables) { + ParseObjects(*m_comp_unit_sp); + + size_t matches = 0; + for (VariableSP variable_sp : m_variables) { + if (matches == max_matches) + break; + if (variable_sp && regex.Execute(variable_sp->GetName())) { + variables.AddVariable(variable_sp); + matches++; + } + } +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h new file mode 100644 index 000000000000..bdd6dcdc3fda --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.h @@ -0,0 +1,300 @@ +//===-- SymbolFileCTF.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_SYMBOLFILE_CTF_SYMBOLFILECTF_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H + +#include <map> +#include <optional> +#include <vector> + +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/SymbolFile.h" + +namespace lldb_private { + +class SymbolFileCTF : public lldb_private::SymbolFileCommon { + /// LLVM RTTI support. + static char ID; + +public: + /// LLVM RTTI support. + /// \{ + bool isA(const void *ClassID) const override { + return ClassID == &ID || SymbolFileCommon::isA(ClassID); + } + static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } + /// \} + + SymbolFileCTF(lldb::ObjectFileSP objfile_sp); + + static void Initialize(); + + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "CTF"; } + + static llvm::StringRef GetPluginDescriptionStatic(); + + static lldb_private::SymbolFile * + CreateInstance(lldb::ObjectFileSP objfile_sp); + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + uint32_t CalculateAbilities() override; + + void InitializeObject() override; + + lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { + return lldb::eLanguageTypeUnknown; + } + + bool ParseHeader(); + + size_t ParseFunctions(CompileUnit &comp_unit) override; + + size_t ParseObjects(CompileUnit &comp_unit); + + bool ParseLineTable(CompileUnit &comp_unit) override { return false; } + + bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } + + bool ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) override { + return false; + } + + size_t ParseTypes(CompileUnit &cu) override; + + bool ParseImportedModules( + const SymbolContext &sc, + std::vector<lldb_private::SourceModule> &imported_modules) override { + return false; + } + + size_t ParseBlocksRecursive(Function &func) override { return 0; } + + size_t ParseVariablesForContext(const SymbolContext &sc) override; + + uint32_t CalculateNumCompileUnits() override { return 0; } + + lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; + + lldb::TypeSP GetTypeForUID(lldb::user_id_t type_uid); + void AddTypeForUID(lldb::user_id_t type_uid, lldb::TypeSP type); + + Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + std::optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override { + return std::nullopt; + } + + bool CompleteType(CompilerType &compiler_type) override { return false; } + + uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContext &sc) override; + + void AddSymbols(Symtab &symtab) override; + + void GetTypes(lldb_private::SymbolContextScope *sc_scope, + lldb::TypeClass type_mask, + lldb_private::TypeList &type_list) 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 FindTypesByRegex(const lldb_private::RegularExpression ®ex, + uint32_t max_matches, lldb_private::TypeMap &types); + + void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + 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 + 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; + + enum TypeKind : uint32_t { + eUnknown = 0, + eInteger = 1, + eFloat = 2, + ePointer = 3, + eArray = 4, + eFunction = 5, + eStruct = 6, + eUnion = 7, + eEnum = 8, + eForward = 9, + eTypedef = 10, + eVolatile = 11, + eConst = 12, + eRestrict = 13, + eSlice = 14, + }; + +private: + enum Flags : uint32_t { + eFlagCompress = (1u << 0), + eFlagNewFuncInfo = (1u << 1), + eFlagIdxSorted = (1u << 2), + eFlagDynStr = (1u << 3), + }; + + enum IntEncoding : uint32_t { + eSigned = 0x1, + eChar = 0x2, + eBool = 0x4, + eVarArgs = 0x8, + }; + + struct ctf_preamble_t { + uint16_t magic; + uint8_t version; + uint8_t flags; + }; + + struct ctf_header_t { + ctf_preamble_t preamble; + uint32_t parlabel; + uint32_t parname; + uint32_t lbloff; + uint32_t objtoff; + uint32_t funcoff; + uint32_t typeoff; + uint32_t stroff; + uint32_t strlen; + }; + + struct ctf_type_t { + uint32_t name; + uint32_t info; + union { + uint32_t size; + uint32_t type; + }; + uint32_t lsizehi; + uint32_t lsizelo; + }; + + struct ctf_stype_t { + uint32_t name; + uint32_t info; + union { + uint32_t size; + uint32_t type; + }; + + bool IsLargeType() const { return size == 0xffff; } + uint32_t GetStructSize() const { + if (IsLargeType()) + return sizeof(ctf_type_t); + return sizeof(ctf_stype_t); + } + uint32_t GetType() const { return type; } + uint32_t GetSize() const { return size; } + }; + + struct ctf_member_t { + uint32_t name; + uint32_t type; + uint16_t offset; + uint16_t padding; + }; + + struct ctf_array_t { + uint32_t contents; + uint32_t index; + uint32_t nelems; + }; + + struct ctf_enum_t { + uint32_t name; + int32_t value; + }; + + llvm::Expected<lldb::TypeSP> ParseType(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name, uint32_t kind, + uint32_t variable_length, + uint32_t type, uint32_t size); + + llvm::Expected<lldb::TypeSP> ParseInteger(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name); + + llvm::Expected<lldb::TypeSP> ParseModifierType(lldb::offset_t &offset, + lldb::user_id_t uid, + uint32_t kind, uint32_t type); + + llvm::Expected<lldb::TypeSP> ParseTypedef(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name, + uint32_t type); + + llvm::Expected<lldb::TypeSP> + ParseArray(lldb::offset_t &offset, lldb::user_id_t uid, llvm::StringRef name); + + llvm::Expected<lldb::TypeSP> ParseEnum(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name, + uint32_t elements, uint32_t size); + + llvm::Expected<lldb::TypeSP> ParseFunction(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name, + uint32_t num_args, uint32_t type); + + llvm::Expected<lldb::TypeSP> ParseRecord(lldb::offset_t &offset, + lldb::user_id_t uid, + llvm::StringRef name, uint32_t kind, + uint32_t fields, uint32_t size); + + llvm::StringRef ReadString(lldb::offset_t offset) const; + + std::vector<uint16_t> GetFieldSizes(lldb::offset_t field_offset, + uint32_t fields, uint32_t struct_size); + + DataExtractor m_data; + + /// The start offset of the CTF body into m_data. If the body is uncompressed, + /// m_data contains the header and the body and the body starts after the + /// header. If the body is compressed, m_data only contains the body and the + /// offset is zero. + lldb::offset_t m_body_offset = 0; + + TypeSystemClang *m_ast; + lldb::CompUnitSP m_comp_unit_sp; + + std::optional<ctf_header_t> m_header; + std::vector<lldb::TypeSP> m_types; + std::vector<lldb::FunctionSP> m_functions; + std::vector<lldb::VariableSP> m_variables; + + static constexpr uint16_t g_ctf_magic = 0xcff1; + static constexpr uint8_t g_ctf_version = 4; +}; +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_CTF_SYMBOLFILECTF_H 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 f6a49ba6141a..34fb98b5a9b6 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -13,6 +13,7 @@ #include "lldb/Core/Module.h" #include "lldb/Symbol/Function.h" +#include "llvm/Support/DJB.h" using namespace lldb_private; using namespace lldb; @@ -22,26 +23,33 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create( Module &module, DWARFDataExtractor apple_names, DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types, DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str) { - auto apple_names_table_up = std::make_unique<DWARFMappedHash::MemoryTable>( - apple_names, debug_str, ".apple_names"); - if (!apple_names_table_up->IsValid()) - apple_names_table_up.reset(); + + llvm::DataExtractor llvm_debug_str = debug_str.GetAsLLVM(); + + auto apple_names_table_up = std::make_unique<llvm::AppleAcceleratorTable>( + apple_names.GetAsLLVMDWARF(), llvm_debug_str); auto apple_namespaces_table_up = - std::make_unique<DWARFMappedHash::MemoryTable>( - apple_namespaces, debug_str, ".apple_namespaces"); - if (!apple_namespaces_table_up->IsValid()) - apple_namespaces_table_up.reset(); + std::make_unique<llvm::AppleAcceleratorTable>( + apple_namespaces.GetAsLLVMDWARF(), llvm_debug_str); + + auto apple_types_table_up = std::make_unique<llvm::AppleAcceleratorTable>( + apple_types.GetAsLLVMDWARF(), llvm_debug_str); - auto apple_types_table_up = std::make_unique<DWARFMappedHash::MemoryTable>( - apple_types, debug_str, ".apple_types"); - if (!apple_types_table_up->IsValid()) - apple_types_table_up.reset(); + auto apple_objc_table_up = std::make_unique<llvm::AppleAcceleratorTable>( + apple_objc.GetAsLLVMDWARF(), llvm_debug_str); - auto apple_objc_table_up = std::make_unique<DWARFMappedHash::MemoryTable>( - apple_objc, debug_str, ".apple_objc"); - if (!apple_objc_table_up->IsValid()) - apple_objc_table_up.reset(); + auto extract_and_check = [](auto &TablePtr) { + if (auto E = TablePtr->extract()) { + llvm::consumeError(std::move(E)); + TablePtr.reset(); + } + }; + + extract_and_check(apple_names_table_up); + extract_and_check(apple_namespaces_table_up); + extract_and_check(apple_types_table_up); + extract_and_check(apple_objc_table_up); if (apple_names_table_up || apple_namespaces_table_up || apple_types_table_up || apple_objc_table_up) @@ -53,13 +61,76 @@ std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create( return nullptr; } +/// Returns true if `tag` is a class_type of structure_type tag. +static bool IsClassOrStruct(dw_tag_t tag) { + return tag == DW_TAG_class_type || tag == DW_TAG_structure_type; +} + +/// Returns true if `entry` has an extractable DW_ATOM_qual_name_hash and it +/// matches `expected_hash`. +static bool +EntryHasMatchingQualhash(const llvm::AppleAcceleratorTable::Entry &entry, + uint32_t expected_hash) { + std::optional<llvm::DWARFFormValue> form_value = + entry.lookup(dwarf::DW_ATOM_qual_name_hash); + if (!form_value) + return false; + std::optional<uint64_t> hash = form_value->getAsUnsignedConstant(); + return hash && (*hash == expected_hash); +} + +/// Returns true if `entry` has an extractable DW_ATOM_die_tag and it matches +/// `expected_tag`. We also consider it a match if the tags are different but +/// in the set of {TAG_class_type, TAG_struct_type}. +static bool EntryHasMatchingTag(const llvm::AppleAcceleratorTable::Entry &entry, + dw_tag_t expected_tag) { + std::optional<llvm::DWARFFormValue> form_value = + entry.lookup(dwarf::DW_ATOM_die_tag); + if (!form_value) + return false; + std::optional<uint64_t> maybe_tag = form_value->getAsUnsignedConstant(); + if (!maybe_tag) + return false; + auto tag = static_cast<dw_tag_t>(*maybe_tag); + return tag == expected_tag || + (IsClassOrStruct(tag) && IsClassOrStruct(expected_tag)); +} + +/// Returns true if `entry` has an extractable DW_ATOM_type_flags and the flag +/// "DW_FLAG_type_implementation" is set. +static bool +HasImplementationFlag(const llvm::AppleAcceleratorTable::Entry &entry) { + std::optional<llvm::DWARFFormValue> form_value = + entry.lookup(dwarf::DW_ATOM_type_flags); + if (!form_value) + return false; + std::optional<uint64_t> Flags = form_value->getAsUnsignedConstant(); + return Flags && + (*Flags & llvm::dwarf::AcceleratorTable::DW_FLAG_type_implementation); +} + +void AppleDWARFIndex::SearchFor(const llvm::AppleAcceleratorTable &table, + llvm::StringRef name, + llvm::function_ref<bool(DWARFDIE die)> callback, + std::optional<dw_tag_t> search_for_tag, + std::optional<uint32_t> search_for_qualhash) { + auto converted_cb = DIERefCallback(callback, name); + for (const auto &entry : table.equal_range(name)) { + if (search_for_qualhash && + !EntryHasMatchingQualhash(entry, *search_for_qualhash)) + continue; + if (search_for_tag && !EntryHasMatchingTag(entry, *search_for_tag)) + continue; + if (!converted_cb(entry)) + break; + } +} + void AppleDWARFIndex::GetGlobalVariables( ConstString basename, llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_names_up) return; - m_apple_names_up->FindByName( - basename.GetStringRef(), - DIERefCallback(callback, basename.GetStringRef())); + SearchFor(*m_apple_names_up, basename, callback); } void AppleDWARFIndex::GetGlobalVariables( @@ -68,11 +139,13 @@ void AppleDWARFIndex::GetGlobalVariables( if (!m_apple_names_up) return; - DWARFMappedHash::DIEInfoArray hash_data; - m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data); - // This is not really the DIE name. - DWARFMappedHash::ExtractDIEArray(hash_data, - DIERefCallback(callback, regex.GetText())); + DIERefCallbackImpl converted_cb = DIERefCallback(callback, regex.GetText()); + + for (const auto &entry : m_apple_names_up->entries()) + if (std::optional<llvm::StringRef> name = entry.readName(); + name && Mangled(*name).NameMatches(regex)) + if (!converted_cb(entry.BaseEntry)) + return; } void AppleDWARFIndex::GetGlobalVariables( @@ -80,22 +153,26 @@ void AppleDWARFIndex::GetGlobalVariables( if (!m_apple_names_up) return; - lldbassert(!cu.GetSymbolFileDWARF().GetDwoNum()); const DWARFUnit &non_skeleton_cu = cu.GetNonSkeletonUnit(); - DWARFMappedHash::DIEInfoArray hash_data; - m_apple_names_up->AppendAllDIEsInRange(non_skeleton_cu.GetOffset(), - non_skeleton_cu.GetNextUnitOffset(), - hash_data); - DWARFMappedHash::ExtractDIEArray(hash_data, DIERefCallback(callback)); + dw_offset_t lower_bound = non_skeleton_cu.GetOffset(); + dw_offset_t upper_bound = non_skeleton_cu.GetNextUnitOffset(); + auto is_in_range = [lower_bound, upper_bound](std::optional<uint32_t> val) { + return val.has_value() && *val >= lower_bound && *val < upper_bound; + }; + + DIERefCallbackImpl converted_cb = DIERefCallback(callback); + for (auto entry : m_apple_names_up->entries()) { + if (is_in_range(entry.BaseEntry.getDIESectionOffset())) + if (!converted_cb(entry.BaseEntry)) + return; + } } void AppleDWARFIndex::GetObjCMethods( ConstString class_name, llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_objc_up) return; - m_apple_objc_up->FindByName( - class_name.GetStringRef(), - DIERefCallback(callback, class_name.GetStringRef())); + SearchFor(*m_apple_objc_up, class_name, callback); } void AppleDWARFIndex::GetCompleteObjCClass( @@ -103,18 +180,32 @@ void AppleDWARFIndex::GetCompleteObjCClass( llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_types_up) return; - m_apple_types_up->FindCompleteObjCClassByName( - class_name.GetStringRef(), - DIERefCallback(callback, class_name.GetStringRef()), - must_be_implementation); + + llvm::SmallVector<DIERef> decl_dies; + auto converted_cb = DIERefCallback(callback, class_name); + + for (const auto &entry : m_apple_types_up->equal_range(class_name)) { + if (HasImplementationFlag(entry)) { + converted_cb(entry); + return; + } + + decl_dies.emplace_back(std::nullopt, DIERef::Section::DebugInfo, + *entry.getDIESectionOffset()); + } + + if (must_be_implementation) + return; + for (DIERef ref : decl_dies) + if (!converted_cb(ref)) + return; } void AppleDWARFIndex::GetTypes( ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_types_up) return; - m_apple_types_up->FindByName(name.GetStringRef(), - DIERefCallback(callback, name.GetStringRef())); + SearchFor(*m_apple_types_up, name, callback); } void AppleDWARFIndex::GetTypes( @@ -124,82 +215,77 @@ void AppleDWARFIndex::GetTypes( return; Log *log = GetLog(DWARFLog::TypeCompletion | DWARFLog::Lookups); - const bool has_tag = m_apple_types_up->GetHeader().header_data.ContainsAtom( - DWARFMappedHash::eAtomTypeTag); - const bool has_qualified_name_hash = - m_apple_types_up->GetHeader().header_data.ContainsAtom( - DWARFMappedHash::eAtomTypeQualNameHash); - - const ConstString type_name(context[0].name); - const dw_tag_t tag = context[0].tag; - if (has_tag && has_qualified_name_hash) { - const char *qualified_name = context.GetQualifiedName(); - const uint32_t qualified_name_hash = llvm::djbHash(qualified_name); + const bool entries_have_tag = + m_apple_types_up->containsAtomType(DW_ATOM_die_tag); + const bool entries_have_qual_hash = + m_apple_types_up->containsAtomType(DW_ATOM_qual_name_hash); + + llvm::StringRef expected_name = context[0].name; + + if (entries_have_tag && entries_have_qual_hash) { + const dw_tag_t expected_tag = context[0].tag; + const uint32_t expected_qualname_hash = + llvm::djbHash(context.GetQualifiedName()); if (log) m_module.LogMessage(log, "FindByNameAndTagAndQualifiedNameHash()"); - m_apple_types_up->FindByNameAndTagAndQualifiedNameHash( - type_name.GetStringRef(), tag, qualified_name_hash, - DIERefCallback(callback, type_name.GetStringRef())); + SearchFor(*m_apple_types_up, expected_name, callback, expected_tag, + expected_qualname_hash); return; } - if (has_tag) { - // When searching for a scoped type (for example, - // "std::vector<int>::const_iterator") searching for the innermost - // name alone ("const_iterator") could yield many false - // positives. By searching for the parent type ("vector<int>") - // first we can avoid extracting type DIEs from object files that - // would fail the filter anyway. - if (!has_qualified_name_hash && (context.GetSize() > 1) && - (context[1].tag == DW_TAG_class_type || - context[1].tag == DW_TAG_structure_type)) { - if (m_apple_types_up->FindByName(context[1].name, - [&](DIERef ref) { return false; })) - return; - } - - if (log) - m_module.LogMessage(log, "FindByNameAndTag()"); - m_apple_types_up->FindByNameAndTag( - type_name.GetStringRef(), tag, - DIERefCallback(callback, type_name.GetStringRef())); + // Historically, if there are no tags, we also ignore qual_hash (why?) + if (!entries_have_tag) { + SearchFor(*m_apple_names_up, expected_name, callback); return; } - m_apple_types_up->FindByName( - type_name.GetStringRef(), - DIERefCallback(callback, type_name.GetStringRef())); + // We have a tag but no qual hash. + + // When searching for a scoped type (for example, + // "std::vector<int>::const_iterator") searching for the innermost + // name alone ("const_iterator") could yield many false + // positives. By searching for the parent type ("vector<int>") + // first we can avoid extracting type DIEs from object files that + // would fail the filter anyway. + if ((context.GetSize() > 1) && IsClassOrStruct(context[1].tag)) + if (m_apple_types_up->equal_range(context[1].name).empty()) + return; + + if (log) + m_module.LogMessage(log, "FindByNameAndTag()"); + const dw_tag_t expected_tag = context[0].tag; + SearchFor(*m_apple_types_up, expected_name, callback, expected_tag); + return; } void AppleDWARFIndex::GetNamespaces( ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { if (!m_apple_namespaces_up) return; - m_apple_namespaces_up->FindByName( - name.GetStringRef(), DIERefCallback(callback, name.GetStringRef())); + SearchFor(*m_apple_namespaces_up, name, callback); } void AppleDWARFIndex::GetFunctions( const Module::LookupInfo &lookup_info, SymbolFileDWARF &dwarf, const CompilerDeclContext &parent_decl_ctx, llvm::function_ref<bool(DWARFDIE die)> callback) { + if (!m_apple_names_up) + return; + ConstString name = lookup_info.GetLookupName(); - m_apple_names_up->FindByName(name.GetStringRef(), [&](DIERef die_ref) { - return ProcessFunctionDIE(lookup_info, die_ref, dwarf, parent_decl_ctx, - callback); - }); + for (const auto &entry : m_apple_names_up->equal_range(name)) { + DIERef die_ref(std::nullopt, DIERef::Section::DebugInfo, + *entry.getDIESectionOffset()); + if (!ProcessFunctionDIE(lookup_info, die_ref, dwarf, parent_decl_ctx, + callback)) + return; + } } void AppleDWARFIndex::GetFunctions( const RegularExpression ®ex, llvm::function_ref<bool(DWARFDIE die)> callback) { - if (!m_apple_names_up) - return; - - DWARFMappedHash::DIEInfoArray hash_data; - m_apple_names_up->AppendAllDIEsThatMatchingRegex(regex, hash_data); - DWARFMappedHash::ExtractDIEArray(hash_data, - DIERefCallback(callback, regex.GetText())); + return GetGlobalVariables(regex, callback); } void AppleDWARFIndex::Dump(Stream &s) { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h index 3a5b8eef9cf4..6b948e079895 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.h @@ -10,7 +10,7 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_APPLEDWARFINDEX_H #include "Plugins/SymbolFile/DWARF/DWARFIndex.h" -#include "Plugins/SymbolFile/DWARF/HashedNameToDIE.h" +#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" namespace lldb_private { class AppleDWARFIndex : public DWARFIndex { @@ -20,11 +20,11 @@ public: DWARFDataExtractor apple_namespaces, DWARFDataExtractor apple_types, DWARFDataExtractor apple_objc, DWARFDataExtractor debug_str); - AppleDWARFIndex( - Module &module, std::unique_ptr<DWARFMappedHash::MemoryTable> apple_names, - std::unique_ptr<DWARFMappedHash::MemoryTable> apple_namespaces, - std::unique_ptr<DWARFMappedHash::MemoryTable> apple_types, - std::unique_ptr<DWARFMappedHash::MemoryTable> apple_objc) + AppleDWARFIndex(Module &module, + std::unique_ptr<llvm::AppleAcceleratorTable> apple_names, + std::unique_ptr<llvm::AppleAcceleratorTable> apple_namespaces, + std::unique_ptr<llvm::AppleAcceleratorTable> apple_types, + std::unique_ptr<llvm::AppleAcceleratorTable> apple_objc) : DWARFIndex(module), m_apple_names_up(std::move(apple_names)), m_apple_namespaces_up(std::move(apple_namespaces)), m_apple_types_up(std::move(apple_types)), @@ -62,10 +62,20 @@ public: void Dump(Stream &s) override; private: - std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_names_up; - std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_up; - std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_types_up; - std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_up; + std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_names_up; + std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_namespaces_up; + std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_types_up; + std::unique_ptr<llvm::AppleAcceleratorTable> m_apple_objc_up; + + /// Search for entries whose name is `name` in `table`, calling `callback` for + /// each match. If `search_for_tag` is provided, ignore entries whose tag is + /// not `search_for_tag`. If `search_for_qualhash` is provided, ignore entries + /// whose qualified name hash does not match `search_for_qualhash`. + /// If `callback` returns false for an entry, the search is interrupted. + void SearchFor(const llvm::AppleAcceleratorTable &table, llvm::StringRef name, + llvm::function_ref<bool(DWARFDIE die)> callback, + std::optional<dw_tag_t> search_for_tag = std::nullopt, + std::optional<uint32_t> search_for_qualhash = std::nullopt); }; } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp index 53e154fd651d..88a5e6027557 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp @@ -17,40 +17,22 @@ using namespace lldb_private; void llvm::format_provider<DIERef>::format(const DIERef &ref, raw_ostream &OS, StringRef Style) { - if (ref.dwo_num()) - OS << format_hex_no_prefix(*ref.dwo_num(), 8) << "/"; + if (ref.file_index()) + OS << format_hex_no_prefix(*ref.file_index(), 8) << "/"; OS << (ref.section() == DIERef::DebugInfo ? "INFO" : "TYPE"); OS << "/" << format_hex_no_prefix(ref.die_offset(), 8); } -constexpr uint32_t k_dwo_num_mask = 0x3FFFFFFF; -constexpr uint32_t k_dwo_num_valid_bitmask = (1u << 30); -constexpr uint32_t k_section_bitmask = (1u << 31); - std::optional<DIERef> DIERef::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr) { - const uint32_t bitfield_storage = data.GetU32(offset_ptr); - uint32_t dwo_num = bitfield_storage & k_dwo_num_mask; - bool dwo_num_valid = (bitfield_storage & (k_dwo_num_valid_bitmask)) != 0; - Section section = (Section)((bitfield_storage & (k_section_bitmask)) != 0); + DIERef die_ref(data.GetU64(offset_ptr)); + // DIE offsets can't be zero and if we fail to decode something from data, // it will return 0 - dw_offset_t die_offset = data.GetU32(offset_ptr); - if (die_offset == 0) + if (!die_ref.die_offset()) return std::nullopt; - if (dwo_num_valid) - return DIERef(dwo_num, section, die_offset); - else - return DIERef(std::nullopt, section, die_offset); -} -void DIERef::Encode(DataEncoder &encoder) const { - uint32_t bitfield_storage = m_dwo_num; - if (m_dwo_num_valid) - bitfield_storage |= k_dwo_num_valid_bitmask; - if (m_section) - bitfield_storage |= k_section_bitmask; - encoder.AppendU32(bitfield_storage); - static_assert(sizeof(m_die_offset) == 4, "m_die_offset must be 4 bytes"); - encoder.AppendU32(m_die_offset); + return die_ref; } + +void DIERef::Encode(DataEncoder &encoder) const { encoder.AppendU64(get_id()); } 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 af7e5e950840..b5a5cfe263f7 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -10,15 +10,17 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DIEREF_H #include "lldb/Core/dwarf.h" -#include "llvm/Support/FormatProviders.h" +#include "lldb/Utility/LLDBAssert.h" #include <cassert> #include <optional> -#include <vector> /// Identifies a DWARF debug info entry within a given Module. It contains three /// "coordinates": -/// - dwo_num: identifies the dwo file in the Module. If this field is not set, -/// the DIERef references the main file. +/// - file_index: identifies the separate stand alone debug info file +/// that is referred to by the main debug info file. This will be the +/// index of a DWO file for fission, or the .o file on mac when not +/// using a dSYM file. If this field is not set, then this references +/// a DIE inside the original object file. /// - section: identifies the section of the debug info entry in the given file: /// debug_info or debug_types. /// - die_offset: The offset of the debug info entry as an absolute offset from @@ -26,17 +28,35 @@ class DIERef { public: enum Section : uint8_t { DebugInfo, DebugTypes }; - - DIERef(std::optional<uint32_t> dwo_num, Section section, + DIERef(std::optional<uint32_t> file_index, Section section, dw_offset_t die_offset) - : 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?"); + : m_die_offset(die_offset), m_file_index(file_index.value_or(0)), + m_file_index_valid(file_index ? true : false), m_section(section) { + assert(this->file_index() == file_index && "File Index is out of range?"); + } + + explicit DIERef(lldb::user_id_t uid) { + m_die_offset = uid & k_die_offset_mask; + m_file_index_valid = (uid & k_file_index_valid_bit) != 0; + m_file_index = m_file_index_valid + ? (uid >> k_die_offset_bit_size) & k_file_index_mask + : 0; + m_section = + (uid & k_section_bit) != 0 ? Section::DebugTypes : Section::DebugInfo; + } + + lldb::user_id_t get_id() const { + if (m_die_offset == k_die_offset_mask) + return LLDB_INVALID_UID; + + return lldb::user_id_t(file_index().value_or(0)) << k_die_offset_bit_size | + die_offset() | (m_file_index_valid ? k_file_index_valid_bit : 0) | + (section() == Section::DebugTypes ? k_section_bit : 0); } - std::optional<uint32_t> dwo_num() const { - if (m_dwo_num_valid) - return m_dwo_num; + std::optional<uint32_t> file_index() const { + if (m_file_index_valid) + return m_file_index; return std::nullopt; } @@ -45,17 +65,17 @@ public: dw_offset_t die_offset() const { return m_die_offset; } bool operator<(DIERef other) const { - if (m_dwo_num_valid != other.m_dwo_num_valid) - return m_dwo_num_valid < other.m_dwo_num_valid; - if (m_dwo_num_valid && (m_dwo_num != other.m_dwo_num)) - return m_dwo_num < other.m_dwo_num; + if (m_file_index_valid != other.m_file_index_valid) + return m_file_index_valid < other.m_file_index_valid; + if (m_file_index_valid && (m_file_index != other.m_file_index)) + return m_file_index < other.m_file_index; if (m_section != other.m_section) return m_section < other.m_section; return m_die_offset < other.m_die_offset; } bool operator==(const DIERef &rhs) const { - return dwo_num() == rhs.dwo_num() && m_section == rhs.m_section && + return file_index() == rhs.file_index() && m_section == rhs.m_section && m_die_offset == rhs.m_die_offset; } @@ -85,11 +105,28 @@ public: /// void Encode(lldb_private::DataEncoder &encoder) const; + static constexpr uint64_t k_die_offset_bit_size = DW_DIE_OFFSET_MAX_BITSIZE; + static constexpr uint64_t k_file_index_bit_size = + 64 - DW_DIE_OFFSET_MAX_BITSIZE - /* size of control bits */ 2; + + static constexpr uint64_t k_file_index_valid_bit = + (1ull << (k_file_index_bit_size + k_die_offset_bit_size)); + static constexpr uint64_t k_section_bit = + (1ull << (k_file_index_bit_size + k_die_offset_bit_size + 1)); + static constexpr uint64_t + k_file_index_mask = (~0ull) >> (64 - k_file_index_bit_size); // 0x3fffff; + static constexpr uint64_t k_die_offset_mask = (~0ull) >> + (64 - k_die_offset_bit_size); + private: - uint32_t m_dwo_num : 30; - uint32_t m_dwo_num_valid : 1; - uint32_t m_section : 1; - dw_offset_t m_die_offset; + // Allow 2TB of .debug_info/.debug_types offset + dw_offset_t m_die_offset : k_die_offset_bit_size; + // Used for DWO index or for .o file index on mac + dw_offset_t m_file_index : k_file_index_bit_size; + // Set to 1 if m_file_index is a DWO number + dw_offset_t m_file_index_valid : 1; + // Set to 0 for .debug_info 1 for .debug_types, + dw_offset_t m_section : 1; }; static_assert(sizeof(DIERef) == 8); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp index dbece346b99a..a68b7cd110eb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp @@ -31,71 +31,70 @@ DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, 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; - } + DWARFAttributes attributes = die.GetAttributes(); + if (attributes.Size() == 0) + continue; + + uint64_t num_elements = 0; + uint64_t lower_bound = 0; + uint64_t upper_bound = 0; + bool upper_bound_valid = false; + for (size_t i = 0; i < attributes.Size(); ++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; - } - } - } + } + } else + num_elements = form_value.Unsigned(); + break; + + case DW_AT_bit_stride: + array_info.bit_stride = form_value.Unsigned(); + break; - if (num_elements == 0) { - if (upper_bound_valid && upper_bound >= lower_bound) - num_elements = upper_bound - lower_bound + 1; + 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; + } } + } - array_info.element_orders.push_back(num_elements); + 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; } 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 56bd089b86a1..a3ade51e1fe5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -266,20 +266,22 @@ static void PrepareContextToReceiveMembers(TypeSystemClang &ast, } ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) { - DWARFAttributes attributes; - size_t num_attributes = die.GetAttributes(attributes); - for (size_t i = 0; i < num_attributes; ++i) { + DWARFAttributes attributes = die.GetAttributes(); + for (size_t i = 0; i < attributes.Size(); ++i) { dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (!attributes.ExtractFormValueAtIndex(i, form_value)) continue; switch (attr) { + default: + break; case DW_AT_abstract_origin: abstract_origin = form_value; break; case DW_AT_accessibility: - accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); + accessibility = + DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_artificial: @@ -731,10 +733,10 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, } } - type_sp = dwarf->MakeType( - die.GetID(), attrs.name, attrs.byte_size, nullptr, - dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl, - clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die))); + type_sp = dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr, + attrs.type.Reference().GetID(), encoding_data_type, + &attrs.decl, clang_type, resolve_state, + TypePayloadClang(GetOwningClangModule(die))); dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); return type_sp; @@ -834,11 +836,11 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, LinkDeclContextToDIE(TypeSystemClang::GetDeclContextForType(clang_type), die); - type_sp = dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr, - dwarf->GetUID(attrs.type.Reference()), - Type::eEncodingIsUID, &attrs.decl, clang_type, - Type::ResolveState::Forward, - TypePayloadClang(GetOwningClangModule(die))); + type_sp = + dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr, + attrs.type.Reference().GetID(), Type::eEncodingIsUID, + &attrs.decl, clang_type, Type::ResolveState::Forward, + TypePayloadClang(GetOwningClangModule(die))); if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) { if (die.HasChildren()) { @@ -978,10 +980,11 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, if (attrs.name) { bool type_handled = false; if (tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine) { - ObjCLanguage::MethodName objc_method(attrs.name.GetStringRef(), true); - if (objc_method.IsValid(true)) { + std::optional<const ObjCLanguage::MethodName> objc_method = + ObjCLanguage::MethodName::Create(attrs.name.GetStringRef(), true); + if (objc_method) { CompilerType class_opaque_type; - ConstString class_name(objc_method.GetClassName()); + ConstString class_name(objc_method->GetClassName()); if (class_name) { TypeSP complete_objc_class_type_sp( dwarf->FindCompleteObjCDefinitionTypeForDIE(DWARFDIE(), @@ -1336,7 +1339,7 @@ DWARFASTParserClang::ParseArrayType(const DWARFDIE &die, ConstString empty_name; TypeSP type_sp = dwarf->MakeType(die.GetID(), empty_name, array_element_bit_stride / 8, - nullptr, dwarf->GetUID(type_die), Type::eEncodingIsUID, + nullptr, type_die.GetID(), Type::eEncodingIsUID, &attrs.decl, clang_type, Type::ResolveState::Full); type_sp->SetEncodingType(element_type); const clang::Type *type = ClangUtil::GetQualType(clang_type).getTypePtr(); @@ -1351,6 +1354,11 @@ TypeSP DWARFASTParserClang::ParsePointerToMemberType( Type *class_type = dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true); + // Check to make sure pointers are not NULL before attempting to + // dereference them. + if ((class_type == nullptr) || (pointee_type == nullptr)) + return nullptr; + CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType(); CompilerType class_clang_type = class_type->GetForwardCompilerType(); @@ -1378,9 +1386,8 @@ void DWARFASTParserClang::ParseInheritance( return; // TODO: implement DW_TAG_inheritance type parsing. - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes == 0) + DWARFAttributes attributes = die.GetAttributes(); + if (attributes.Size() == 0) return; DWARFFormValue encoding_form; @@ -1389,7 +1396,7 @@ void DWARFASTParserClang::ParseInheritance( bool is_base_of_class = true; off_t member_byte_offset = 0; - for (uint32_t i = 0; i < num_attributes; ++i) { + for (uint32_t i = 0; i < attributes.Size(); ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { @@ -1421,7 +1428,8 @@ void DWARFASTParserClang::ParseInheritance( break; case DW_AT_accessibility: - accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); + accessibility = + DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_virtuality: @@ -1980,14 +1988,14 @@ bool DWARFASTParserClang::ParseTemplateDIE( switch (tag) { case DW_TAG_GNU_template_parameter_pack: { - template_param_infos.packed_args = - std::make_unique<TypeSystemClang::TemplateParameterInfos>(); + template_param_infos.SetParameterPack( + std::make_unique<TypeSystemClang::TemplateParameterInfos>()); for (DWARFDIE child_die : die.children()) { - if (!ParseTemplateDIE(child_die, *template_param_infos.packed_args)) + if (!ParseTemplateDIE(child_die, template_param_infos.GetParameterPack())) return false; } if (const char *name = die.GetName()) { - template_param_infos.pack_name = name; + template_param_infos.SetPackName(name); } return true; } @@ -1996,80 +2004,86 @@ bool DWARFASTParserClang::ParseTemplateDIE( [[fallthrough]]; case DW_TAG_template_type_parameter: case DW_TAG_template_value_parameter: { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); + DWARFAttributes attributes = die.GetAttributes(); + if (attributes.Size() == 0) + return true; + const char *name = nullptr; const char *template_name = nullptr; CompilerType clang_type; uint64_t uval64 = 0; bool uval64_valid = false; - if (num_attributes > 0) { - DWARFFormValue form_value; - for (size_t i = 0; i < num_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); + bool is_default_template_arg = false; + DWARFFormValue form_value; + for (size_t i = 0; i < attributes.Size(); ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); - switch (attr) { - case DW_AT_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - name = form_value.AsCString(); - break; + switch (attr) { + case DW_AT_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + name = form_value.AsCString(); + break; - case DW_AT_GNU_template_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - template_name = form_value.AsCString(); - break; + case DW_AT_GNU_template_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + template_name = form_value.AsCString(); + break; - case DW_AT_type: - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - Type *lldb_type = die.ResolveTypeUID(form_value.Reference()); - if (lldb_type) - clang_type = lldb_type->GetForwardCompilerType(); - } - break; + case DW_AT_type: + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + Type *lldb_type = die.ResolveTypeUID(form_value.Reference()); + if (lldb_type) + clang_type = lldb_type->GetForwardCompilerType(); + } + break; - case DW_AT_const_value: - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - uval64_valid = true; - uval64 = form_value.Unsigned(); - } - break; - default: - break; + case DW_AT_const_value: + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + uval64_valid = true; + uval64 = form_value.Unsigned(); } + break; + case DW_AT_default_value: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + is_default_template_arg = form_value.Boolean(); + break; + default: + break; } + } - clang::ASTContext &ast = m_ast.getASTContext(); - if (!clang_type) - clang_type = m_ast.GetBasicType(eBasicTypeVoid); + clang::ASTContext &ast = m_ast.getASTContext(); + if (!clang_type) + clang_type = m_ast.GetBasicType(eBasicTypeVoid); - if (!is_template_template_argument) { - bool is_signed = false; - if (name && name[0]) - template_param_infos.names.push_back(name); - else - template_param_infos.names.push_back(nullptr); - - // Get the signed value for any integer or enumeration if available - clang_type.IsIntegerOrEnumerationType(is_signed); - - if (tag == DW_TAG_template_value_parameter && uval64_valid) { - std::optional<uint64_t> size = clang_type.GetBitSize(nullptr); - if (!size) - return false; - llvm::APInt apint(*size, uval64, is_signed); - template_param_infos.args.push_back( - clang::TemplateArgument(ast, llvm::APSInt(apint, !is_signed), - ClangUtil::GetQualType(clang_type))); - } else { - template_param_infos.args.push_back( - clang::TemplateArgument(ClangUtil::GetQualType(clang_type))); - } + if (!is_template_template_argument) { + bool is_signed = false; + // Get the signed value for any integer or enumeration if available + clang_type.IsIntegerOrEnumerationType(is_signed); + + if (name && !name[0]) + name = nullptr; + + if (tag == DW_TAG_template_value_parameter && uval64_valid) { + std::optional<uint64_t> size = clang_type.GetBitSize(nullptr); + if (!size) + return false; + llvm::APInt apint(*size, uval64, is_signed); + template_param_infos.InsertArg( + name, clang::TemplateArgument(ast, llvm::APSInt(apint, !is_signed), + ClangUtil::GetQualType(clang_type), + is_default_template_arg)); } else { - auto *tplt_type = m_ast.CreateTemplateTemplateParmDecl(template_name); - template_param_infos.names.push_back(name); - template_param_infos.args.push_back( - clang::TemplateArgument(clang::TemplateName(tplt_type))); + template_param_infos.InsertArg( + name, clang::TemplateArgument(ClangUtil::GetQualType(clang_type), + /*isNullPtr*/ false, + is_default_template_arg)); } + } else { + auto *tplt_type = m_ast.CreateTemplateTemplateParmDecl(template_name); + template_param_infos.InsertArg( + name, clang::TemplateArgument(clang::TemplateName(tplt_type), + is_default_template_arg)); } } return true; @@ -2102,10 +2116,9 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos( break; } } - return template_param_infos.args.size() == - template_param_infos.names.size() && - (!template_param_infos.args.empty() || - template_param_infos.packed_args); + + return !template_param_infos.IsEmpty() || + template_param_infos.hasParameterPack(); } bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, @@ -2230,7 +2243,6 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, const dw_tag_t tag = die.Tag(); assert(clang_type); - DWARFAttributes attributes; switch (tag) { case DW_TAG_structure_type: case DW_TAG_union_type: @@ -2291,58 +2303,58 @@ size_t DWARFASTParserClang::ParseChildEnumerators( for (DWARFDIE die : parent_die.children()) { const dw_tag_t tag = die.Tag(); - if (tag == DW_TAG_enumerator) { - DWARFAttributes attributes; - const size_t num_child_attributes = die.GetAttributes(attributes); - if (num_child_attributes > 0) { - const char *name = nullptr; - bool got_value = false; - int64_t enum_value = 0; - Declaration decl; - - 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_const_value: - got_value = true; - if (is_signed) - enum_value = form_value.Signed(); - else - enum_value = form_value.Unsigned(); - break; - - case DW_AT_name: - name = form_value.AsCString(); - break; - - case DW_AT_description: - default: - case DW_AT_decl_file: - decl.SetFile(attributes.CompileUnitAtIndex(i)->GetFile( - form_value.Unsigned())); - break; - case DW_AT_decl_line: - decl.SetLine(form_value.Unsigned()); - break; - case DW_AT_decl_column: - decl.SetColumn(form_value.Unsigned()); - break; - case DW_AT_sibling: - break; - } - } - } + if (tag != DW_TAG_enumerator) + continue; - if (name && name[0] && got_value) { - m_ast.AddEnumerationValueToEnumerationType( - clang_type, decl, name, enum_value, enumerator_byte_size * 8); - ++enumerators_added; + DWARFAttributes attributes = die.GetAttributes(); + if (attributes.Size() == 0) + continue; + + const char *name = nullptr; + bool got_value = false; + int64_t enum_value = 0; + Declaration decl; + + for (size_t i = 0; i < attributes.Size(); ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + switch (attr) { + case DW_AT_const_value: + got_value = true; + if (is_signed) + enum_value = form_value.Signed(); + else + enum_value = form_value.Unsigned(); + break; + + case DW_AT_name: + name = form_value.AsCString(); + break; + + case DW_AT_description: + default: + case DW_AT_decl_file: + decl.SetFile( + attributes.CompileUnitAtIndex(i)->GetFile(form_value.Unsigned())); + break; + case DW_AT_decl_line: + decl.SetLine(form_value.Unsigned()); + break; + case DW_AT_decl_column: + decl.SetColumn(form_value.Unsigned()); + break; + case DW_AT_sibling: + break; } } } + + if (name && name[0] && got_value) { + m_ast.AddEnumerationValueToEnumerationType( + clang_type, decl, name, enum_value, enumerator_byte_size * 8); + ++enumerators_added; + } } return enumerators_added; } @@ -2388,12 +2400,12 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, DWARFRangeList func_ranges; const char *name = nullptr; const char *mangled = nullptr; - int decl_file = 0; - int decl_line = 0; - int decl_column = 0; - int call_file = 0; - int call_line = 0; - int call_column = 0; + std::optional<int> decl_file; + std::optional<int> decl_line; + std::optional<int> decl_column; + std::optional<int> call_file; + std::optional<int> call_line; + std::optional<int> call_column; DWARFExpressionList frame_base; const dw_tag_t tag = die.Tag(); @@ -2406,7 +2418,7 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, &frame_base)) { Mangled func_name; if (mangled) - func_name.SetValue(ConstString(mangled), true); + func_name.SetValue(ConstString(mangled)); else if ((die.GetParent().Tag() == DW_TAG_compile_unit || die.GetParent().Tag() == DW_TAG_partial_unit) && Language::LanguageIsCPlusPlus( @@ -2417,15 +2429,16 @@ DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, // If the mangled name is not present in the DWARF, generate the // demangled name using the decl context. We skip if the function is // "main" as its name is never mangled. - func_name.SetValue(ConstructDemangledNameFromDWARF(die), false); + func_name.SetValue(ConstructDemangledNameFromDWARF(die)); } else - func_name.SetValue(ConstString(name), false); + func_name.SetValue(ConstString(name)); FunctionSP func_sp; std::unique_ptr<Declaration> decl_up; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file), - decl_line, decl_column); + if (decl_file || decl_line || decl_column) + decl_up = std::make_unique<Declaration>( + die.GetCU()->GetFile(decl_file ? *decl_file : 0), + decl_line ? *decl_line : 0, decl_column ? *decl_column : 0); SymbolFileDWARF *dwarf = die.GetDWARF(); // Supply the type _only_ if it has already been parsed @@ -2489,9 +2502,8 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die, ModuleSP module_sp) { member_byte_offset = (parent_die.Tag() == DW_TAG_union_type) ? 0 : UINT32_MAX; - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (std::size_t i = 0; i < num_attributes; ++i) { + DWARFAttributes attributes = die.GetAttributes(); + for (size_t i = 0; i < attributes.Size(); ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { @@ -2543,7 +2555,8 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die, break; case DW_AT_accessibility: - accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); + accessibility = + DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_artificial: is_artificial = form_value.Boolean(); @@ -2574,9 +2587,8 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die, PropertyAttributes::PropertyAttributes(const DWARFDIE &die) { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (size_t i = 0; i < num_attributes; ++i) { + DWARFAttributes attributes = die.GetAttributes(); + for (size_t i = 0; i < attributes.Size(); ++i) { const dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (attributes.ExtractFormValueAtIndex(i, form_value)) { @@ -2606,13 +2618,19 @@ PropertyAttributes::PropertyAttributes(const DWARFDIE &die) { // Check if the property getter/setter were provided as full names. // We want basenames, so we extract them. if (prop_getter_name && prop_getter_name[0] == '-') { - ObjCLanguage::MethodName prop_getter_method(prop_getter_name, true); - prop_getter_name = prop_getter_method.GetSelector().GetCString(); + std::optional<const ObjCLanguage::MethodName> prop_getter_method = + ObjCLanguage::MethodName::Create(prop_getter_name, true); + if (prop_getter_method) + prop_getter_name = + ConstString(prop_getter_method->GetSelector()).GetCString(); } if (prop_setter_name && prop_setter_name[0] == '-') { - ObjCLanguage::MethodName prop_setter_method(prop_setter_name, true); - prop_setter_name = prop_setter_method.GetSelector().GetCString(); + std::optional<const ObjCLanguage::MethodName> prop_setter_method = + ObjCLanguage::MethodName::Create(prop_setter_name, true); + if (prop_setter_method) + prop_setter_name = + ConstString(prop_setter_method->GetSelector()).GetCString(); } // If the names haven't been provided, they need to be filled in. @@ -2701,7 +2719,7 @@ llvm::Expected<llvm::APInt> DWARFASTParserClang::ExtractIntFromFormValue( // For signed types, ask APInt how many bits are required to represent the // signed integer. const unsigned required_bits = - is_unsigned ? result.getActiveBits() : result.getMinSignedBits(); + is_unsigned ? result.getActiveBits() : result.getSignificantBits(); // If the input value doesn't fit into the integer type, return an error. if (required_bits > type_bits) { @@ -2869,9 +2887,8 @@ void DWARFASTParserClang::ParseSingleMember( if (detect_unnamed_bitfields) { std::optional<FieldInfo> unnamed_field_info; - uint64_t last_field_end = 0; - - last_field_end = last_field_info.bit_offset + last_field_info.bit_size; + uint64_t last_field_end = + last_field_info.bit_offset + last_field_info.bit_size; if (!last_field_info.IsBitfield()) { // The last field was not a bit-field... @@ -2882,20 +2899,8 @@ void DWARFASTParserClang::ParseSingleMember( last_field_end += word_width - (last_field_end % word_width); } - // If we have a gap between the last_field_end and the current - // field we have an unnamed bit-field. - // If we have a base class, we assume there is no unnamed - // bit-field if this is the first field since the gap can be - // attributed to the members from the base class. This assumption - // is not correct if the first field of the derived class is - // indeed an unnamed bit-field. We currently do not have the - // machinary to track the offset of the last field of classes we - // have seen before, so we are not handling this case. - if (this_field_info.bit_offset != last_field_end && - this_field_info.bit_offset > last_field_end && - !(last_field_info.bit_offset == 0 && - last_field_info.bit_size == 0 && - layout_info.base_offsets.size() != 0)) { + if (ShouldCreateUnnamedBitfield(last_field_info, last_field_end, + this_field_info, layout_info)) { unnamed_field_info = FieldInfo{}; unnamed_field_info->bit_size = this_field_info.bit_offset - last_field_end; @@ -2936,8 +2941,10 @@ void DWARFASTParserClang::ParseSingleMember( // artificial member with (unnamed bitfield) padding. // FIXME: This check should verify that this is indeed an artificial member // we are supposed to ignore. - if (attrs.is_artificial) + if (attrs.is_artificial) { + last_field_info.SetIsArtificial(true); return; + } if (!member_clang_type.IsCompleteType()) member_clang_type.GetCompleteType(); @@ -3052,87 +3059,87 @@ size_t DWARFASTParserClang::ParseChildParameters( const dw_tag_t tag = die.Tag(); switch (tag) { case DW_TAG_formal_parameter: { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - const char *name = nullptr; - DWARFFormValue param_type_die_form; - bool is_artificial = false; - // one of None, Auto, Register, Extern, Static, PrivateExtern - - clang::StorageClass storage = clang::SC_None; - uint32_t i; - for (i = 0; i < num_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: - name = form_value.AsCString(); - break; - case DW_AT_type: - param_type_die_form = form_value; - break; - case DW_AT_artificial: - is_artificial = form_value.Boolean(); - break; - case DW_AT_location: - case DW_AT_const_value: - case DW_AT_default_value: - case DW_AT_description: - case DW_AT_endianity: - case DW_AT_is_optional: - case DW_AT_segment: - case DW_AT_variable_parameter: - default: - case DW_AT_abstract_origin: - case DW_AT_sibling: - break; - } + DWARFAttributes attributes = die.GetAttributes(); + if (attributes.Size() == 0) { + arg_idx++; + break; + } + + const char *name = nullptr; + DWARFFormValue param_type_die_form; + bool is_artificial = false; + // one of None, Auto, Register, Extern, Static, PrivateExtern + + clang::StorageClass storage = clang::SC_None; + uint32_t i; + for (i = 0; i < attributes.Size(); ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + switch (attr) { + case DW_AT_name: + name = form_value.AsCString(); + break; + case DW_AT_type: + param_type_die_form = form_value; + break; + case DW_AT_artificial: + is_artificial = form_value.Boolean(); + break; + case DW_AT_location: + case DW_AT_const_value: + case DW_AT_default_value: + case DW_AT_description: + case DW_AT_endianity: + case DW_AT_is_optional: + case DW_AT_segment: + case DW_AT_variable_parameter: + default: + case DW_AT_abstract_origin: + case DW_AT_sibling: + break; } } + } - bool skip = false; - if (skip_artificial && is_artificial) { - // In order to determine if a C++ member function is "const" we - // have to look at the const-ness of "this"... - if (arg_idx == 0 && - DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()) && - // Often times compilers omit the "this" name for the - // specification DIEs, so we can't rely upon the name being in - // the formal parameter DIE... - (name == nullptr || ::strcmp(name, "this") == 0)) { - Type *this_type = - die.ResolveTypeUID(param_type_die_form.Reference()); - if (this_type) { - uint32_t encoding_mask = this_type->GetEncodingMask(); - if (encoding_mask & Type::eEncodingIsPointerUID) { - is_static = false; - - if (encoding_mask & (1u << Type::eEncodingIsConstUID)) - type_quals |= clang::Qualifiers::Const; - if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) - type_quals |= clang::Qualifiers::Volatile; - } + bool skip = false; + if (skip_artificial && is_artificial) { + // In order to determine if a C++ member function is "const" we + // have to look at the const-ness of "this"... + if (arg_idx == 0 && + DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()) && + // Often times compilers omit the "this" name for the + // specification DIEs, so we can't rely upon the name being in + // the formal parameter DIE... + (name == nullptr || ::strcmp(name, "this") == 0)) { + Type *this_type = die.ResolveTypeUID(param_type_die_form.Reference()); + if (this_type) { + uint32_t encoding_mask = this_type->GetEncodingMask(); + if (encoding_mask & Type::eEncodingIsPointerUID) { + is_static = false; + + if (encoding_mask & (1u << Type::eEncodingIsConstUID)) + type_quals |= clang::Qualifiers::Const; + if (encoding_mask & (1u << Type::eEncodingIsVolatileUID)) + type_quals |= clang::Qualifiers::Volatile; } } - skip = true; } + skip = true; + } - if (!skip) { - Type *type = die.ResolveTypeUID(param_type_die_form.Reference()); - if (type) { - function_param_types.push_back(type->GetForwardCompilerType()); + if (!skip) { + Type *type = die.ResolveTypeUID(param_type_die_form.Reference()); + if (type) { + function_param_types.push_back(type->GetForwardCompilerType()); - clang::ParmVarDecl *param_var_decl = - m_ast.CreateParameterDeclaration( - containing_decl_ctx, GetOwningClangModule(die), name, - type->GetForwardCompilerType(), storage); - assert(param_var_decl); - function_param_decls.push_back(param_var_decl); + clang::ParmVarDecl *param_var_decl = m_ast.CreateParameterDeclaration( + containing_decl_ctx, GetOwningClangModule(die), name, + type->GetForwardCompilerType(), storage); + assert(param_var_decl); + function_param_decls.push_back(param_var_decl); - m_ast.SetMetadataAsUserID(param_var_decl, die.GetID()); - } + m_ast.SetMetadataAsUserID(param_var_decl, die.GetID()); } } arg_idx++; @@ -3161,21 +3168,24 @@ size_t DWARFASTParserClang::ParseChildParameters( } Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) { - if (die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - DWARFFormValue type_die_form; - for (size_t i = 0; i < num_attributes; ++i) { - dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; + if (!die) + return nullptr; - if (attr == DW_AT_type && - attributes.ExtractFormValueAtIndex(i, form_value)) - return dwarf->ResolveTypeUID(form_value.Reference(), true); - } - } + SymbolFileDWARF *dwarf = die.GetDWARF(); + if (!dwarf) + return nullptr; + + DWARFAttributes attributes = die.GetAttributes(); + if (attributes.Size() == 0) + return nullptr; + + DWARFFormValue type_die_form; + for (size_t i = 0; i < attributes.Size(); ++i) { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + + if (attr == DW_AT_type && attributes.ExtractFormValueAtIndex(i, form_value)) + return dwarf->ResolveTypeUID(form_value.Reference(), true); } return nullptr; @@ -3298,6 +3308,11 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) { try_parsing_type = false; break; + case DW_TAG_imported_declaration: + decl_ctx = ResolveImportedDeclarationDIE(die); + try_parsing_type = false; + break; + case DW_TAG_lexical_block: decl_ctx = GetDeclContextForBlock(die); try_parsing_type = false; @@ -3459,6 +3474,42 @@ DWARFASTParserClang::ResolveNamespaceDIE(const DWARFDIE &die) { return nullptr; } +clang::NamespaceDecl * +DWARFASTParserClang::ResolveImportedDeclarationDIE(const DWARFDIE &die) { + assert(die && die.Tag() == DW_TAG_imported_declaration); + + // See if we cached a NamespaceDecl for this imported declaration + // already + auto it = m_die_to_decl_ctx.find(die.GetDIE()); + if (it != m_die_to_decl_ctx.end()) + return static_cast<clang::NamespaceDecl *>(it->getSecond()); + + clang::NamespaceDecl *namespace_decl = nullptr; + + const DWARFDIE imported_uid = + die.GetAttributeValueAsReferenceDIE(DW_AT_import); + if (!imported_uid) + return nullptr; + + switch (imported_uid.Tag()) { + case DW_TAG_imported_declaration: + namespace_decl = ResolveImportedDeclarationDIE(imported_uid); + break; + case DW_TAG_namespace: + namespace_decl = ResolveNamespaceDIE(imported_uid); + break; + default: + return nullptr; + } + + if (!namespace_decl) + return nullptr; + + LinkDeclContextToDIE(namespace_decl, die); + + return namespace_decl; +} + clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE( const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) { SymbolFileDWARF *dwarf = die.GetDWARF(); @@ -3646,3 +3697,35 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( return !failures.empty(); } + +bool DWARFASTParserClang::ShouldCreateUnnamedBitfield( + FieldInfo const &last_field_info, uint64_t last_field_end, + FieldInfo const &this_field_info, + lldb_private::ClangASTImporter::LayoutInfo const &layout_info) const { + // If we have a gap between the last_field_end and the current + // field we have an unnamed bit-field. + if (this_field_info.bit_offset <= last_field_end) + return false; + + // If we have a base class, we assume there is no unnamed + // bit-field if either of the following is true: + // (a) this is the first field since the gap can be + // attributed to the members from the base class. + // FIXME: This assumption is not correct if the first field of + // the derived class is indeed an unnamed bit-field. We currently + // do not have the machinary to track the offset of the last field + // of classes we have seen before, so we are not handling this case. + // (b) Or, the first member of the derived class was a vtable pointer. + // In this case we don't want to create an unnamed bitfield either + // since those will be inserted by clang later. + const bool have_base = layout_info.base_offsets.size() != 0; + const bool this_is_first_field = + last_field_info.bit_offset == 0 && last_field_info.bit_size == 0; + const bool first_field_is_vptr = + last_field_info.bit_offset == 0 && last_field_info.IsArtificial(); + + if (have_base && (this_is_first_field || first_field_is_vptr)) + return false; + + return true; +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 0733d22a0069..042075b7df5f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -132,6 +132,17 @@ protected: clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die); + /// Returns the namespace decl that a DW_TAG_imported_declaration imports. + /// + /// \param[in] die The import declaration to resolve. If the DIE is not a + /// DW_TAG_imported_declaration the behaviour is undefined. + /// + /// \returns The decl corresponding to the namespace that the specified + /// 'die' imports. If the imported entity is not a namespace + /// or another import declaration, returns nullptr. If an error + /// occurs, returns nullptr. + clang::NamespaceDecl *ResolveImportedDeclarationDIE(const DWARFDIE &die); + bool ParseTemplateDIE(const DWARFDIE &die, lldb_private::TypeSystemClang::TemplateParameterInfos &template_param_infos); @@ -212,12 +223,16 @@ private: uint64_t bit_size = 0; uint64_t bit_offset = 0; bool is_bitfield = false; + bool is_artificial = false; FieldInfo() = default; void SetIsBitfield(bool flag) { is_bitfield = flag; } bool IsBitfield() { return is_bitfield; } + void SetIsArtificial(bool flag) { is_artificial = flag; } + bool IsArtificial() const { return is_artificial; } + bool NextBitfieldOffsetIsValid(const uint64_t next_bit_offset) const { // Any subsequent bitfields must not overlap and must be at a higher // bit offset than any previous bitfield + size. @@ -225,6 +240,22 @@ private: } }; + /// Returns 'true' if we should create an unnamed bitfield + /// and add it to the parser's current AST. + /// + /// \param[in] last_field_info FieldInfo of the previous DW_TAG_member + /// we parsed. + /// \param[in] last_field_end Offset (in bits) where the last parsed field + /// ended. + /// \param[in] this_field_info FieldInfo of the current DW_TAG_member + /// being parsed. + /// \param[in] layout_info Layout information of all decls parsed by the + /// current parser. + bool ShouldCreateUnnamedBitfield( + FieldInfo const &last_field_info, uint64_t last_field_end, + FieldInfo const &this_field_info, + lldb_private::ClangASTImporter::LayoutInfo const &layout_info) const; + /// Parses a DW_TAG_APPLE_property DIE and appends the parsed data to the /// list of delayed Objective-C properties. /// diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp deleted file mode 100644 index 62d75c69afa8..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ /dev/null @@ -1,82 +0,0 @@ -//===-- DWARFAbbreviationDeclaration.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 "DWARFAbbreviationDeclaration.h" - -#include "lldb/Core/dwarf.h" -#include "lldb/Utility/Stream.h" - -#include "llvm/Object/Error.h" - -#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_tag(tag), m_has_children(has_children), m_attributes() {} - -llvm::Expected<DWARFEnumState> -DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data, - lldb::offset_t *offset_ptr) { - m_code = data.GetULEB128(offset_ptr); - if (m_code == 0) - return DWARFEnumState::Complete; - - m_attributes.clear(); - m_tag = static_cast<dw_tag_t>(data.GetULEB128(offset_ptr)); - if (m_tag == DW_TAG_null) - return llvm::make_error<llvm::object::GenericBinaryError>( - "abbrev decl requires non-null tag."); - - m_has_children = data.GetU8(offset_ptr); - - while (data.ValidOffset(*offset_ptr)) { - dw_attr_t attr = data.GetULEB128(offset_ptr); - dw_form_t form = data.GetULEB128(offset_ptr); - - // This is the last attribute for this abbrev decl, but there may still be - // more abbrev decls, so return MoreItems to indicate to the caller that - // they should call this function again. - if (!attr && !form) - return DWARFEnumState::MoreItems; - - if (!attr || !form) - return llvm::make_error<llvm::object::GenericBinaryError>( - "malformed abbreviation declaration attribute"); - - DWARFFormValue::ValueType val; - - if (form == DW_FORM_implicit_const) - val.value.sval = data.GetSLEB128(offset_ptr); - - m_attributes.push_back(DWARFAttribute(attr, form, val)); - } - - return llvm::make_error<llvm::object::GenericBinaryError>( - "abbreviation declaration attribute list not terminated with a null " - "entry"); -} - -bool DWARFAbbreviationDeclaration::IsValid() { - return m_code != 0 && m_tag != llvm::dwarf::DW_TAG_null; -} - -uint32_t -DWARFAbbreviationDeclaration::FindAttributeIndex(dw_attr_t attr) const { - uint32_t i; - const uint32_t kNumAttributes = m_attributes.size(); - for (i = 0; i < kNumAttributes; ++i) { - if (m_attributes[i].get_attr() == attr) - return i; - } - return DW_INVALID_INDEX; -} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h deleted file mode 100644 index 378ba888f4e0..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h +++ /dev/null @@ -1,64 +0,0 @@ -//===-- DWARFAbbreviationDeclaration.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_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H -#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H - -#include "DWARFAttribute.h" -#include "DWARFDefines.h" -#include "SymbolFileDWARF.h" -#include "llvm/Support/Error.h" - -class DWARFAbbreviationDeclaration { -public: - enum { InvalidCode = 0 }; - DWARFAbbreviationDeclaration(); - - // For hand crafting an abbreviation declaration - DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children); - - dw_uleb128_t Code() const { return m_code; } - void SetCode(dw_uleb128_t code) { m_code = code; } - dw_tag_t Tag() const { return m_tag; } - bool HasChildren() const { return m_has_children; } - size_t NumAttributes() const { return m_attributes.size(); } - dw_form_t GetFormByIndex(uint32_t idx) const { - return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0; - } - - // idx is assumed to be valid when calling GetAttrAndFormByIndex() - void GetAttrAndFormValueByIndex(uint32_t idx, dw_attr_t &attr, - DWARFFormValue &form_value) const { - m_attributes[idx].get(attr, form_value.FormRef(), form_value.ValueRef()); - } - dw_form_t GetFormByIndexUnchecked(uint32_t idx) const { - return m_attributes[idx].get_form(); - } - uint32_t FindAttributeIndex(dw_attr_t attr) const; - - /// Extract one abbreviation declaration and all of its associated attributes. - /// Possible return values: - /// DWARFEnumState::Complete - the extraction completed successfully. This - /// was the last abbrev decl in a sequence, and the user should not call - /// this function again. - /// DWARFEnumState::MoreItems - the extraction completed successfully. The - /// user should call this function again to retrieve the next decl. - /// llvm::Error - A parsing error occurred. The debug info is malformed. - llvm::Expected<lldb_private::DWARFEnumState> - extract(const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr); - bool IsValid(); - -protected: - dw_uleb128_t m_code = InvalidCode; - dw_tag_t m_tag = llvm::dwarf::DW_TAG_null; - uint8_t m_has_children = 0; - DWARFAttribute::collection m_attributes; -}; - -#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFABBREVIATIONDECLARATION_H diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h index a31ee861179c..90e12fa02493 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -31,10 +31,6 @@ public: form = m_form; val = m_value; } - typedef std::vector<DWARFAttribute> collection; - typedef collection::iterator iterator; - typedef collection::const_iterator const_iterator; - protected: dw_attr_t m_attr; dw_form_t m_form; @@ -55,7 +51,7 @@ public: dw_attr_t AttributeAtIndex(uint32_t i) const { return m_infos[i].attr.get_attr(); } - dw_attr_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); } + dw_form_t FormAtIndex(uint32_t i) const { return m_infos[i].attr.get_form(); } DWARFFormValue::ValueType ValueAtIndex(uint32_t i) const { return m_infos[i].attr.get_value(); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp index e631f99f09a0..37a917c3a766 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp @@ -23,8 +23,8 @@ std::optional<DIERef> DWARFBaseDIE::GetDIERef() const { if (!IsValid()) return std::nullopt; - return DIERef(m_cu->GetSymbolFileDWARF().GetDwoNum(), m_cu->GetDebugSection(), - m_die->GetOffset()); + return DIERef(m_cu->GetSymbolFileDWARF().GetFileIndex(), + m_cu->GetDebugSection(), m_die->GetOffset()); } dw_tag_t DWARFBaseDIE::Tag() const { @@ -70,8 +70,10 @@ uint64_t DWARFBaseDIE::GetAttributeValueAsAddress(const dw_attr_t attr, } lldb::user_id_t DWARFBaseDIE::GetID() const { - if (IsValid()) - return GetDWARF()->GetUID(*this); + const std::optional<DIERef> &ref = this->GetDIERef(); + if (ref) + return ref->get_id(); + return LLDB_INVALID_UID; } @@ -112,12 +114,10 @@ bool DWARFBaseDIE::Supports_DW_AT_APPLE_objc_complete_type() const { return IsValid() && GetDWARF()->Supports_DW_AT_APPLE_objc_complete_type(m_cu); } -size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes, - Recurse recurse) const { +DWARFAttributes DWARFBaseDIE::GetAttributes(Recurse recurse) const { if (IsValid()) - return m_die->GetAttributes(m_cu, attributes, recurse); - attributes.Clear(); - return 0; + return m_die->GetAttributes(m_cu, recurse); + return DWARFAttributes(); } bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h index 51145ab0c4dc..8bcf807ad163 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h @@ -115,8 +115,7 @@ public: uint64_t fail_value) const; enum class Recurse : bool { no, yes }; - size_t GetAttributes(DWARFAttributes &attributes, - Recurse recurse = Recurse::yes) const; + DWARFAttributes GetAttributes(Recurse recurse = Recurse::yes) const; protected: DWARFUnit *m_cu = nullptr; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index dbe86c6ccb9c..f839a59bf6c3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -40,18 +40,14 @@ void DWARFCompileUnit::BuildAddressRangeTable( const dw_offset_t cu_offset = GetOffset(); if (die) { - DWARFRangeList ranges; - const size_t num_ranges = - die->GetAttributeAddressRanges(this, ranges, /*check_hi_lo_pc=*/true); - if (num_ranges > 0) { - for (size_t i = 0; i < num_ranges; ++i) { - const DWARFRangeList::Entry &range = ranges.GetEntryRef(i); - debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), - range.GetRangeEnd()); - } + DWARFRangeList ranges = + die->GetAttributeAddressRanges(this, /*check_hi_lo_pc=*/true); + for (const DWARFRangeList::Entry &range : ranges) + debug_aranges->AppendRange(cu_offset, range.GetRangeBase(), + range.GetRangeEnd()); + if (!ranges.IsEmpty()) return; - } } if (debug_aranges->GetNumRanges() == num_debug_aranges) { 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 7b9da6fa166f..b31c5dcac918 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -168,10 +168,9 @@ DWARFDIE::LookupDeepestBlock(lldb::addr_t address) const { } if (match_addr_range) { - DWARFRangeList ranges; - if (m_die->GetAttributeAddressRanges(m_cu, ranges, - /*check_hi_lo_pc=*/true) && - ranges.FindEntryThatContains(address)) { + DWARFRangeList ranges = + m_die->GetAttributeAddressRanges(m_cu, /*check_hi_lo_pc=*/true); + if (ranges.FindEntryThatContains(address)) { check_children = true; switch (Tag()) { default: @@ -439,8 +438,9 @@ bool DWARFDIE::IsMethod() const { bool DWARFDIE::GetDIENamesAndRanges( const char *&name, const char *&mangled, DWARFRangeList &ranges, - int &decl_file, int &decl_line, int &decl_column, int &call_file, - int &call_line, int &call_column, + std::optional<int> &decl_file, std::optional<int> &decl_line, + std::optional<int> &decl_column, std::optional<int> &call_file, + std::optional<int> &call_line, std::optional<int> &call_column, lldb_private::DWARFExpressionList *frame_base) const { if (IsValid()) { return m_die->GetDIENamesAndRanges( diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index 3564f757dbd8..031ea26ad405 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -83,12 +83,12 @@ public: DWARFDIE GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const; - bool - GetDIENamesAndRanges(const char *&name, const char *&mangled, - DWARFRangeList &ranges, int &decl_file, int &decl_line, - int &decl_column, int &call_file, int &call_line, - int &call_column, - lldb_private::DWARFExpressionList *frame_base) const; + bool GetDIENamesAndRanges( + const char *&name, const char *&mangled, DWARFRangeList &ranges, + std::optional<int> &decl_file, std::optional<int> &decl_line, + std::optional<int> &decl_column, std::optional<int> &call_file, + std::optional<int> &call_line, std::optional<int> &call_column, + lldb_private::DWARFExpressionList *frame_base) const; /// The range of all the children of this DIE. llvm::iterator_range<child_iterator> children() const; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp index a0e8dcc3d4f3..c5876502b8f2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.cpp @@ -21,9 +21,14 @@ DWARFDataExtractor::GetDWARFOffset(lldb::offset_t *offset_ptr) const { return GetMaxU64(offset_ptr, GetDWARFSizeOfOffset()); } -llvm::DWARFDataExtractor DWARFDataExtractor::GetAsLLVM() const { +llvm::DWARFDataExtractor DWARFDataExtractor::GetAsLLVMDWARF() const { return llvm::DWARFDataExtractor(llvm::ArrayRef(GetDataStart(), GetByteSize()), GetByteOrder() == lldb::eByteOrderLittle, GetAddressByteSize()); } +llvm::DataExtractor DWARFDataExtractor::GetAsLLVM() const { + return llvm::DataExtractor(llvm::ArrayRef(GetDataStart(), GetByteSize()), + GetByteOrder() == lldb::eByteOrderLittle, + GetAddressByteSize()); +} } // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h index df92bd45d5cc..b9526b079c1e 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h @@ -30,7 +30,8 @@ public: size_t GetDWARFSizeofInitialLength() const { return 4; } size_t GetDWARFSizeOfOffset() const { return 4; } - llvm::DWARFDataExtractor GetAsLLVM() const; + llvm::DWARFDataExtractor GetAsLLVMDWARF() const; + llvm::DataExtractor GetAsLLVM() const; }; } 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 d890288cdf56..0cd53463ee65 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp @@ -8,107 +8,26 @@ #include "DWARFDebugAbbrev.h" #include "DWARFDataExtractor.h" +#include "DWARFFormValue.h" #include "lldb/Utility/Stream.h" using namespace lldb; using namespace lldb_private; -// DWARFAbbreviationDeclarationSet::Clear() -void DWARFAbbreviationDeclarationSet::Clear() { - m_idx_offset = 0; - m_decls.clear(); -} - -// DWARFAbbreviationDeclarationSet::Extract() -llvm::Error -DWARFAbbreviationDeclarationSet::extract(const DWARFDataExtractor &data, - lldb::offset_t *offset_ptr) { - const lldb::offset_t begin_offset = *offset_ptr; - m_offset = begin_offset; - Clear(); - DWARFAbbreviationDeclaration abbrevDeclaration; - dw_uleb128_t prev_abbr_code = 0; - while (true) { - llvm::Expected<DWARFEnumState> es = - abbrevDeclaration.extract(data, offset_ptr); - if (!es) - return es.takeError(); - if (*es == DWARFEnumState::Complete) - break; - m_decls.push_back(abbrevDeclaration); - if (m_idx_offset == 0) - m_idx_offset = abbrevDeclaration.Code(); - else if (prev_abbr_code + 1 != abbrevDeclaration.Code()) { - // Out of order indexes, we can't do O(1) lookups... - m_idx_offset = UINT32_MAX; - } - prev_abbr_code = abbrevDeclaration.Code(); - } - return llvm::ErrorSuccess(); -} - -// DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration() -const DWARFAbbreviationDeclaration * -DWARFAbbreviationDeclarationSet::GetAbbreviationDeclaration( - dw_uleb128_t abbrCode) const { - if (m_idx_offset == UINT32_MAX) { - DWARFAbbreviationDeclarationCollConstIter pos; - DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); - for (pos = m_decls.begin(); pos != end; ++pos) { - if (pos->Code() == abbrCode) - return &(*pos); - } - } else { - uint32_t idx = abbrCode - m_idx_offset; - if (idx < m_decls.size()) - return &m_decls[idx]; - } - return nullptr; -} - - -// DWARFAbbreviationDeclarationSet::GetUnsupportedForms() -void DWARFAbbreviationDeclarationSet::GetUnsupportedForms( - std::set<dw_form_t> &invalid_forms) const { - for (const auto &abbr_decl : m_decls) { - const size_t num_attrs = abbr_decl.NumAttributes(); - for (size_t i=0; i<num_attrs; ++i) { - dw_form_t form = abbr_decl.GetFormByIndex(i); - if (!DWARFFormValue::FormIsSupported(form)) - invalid_forms.insert(form); - } - } -} - -// Encode -// -// Encode the abbreviation table onto the end of the buffer provided into a -// byte representation as would be found in a ".debug_abbrev" debug information -// section. -// void -// DWARFAbbreviationDeclarationSet::Encode(BinaryStreamBuf& debug_abbrev_buf) -// const -//{ -// DWARFAbbreviationDeclarationCollConstIter pos; -// DWARFAbbreviationDeclarationCollConstIter end = m_decls.end(); -// for (pos = m_decls.begin(); pos != end; ++pos) -// pos->Append(debug_abbrev_buf); -// debug_abbrev_buf.Append8(0); -//} - // DWARFDebugAbbrev constructor DWARFDebugAbbrev::DWARFDebugAbbrev() : m_abbrevCollMap(), m_prev_abbr_offset_pos(m_abbrevCollMap.end()) {} // DWARFDebugAbbrev::Parse() llvm::Error DWARFDebugAbbrev::parse(const DWARFDataExtractor &data) { + llvm::DataExtractor llvm_data = data.GetAsLLVM(); lldb::offset_t offset = 0; - while (data.ValidOffset(offset)) { + while (llvm_data.isValidOffset(offset)) { uint32_t initial_cu_offset = offset; DWARFAbbreviationDeclarationSet abbrevDeclSet; - llvm::Error error = abbrevDeclSet.extract(data, &offset); + llvm::Error error = abbrevDeclSet.extract(llvm_data, &offset); if (error) return error; @@ -141,5 +60,8 @@ DWARFDebugAbbrev::GetAbbreviationDeclarationSet( void DWARFDebugAbbrev::GetUnsupportedForms( std::set<dw_form_t> &invalid_forms) const { for (const auto &pair : m_abbrevCollMap) - pair.second.GetUnsupportedForms(invalid_forms); + for (const auto &decl : pair.second) + for (const auto &attr : decl.attributes()) + if (!DWARFFormValue::FormIsSupported(attr.Form)) + invalid_forms.insert(attr.Form); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h index ec6b93ce0e7f..0a579e34b001 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.h @@ -9,50 +9,16 @@ #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGABBREV_H -#include <list> -#include <map> - -#include "lldb/lldb-private.h" - -#include "DWARFAbbreviationDeclaration.h" #include "DWARFDefines.h" +#include "lldb/lldb-private.h" -typedef std::vector<DWARFAbbreviationDeclaration> - DWARFAbbreviationDeclarationColl; -typedef DWARFAbbreviationDeclarationColl::iterator - DWARFAbbreviationDeclarationCollIter; -typedef DWARFAbbreviationDeclarationColl::const_iterator - DWARFAbbreviationDeclarationCollConstIter; - -class DWARFAbbreviationDeclarationSet { -public: - DWARFAbbreviationDeclarationSet() : m_offset(DW_INVALID_OFFSET), m_decls() {} - - DWARFAbbreviationDeclarationSet(dw_offset_t offset, uint32_t idx_offset) - : m_offset(offset), m_idx_offset(idx_offset), m_decls() {} - - void Clear(); - dw_offset_t GetOffset() const { return m_offset; } - - /// Extract all abbrev decls in a set. Returns llvm::ErrorSuccess() on - /// success, and an appropriate llvm::Error object otherwise. - llvm::Error extract(const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr); - // void Encode(BinaryStreamBuf& debug_abbrev_buf) const; - void GetUnsupportedForms(std::set<dw_form_t> &invalid_forms) const; +#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" - const DWARFAbbreviationDeclaration * - GetAbbreviationDeclaration(dw_uleb128_t abbrCode) const; +#include <map> - /// Unit test accessor functions. - /// @{ - uint32_t GetIndexOffset() const { return m_idx_offset; } - /// @} -private: - dw_offset_t m_offset; - uint32_t m_idx_offset = 0; - std::vector<DWARFAbbreviationDeclaration> m_decls; -}; +using DWARFAbbreviationDeclaration = llvm::DWARFAbbreviationDeclaration; +using DWARFAbbreviationDeclarationSet = llvm::DWARFAbbreviationDeclarationSet; typedef std::map<dw_offset_t, DWARFAbbreviationDeclarationSet> DWARFAbbreviationDeclarationCollMap; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp index a37499175858..b38dd2b88c9d 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.cpp @@ -43,7 +43,7 @@ void DWARFDebugAranges::extract(const DWARFDataExtractor &debug_aranges_data) { Log *log = GetLog(DWARFLog::DebugInfo); LLDB_LOG_ERROR(log, std::move(error), "DWARFDebugAranges::extract failed to extract " - ".debug_aranges set at offset %#" PRIx64, + ".debug_aranges set at offset {1:x}: {0}", set_offset); } else { const uint32_t num_descriptors = set.NumDescriptors(); @@ -76,8 +76,8 @@ void DWARFDebugAranges::Dump(Log *log) const { for (size_t i = 0; i < num_entries; ++i) { const RangeToDIE::Entry *entry = m_aranges.GetEntryAtIndex(i); if (entry) - LLDB_LOGF(log, "0x%8.8x: [0x%" PRIx64 " - 0x%" PRIx64 ")", entry->data, - entry->GetRangeBase(), entry->GetRangeEnd()); + LLDB_LOG(log, "{0:x8}: [{1:x16} - {2:x16})", entry->data, + entry->GetRangeBase(), entry->GetRangeEnd()); } } 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 b631985d60c4..9a33d6338b87 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -136,7 +136,7 @@ uint32_t DWARFDebugInfo::FindUnitIndex(DIERef::Section section, }); uint32_t idx = std::distance(m_units.begin(), pos); if (idx == 0) - return DW_INVALID_OFFSET; + return DW_INVALID_INDEX; return idx - 1; } 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 bb1fd60a834d..a08637aef066 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -64,19 +64,17 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data, "[{0:x16}]: invalid abbreviation code {1}, " "please file a bug and " "attach the file at the start of this error message", - m_offset, (unsigned)abbr_idx); + (uint64_t)m_offset, (unsigned)abbr_idx); // WE can't parse anymore if the DWARF is borked... *offset_ptr = UINT32_MAX; return false; } - m_tag = abbrevDecl->Tag(); - m_has_children = abbrevDecl->HasChildren(); + m_tag = abbrevDecl->getTag(); + m_has_children = abbrevDecl->hasChildren(); // Skip all data in the .debug_info or .debug_types for the attributes - const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; dw_form_t form; - for (i = 0; i < numAttributes; ++i) { - form = abbrevDecl->GetFormByIndexUnchecked(i); + for (const auto &attribute : abbrevDecl->attributes()) { + form = attribute.Form; std::optional<uint8_t> fixed_skip_size = DWARFFormValue::GetFixedSize(form, cu); if (fixed_skip_size) @@ -177,7 +175,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data, case DW_FORM_indirect: form_is_indirect = true; - form = data.GetULEB128(&offset); + form = static_cast<dw_form_t>(data.GetULEB128(&offset)); break; case DW_FORM_strp: @@ -195,7 +193,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data, "[{0:x16}]: Unsupported DW_FORM_{1:x}, please file a bug " "and " "attach the file at the start of this error message", - m_offset, (unsigned)form); + (uint64_t)m_offset, (unsigned)form); *offset_ptr = m_offset; return false; } @@ -228,39 +226,46 @@ static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit, return DWARFRangeList(); } +static void ExtractAttrAndFormValue( + const llvm::DWARFAbbreviationDeclaration::AttributeSpec &attr_spec, + dw_attr_t &attr, DWARFFormValue &form_value) { + attr = attr_spec.Attr; + form_value.FormRef() = attr_spec.Form; + if (attr_spec.isImplicitConst()) + form_value.SetSigned(attr_spec.getImplicitConstValue()); +} + // GetDIENamesAndRanges // // Gets the valid address ranges for a given DIE by looking for a // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes. bool DWARFDebugInfoEntry::GetDIENamesAndRanges( DWARFUnit *cu, const char *&name, const char *&mangled, - DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column, - int &call_file, int &call_line, int &call_column, - DWARFExpressionList *frame_base) const { + DWARFRangeList &ranges, std::optional<int> &decl_file, + std::optional<int> &decl_line, std::optional<int> &decl_column, + std::optional<int> &call_file, std::optional<int> &call_line, + std::optional<int> &call_column, DWARFExpressionList *frame_base) const { dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; std::vector<DWARFDIE> dies; bool set_frame_base_loclist_addr = false; - const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); - SymbolFileDWARF &dwarf = cu->GetSymbolFileDWARF(); lldb::ModuleSP module = dwarf.GetObjectFile()->GetModule(); - if (abbrevDecl) { + if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) { const DWARFDataExtractor &data = cu->GetData(); lldb::offset_t offset = GetFirstAttributeOffset(); if (!data.ValidOffset(offset)) return false; - const uint32_t numAttributes = abbrevDecl->NumAttributes(); bool do_offset = false; - for (uint32_t i = 0; i < numAttributes; ++i) { + for (const auto &attribute : abbrevDecl->attributes()) { DWARFFormValue form_value(cu); dw_attr_t attr; - abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); + ExtractAttrAndFormValue(attribute, attr, form_value); if (form_value.ExtractValue(data, &offset)) { switch (attr) { @@ -315,32 +320,32 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( break; case DW_AT_decl_file: - if (decl_file == 0) + if (!decl_file) decl_file = form_value.Unsigned(); break; case DW_AT_decl_line: - if (decl_line == 0) + if (!decl_line) decl_line = form_value.Unsigned(); break; case DW_AT_decl_column: - if (decl_column == 0) + if (!decl_column) decl_column = form_value.Unsigned(); break; case DW_AT_call_file: - if (call_file == 0) + if (!call_file) call_file = form_value.Unsigned(); break; case DW_AT_call_line: - if (call_line == 0) + if (!call_line) call_line = form_value.Unsigned(); break; case DW_AT_call_column: - if (call_column == 0) + if (!call_column) call_column = form_value.Unsigned(); break; @@ -409,61 +414,60 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( // specification or abstract origin attributes and including those in the // results. Any duplicate attributes will have the first instance take // precedence (this can happen for declaration attributes). -size_t DWARFDebugInfoEntry::GetAttributes(DWARFUnit *cu, - DWARFAttributes &attributes, - Recurse recurse, - uint32_t curr_depth) const { +void DWARFDebugInfoEntry::GetAttributes(DWARFUnit *cu, + DWARFAttributes &attributes, + Recurse recurse, + uint32_t curr_depth) const { const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu); - if (abbrevDecl) { - const DWARFDataExtractor &data = cu->GetData(); - lldb::offset_t offset = GetFirstAttributeOffset(); - - const uint32_t num_attributes = abbrevDecl->NumAttributes(); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value(cu); - dw_attr_t attr; - abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); - const dw_form_t form = form_value.Form(); + if (!abbrevDecl) { + attributes.Clear(); + return; + } - // If we are tracking down DW_AT_specification or DW_AT_abstract_origin - // attributes, the depth will be non-zero. We need to omit certain - // attributes that don't make sense. - switch (attr) { - case DW_AT_sibling: - case DW_AT_declaration: - if (curr_depth > 0) { - // This attribute doesn't make sense when combined with the DIE that - // references this DIE. We know a DIE is referencing this DIE because - // curr_depth is not zero - break; - } - [[fallthrough]]; - default: - attributes.Append(form_value, offset, attr); + const DWARFDataExtractor &data = cu->GetData(); + lldb::offset_t offset = GetFirstAttributeOffset(); + + for (const auto &attribute : abbrevDecl->attributes()) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + ExtractAttrAndFormValue(attribute, attr, form_value); + + // If we are tracking down DW_AT_specification or DW_AT_abstract_origin + // attributes, the depth will be non-zero. We need to omit certain + // attributes that don't make sense. + switch (attr) { + case DW_AT_sibling: + case DW_AT_declaration: + if (curr_depth > 0) { + // This attribute doesn't make sense when combined with the DIE that + // references this DIE. We know a DIE is referencing this DIE because + // curr_depth is not zero break; } + [[fallthrough]]; + default: + attributes.Append(form_value, offset, attr); + break; + } - if (recurse == Recurse::yes && - ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) { - if (form_value.ExtractValue(data, &offset)) { - DWARFDIE spec_die = form_value.Reference(); - if (spec_die) - spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes, - recurse, curr_depth + 1); - } - } else { - std::optional<uint8_t> fixed_skip_size = - DWARFFormValue::GetFixedSize(form, cu); - if (fixed_skip_size) - offset += *fixed_skip_size; - else - DWARFFormValue::SkipValue(form, data, &offset, cu); + if (recurse == Recurse::yes && + ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) { + if (form_value.ExtractValue(data, &offset)) { + DWARFDIE spec_die = form_value.Reference(); + if (spec_die) + spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes, + recurse, curr_depth + 1); } + } else { + const dw_form_t form = form_value.Form(); + std::optional<uint8_t> fixed_skip_size = + DWARFFormValue::GetFixedSize(form, cu); + if (fixed_skip_size) + offset += *fixed_skip_size; + else + DWARFFormValue::SkipValue(form, data, &offset, cu); } - } else { - attributes.Clear(); } - return attributes.Size(); } // GetAttributeValue @@ -477,20 +481,20 @@ dw_offset_t DWARFDebugInfoEntry::GetAttributeValue( dw_offset_t *end_attr_offset_ptr, bool check_specification_or_abstract_origin) const { if (const auto *abbrevDecl = GetAbbreviationDeclarationPtr(cu)) { - uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr); + std::optional<uint32_t> attr_idx = abbrevDecl->findAttributeIndex(attr); - if (attr_idx != DW_INVALID_INDEX) { + if (attr_idx) { const DWARFDataExtractor &data = cu->GetData(); lldb::offset_t offset = GetFirstAttributeOffset(); uint32_t idx = 0; - while (idx < attr_idx) - DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++), - data, &offset, cu); + while (idx < *attr_idx) + DWARFFormValue::SkipValue(abbrevDecl->getFormByIndex(idx++), data, + &offset, cu); const dw_offset_t attr_offset = offset; form_value.SetUnit(cu); - form_value.SetForm(abbrevDecl->GetFormByIndex(idx)); + form_value.SetForm(abbrevDecl->getFormByIndex(idx)); if (form_value.ExtractValue(data, &offset)) { if (end_attr_offset_ptr) *end_attr_offset_ptr = offset; @@ -632,15 +636,16 @@ bool DWARFDebugInfoEntry::GetAttributeAddressRange( return false; } -size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( - DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, +DWARFRangeList DWARFDebugInfoEntry::GetAttributeAddressRanges( + DWARFUnit *cu, bool check_hi_lo_pc, bool check_specification_or_abstract_origin) const { - ranges.Clear(); DWARFFormValue form_value; - if (GetAttributeValue(cu, DW_AT_ranges, form_value)) { - ranges = GetRangesOrReportError(*cu, *this, form_value); - } else if (check_hi_lo_pc) { + if (GetAttributeValue(cu, DW_AT_ranges, form_value)) + return GetRangesOrReportError(*cu, *this, form_value); + + DWARFRangeList ranges; + if (check_hi_lo_pc) { dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; if (GetAttributeAddressRange(cu, lo_pc, hi_pc, LLDB_INVALID_ADDRESS, @@ -649,7 +654,7 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc)); } } - return ranges.GetSize(); + return ranges; } // GetName @@ -712,9 +717,8 @@ void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable( DWARFUnit *cu, DWARFDebugAranges *debug_aranges) const { if (m_tag) { if (m_tag == DW_TAG_subprogram) { - DWARFRangeList ranges; - GetAttributeAddressRanges(cu, ranges, - /*check_hi_lo_pc=*/true); + DWARFRangeList ranges = + GetAttributeAddressRanges(cu, /*check_hi_lo_pc=*/true); for (const auto &r : ranges) { debug_aranges->AppendRange(GetOffset(), r.GetRangeBase(), r.GetRangeEnd()); @@ -755,8 +759,7 @@ DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const { DWARFDIE DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const { - DWARFAttributes attributes; - GetAttributes(cu, attributes, Recurse::yes); + DWARFAttributes attributes = GetAttributes(cu, Recurse::yes); return GetParentDeclContextDIE(cu, attributes); } @@ -809,12 +812,14 @@ lldb::offset_t DWARFDebugInfoEntry::GetFirstAttributeOffset() const { const DWARFAbbreviationDeclaration * DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const { - if (cu) { - const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations(); - if (abbrev_set) - return abbrev_set->GetAbbreviationDeclaration(m_abbr_idx); - } - return nullptr; + if (!cu) + return nullptr; + + const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations(); + if (!abbrev_set) + return nullptr; + + return abbrev_set->getAbbreviationDeclaration(m_abbr_idx); } bool DWARFDebugInfoEntry::IsGlobalOrStaticScopeVariable() const { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index fcfffbfd38f0..c2ea40065232 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -12,7 +12,7 @@ #include "SymbolFileDWARF.h" #include "llvm/ADT/SmallVector.h" -#include "DWARFAbbreviationDeclaration.h" +#include "DWARFAttribute.h" #include "DWARFBaseDIE.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugRanges.h" @@ -21,6 +21,8 @@ #include <set> #include <vector> +#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" + class DWARFDeclContext; #define DIE_SIBLING_IDX_BITSIZE 31 @@ -36,7 +38,8 @@ public: typedef collection::const_iterator const_iterator; DWARFDebugInfoEntry() - : m_offset(DW_INVALID_OFFSET), m_sibling_idx(0), m_has_children(false) {} + : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0), + m_has_children(false) {} explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; } bool operator==(const DWARFDebugInfoEntry &rhs) const; @@ -49,9 +52,11 @@ public: const DWARFUnit *cu, lldb::offset_t *offset_ptr); using Recurse = DWARFBaseDIE::Recurse; - size_t GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, - Recurse recurse = Recurse::yes) const { - return GetAttributes(cu, attrs, recurse, 0 /* curr_depth */); + DWARFAttributes GetAttributes(DWARFUnit *cu, + Recurse recurse = Recurse::yes) const { + DWARFAttributes attrs; + GetAttributes(cu, attrs, recurse, 0 /* curr_depth */); + return attrs; } dw_offset_t @@ -89,8 +94,8 @@ public: uint64_t fail_value, bool check_specification_or_abstract_origin = false) const; - size_t GetAttributeAddressRanges( - DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc, + DWARFRangeList GetAttributeAddressRanges( + DWARFUnit *cu, bool check_hi_lo_pc, bool check_specification_or_abstract_origin = false) const; const char *GetName(const DWARFUnit *cu) const; @@ -102,11 +107,13 @@ public: bool GetDIENamesAndRanges( DWARFUnit *cu, const char *&name, const char *&mangled, - DWARFRangeList &rangeList, int &decl_file, int &decl_line, - int &decl_column, int &call_file, int &call_line, int &call_column, + DWARFRangeList &rangeList, std::optional<int> &decl_file, + std::optional<int> &decl_line, std::optional<int> &decl_column, + std::optional<int> &call_file, std::optional<int> &call_line, + std::optional<int> &call_column, lldb_private::DWARFExpressionList *frame_base = nullptr) const; - const DWARFAbbreviationDeclaration * + const llvm::DWARFAbbreviationDeclaration * GetAbbreviationDeclarationPtr(const DWARFUnit *cu) const; lldb::offset_t GetFirstAttributeOffset() const; @@ -165,22 +172,24 @@ protected: static DWARFDeclContext GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu); - dw_offset_t m_offset; // Offset within the .debug_info/.debug_types - uint32_t m_parent_idx = 0; // How many to subtract from "this" to get the - // parent. If zero this die has no parent - uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling. - // If it is zero, then the DIE doesn't have children, or the - // DWARF claimed it had children but the DIE only contained - // a single NULL terminating child. - m_has_children : 1; + // Up to 2TB offset within the .debug_info/.debug_types + dw_offset_t m_offset : DW_DIE_OFFSET_MAX_BITSIZE; + // How many to subtract from "this" to get the parent. If zero this die has no + // parent + dw_offset_t m_parent_idx : 64 - DW_DIE_OFFSET_MAX_BITSIZE; + // How many to add to "this" to get the sibling. + // If it is zero, then the DIE doesn't have children, + // or the DWARF claimed it had children but the DIE + // only contained a single NULL terminating child. + uint32_t m_sibling_idx : 31, m_has_children : 1; uint16_t m_abbr_idx = 0; /// A copy of the DW_TAG value so we don't have to go through the compile /// unit abbrev table dw_tag_t m_tag = llvm::dwarf::DW_TAG_null; private: - size_t GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, Recurse recurse, - uint32_t curr_depth) const; + void GetAttributes(DWARFUnit *cu, DWARFAttributes &attrs, Recurse recurse, + uint32_t curr_depth) const; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGINFOENTRY_H diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index 6a0f11d2a1c4..0b5bb23a4981 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -8,119 +8,48 @@ #include "DWARFDebugRanges.h" #include "DWARFUnit.h" -#include "lldb/Utility/Stream.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" using namespace lldb_private; -static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) { - switch(addr_size) { - case 2: - return 0xffff; - case 4: - return 0xffffffff; - case 8: - return 0xffffffffffffffff; - } - llvm_unreachable("GetBaseAddressMarker unsupported address size."); -} - DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} void DWARFDebugRanges::Extract(DWARFContext &context) { - DWARFRangeList range_list; - lldb::offset_t offset = 0; - dw_offset_t debug_ranges_offset = offset; - while (Extract(context, &offset, range_list)) { - range_list.Sort(); - m_range_map[debug_ranges_offset] = range_list; - debug_ranges_offset = offset; - } -} - -bool DWARFDebugRanges::Extract(DWARFContext &context, - lldb::offset_t *offset_ptr, - DWARFRangeList &range_list) { - range_list.Clear(); - - lldb::offset_t range_offset = *offset_ptr; - const DWARFDataExtractor &debug_ranges_data = context.getOrLoadRangesData(); - uint32_t addr_size = debug_ranges_data.GetAddressByteSize(); - dw_addr_t base_addr = 0; - dw_addr_t base_addr_marker = GetBaseAddressMarker(addr_size); - - while ( - debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { - dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - - if (!begin && !end) { - // End of range list - break; - } - - if (begin == base_addr_marker) { - base_addr = end; - continue; - } - - // Filter out empty ranges - if (begin < end) - range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin)); - } - - // Make sure we consumed at least something - return range_offset != *offset_ptr; -} - -void DWARFDebugRanges::Dump(Stream &s, - const DWARFDataExtractor &debug_ranges_data, - lldb::offset_t *offset_ptr, - dw_addr_t cu_base_addr) { - uint32_t addr_size = s.GetAddressByteSize(); - - dw_addr_t base_addr = cu_base_addr; - while ( - debug_ranges_data.ValidOffsetForDataOfSize(*offset_ptr, 2 * addr_size)) { - dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size); - // Extend 4 byte addresses that consists of 32 bits of 1's to be 64 bits of - // ones - if (begin == 0xFFFFFFFFull && addr_size == 4) - begin = LLDB_INVALID_ADDRESS; - - s.Indent(); - if (begin == 0 && end == 0) { - s.PutCString(" End"); - break; - } else if (begin == LLDB_INVALID_ADDRESS) { - // A base address selection entry - base_addr = end; - DumpAddress(s.AsRawOstream(), base_addr, sizeof(dw_addr_t), - " Base address = "); - } else { - // Convert from offset to an address - dw_addr_t begin_addr = begin + base_addr; - dw_addr_t end_addr = end + base_addr; - - DumpAddressRange(s.AsRawOstream(), begin_addr, end_addr, - sizeof(dw_addr_t), nullptr); + llvm::DWARFDataExtractor extractor = + context.getOrLoadRangesData().GetAsLLVMDWARF(); + llvm::DWARFDebugRangeList extracted_list; + uint64_t current_offset = 0; + auto extract_next_list = [&] { + if (auto error = extracted_list.extract(extractor, ¤t_offset)) { + consumeError(std::move(error)); + return false; } + return true; + }; + + uint64_t previous_offset = current_offset; + while (extractor.isValidOffset(current_offset) && extract_next_list()) { + DWARFRangeList &lldb_range_list = m_range_map[previous_offset]; + lldb_range_list.Reserve(extracted_list.getEntries().size()); + for (auto &range : extracted_list.getEntries()) + lldb_range_list.Append(range.StartAddress, + range.EndAddress - range.StartAddress); + lldb_range_list.Sort(); + previous_offset = current_offset; } } -bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu, - dw_offset_t debug_ranges_offset, - DWARFRangeList &range_list) const { +DWARFRangeList +DWARFDebugRanges::FindRanges(const DWARFUnit *cu, + dw_offset_t debug_ranges_offset) const { dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; - range_map_const_iterator pos = m_range_map.find(debug_ranges_address); - if (pos != m_range_map.end()) { - range_list = pos->second; - - // All DW_AT_ranges are relative to the base address of the compile - // unit. We add the compile unit base address to make sure all the - // addresses are properly fixed up. - range_list.Slide(cu->GetBaseAddress()); - return true; - } - return false; + auto pos = m_range_map.find(debug_ranges_address); + DWARFRangeList ans = + pos == m_range_map.end() ? DWARFRangeList() : pos->second; + + // All DW_AT_ranges are relative to the base address of the compile + // unit. We add the compile unit base address to make sure all the + // addresses are properly fixed up. + ans.Slide(cu->GetBaseAddress()); + return ans; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h index b587845a67d9..2e06cd5daf6f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -22,21 +22,11 @@ public: DWARFDebugRanges(); void Extract(lldb_private::DWARFContext &context); - bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, - DWARFRangeList &range_list) const; - - static void Dump(lldb_private::Stream &s, - const lldb_private::DWARFDataExtractor &debug_ranges_data, - lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr); + DWARFRangeList FindRanges(const DWARFUnit *cu, + dw_offset_t debug_ranges_offset) const; protected: - bool Extract(lldb_private::DWARFContext &context, lldb::offset_t *offset_ptr, - DWARFRangeList &range_list); - - typedef std::map<dw_offset_t, DWARFRangeList> range_map; - typedef range_map::iterator range_map_iterator; - typedef range_map::const_iterator range_map_const_iterator; - range_map m_range_map; + std::map<dw_offset_t, DWARFRangeList> m_range_map; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDEBUGRANGES_H diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index fa776f27d501..13e3dfb70c0c 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -9,11 +9,13 @@ #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFDECLCONTEXT_H -#include <string> -#include <vector> #include "lldb/Utility/ConstString.h" #include "DWARFDefines.h" +#include <cassert> +#include <string> +#include <vector> + // DWARFDeclContext // // A class that represents a declaration context all the way down to a @@ -53,12 +55,12 @@ public: uint32_t GetSize() const { return m_entries.size(); } Entry &operator[](uint32_t idx) { - // "idx" must be valid + assert(idx < m_entries.size() && "invalid index"); return m_entries[idx]; } const Entry &operator[](uint32_t idx) const { - // "idx" must be valid + assert(idx < m_entries.size() && "invalid index"); return m_entries[idx]; } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h index 2d0d5cad4612..2afdbb47381a 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h @@ -14,8 +14,6 @@ namespace lldb_private { -enum class DWARFEnumState { MoreItems, Complete }; - typedef uint32_t DRC_class; // Holds DRC_* class bitfields const char *DW_TAG_value_to_name(uint32_t val); 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 a1578b47ae94..6ca17dcf47ff 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -25,7 +25,7 @@ using namespace lldb_private::dwarf; void DWARFFormValue::Clear() { m_unit = nullptr; - m_form = 0; + m_form = dw_form_t(0); m_value = ValueTypeTag(); } @@ -127,7 +127,7 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); break; case DW_FORM_indirect: - m_form = data.GetULEB128(offset_ptr); + m_form = static_cast<dw_form_t>(data.GetULEB128(offset_ptr)); indirect = true; break; case DW_FORM_flag_present: @@ -216,22 +216,22 @@ bool DWARFFormValue::SkipValue(dw_form_t form, // in the .debug_info case DW_FORM_exprloc: case DW_FORM_block: { - dw_uleb128_t size = debug_info_data.GetULEB128(offset_ptr); + uint64_t size = debug_info_data.GetULEB128(offset_ptr); *offset_ptr += size; } return true; case DW_FORM_block1: { - dw_uleb128_t size = debug_info_data.GetU8(offset_ptr); + uint8_t size = debug_info_data.GetU8(offset_ptr); *offset_ptr += size; } return true; case DW_FORM_block2: { - dw_uleb128_t size = debug_info_data.GetU16(offset_ptr); + uint16_t size = debug_info_data.GetU16(offset_ptr); *offset_ptr += size; } return true; case DW_FORM_block4: { - dw_uleb128_t size = debug_info_data.GetU32(offset_ptr); + uint32_t size = debug_info_data.GetU32(offset_ptr); *offset_ptr += size; } return true; @@ -321,9 +321,10 @@ bool DWARFFormValue::SkipValue(dw_form_t form, return true; case DW_FORM_indirect: { - dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); - return DWARFFormValue::SkipValue(indirect_form, debug_info_data, offset_ptr, - unit); + auto indirect_form = + static_cast<dw_form_t>(debug_info_data.GetULEB128(offset_ptr)); + return DWARFFormValue::SkipValue(indirect_form, debug_info_data, + offset_ptr, unit); } default: @@ -573,8 +574,10 @@ bool DWARFFormValue::IsBlockForm(const dw_form_t form) { case DW_FORM_block2: case DW_FORM_block4: return true; + default: + return false; } - return false; + llvm_unreachable("All cases handled above!"); } bool DWARFFormValue::IsDataForm(const dw_form_t form) { @@ -586,8 +589,10 @@ bool DWARFFormValue::IsDataForm(const dw_form_t form) { case DW_FORM_data4: case DW_FORM_data8: return true; + default: + return false; } - return false; + llvm_unreachable("All cases handled above!"); } bool DWARFFormValue::FormIsSupported(dw_form_t form) { diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index 90e07ea67f53..2a8843c1a0d4 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -45,7 +45,7 @@ public: const DWARFUnit *GetUnit() const { return m_unit; } void SetUnit(const DWARFUnit *unit) { m_unit = unit; } dw_form_t Form() const { return m_form; } - dw_form_t& FormRef() { return m_form; } + dw_form_t &FormRef() { return m_form; } void SetForm(dw_form_t form) { m_form = form; } const ValueType &Value() const { return m_value; } ValueType &ValueRef() { return m_value; } @@ -83,7 +83,7 @@ protected: // Compile unit where m_value was located. // It may be different from compile unit where m_value refers to. const DWARFUnit *m_unit = nullptr; // Unit for this form - dw_form_t m_form = 0; // Form for this value + dw_form_t m_form = dw_form_t(0); // Form for this value ValueType m_value; // Contains all data for the form }; 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 6e957f7eae62..779b52481b85 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -99,6 +99,12 @@ bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const { return true; } +bool DWARFIndex::DIERefCallbackImpl::operator()( + const llvm::AppleAcceleratorTable::Entry &entry) const { + return this->operator()(DIERef(std::nullopt, DIERef::Section::DebugInfo, + *entry.getDIESectionOffset())); +} + void DWARFIndex::ReportInvalidDIERef(DIERef ref, llvm::StringRef name) const { m_module.ReportErrorIfModifyDetected( "the DWARF debug information has been modified (accelerator table had " diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h index c8207931a819..13fe96dae2aa 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.h @@ -12,6 +12,7 @@ #include "Plugins/SymbolFile/DWARF/DIERef.h" #include "Plugins/SymbolFile/DWARF/DWARFDIE.h" #include "Plugins/SymbolFile/DWARF/DWARFFormValue.h" +#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "lldb/Core/Module.h" #include "lldb/Target/Statistics.h" @@ -85,6 +86,7 @@ protected: llvm::function_ref<bool(DWARFDIE die)> callback, llvm::StringRef name); bool operator()(DIERef ref) const; + bool operator()(const llvm::AppleAcceleratorTable::Entry &entry) const; private: const DWARFIndex &m_index; 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 ba8d0e9c9927..749ffcb094ec 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -341,7 +341,7 @@ void DWARFUnit::SetDwoStrOffsetsBase() { if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { if (const auto *contribution = entry->getContribution(llvm::DW_SECT_STR_OFFSETS)) - baseOffset = contribution->getOffset32(); + baseOffset = contribution->getOffset(); else return; } @@ -371,11 +371,10 @@ std::optional<uint64_t> DWARFUnit::GetDWOId() { // m_die_array_mutex must be already held as read/write. void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { - DWARFAttributes attributes; - size_t num_attributes = cu_die.GetAttributes(this, attributes); + DWARFAttributes attributes = cu_die.GetAttributes(this); // Extract DW_AT_addr_base first, as other attributes may need it. - for (size_t i = 0; i < num_attributes; ++i) { + for (size_t i = 0; i < attributes.Size(); ++i) { if (attributes.AttributeAtIndex(i) != DW_AT_addr_base) continue; DWARFFormValue form_value; @@ -385,12 +384,14 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { } } - for (size_t i = 0; i < num_attributes; ++i) { + for (size_t i = 0; i < attributes.Size(); ++i) { dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; if (!attributes.ExtractFormValueAtIndex(i, form_value)) continue; switch (attr) { + default: + break; case DW_AT_loclists_base: SetLoclistsBase(form_value.Unsigned()); break; @@ -439,7 +440,7 @@ const DWARFAbbreviationDeclarationSet *DWARFUnit::GetAbbreviations() const { } dw_offset_t DWARFUnit::GetAbbrevOffset() const { - return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; + return m_abbrevs ? m_abbrevs->getOffset() : DW_INVALID_OFFSET; } dw_offset_t DWARFUnit::GetLineTableOffset() { @@ -489,7 +490,7 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { *GetDWOId()); return; } - offset += contribution->getOffset32(); + offset += contribution->getOffset(); } m_loclists_base = loclists_base; @@ -500,7 +501,7 @@ void DWARFUnit::SetLoclistsBase(dw_addr_t loclists_base) { m_loclist_table_header.emplace(".debug_loclists", "locations"); offset += loclists_base - header_size; if (llvm::Error E = m_loclist_table_header->extract( - m_dwarf.GetDWARFContext().getOrLoadLocListsData().GetAsLLVM(), + m_dwarf.GetDWARFContext().getOrLoadLocListsData().GetAsLLVMDWARF(), &offset)) { GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( "Failed to extract location list table at offset {0:x16} (location " @@ -527,7 +528,7 @@ DWARFDataExtractor DWARFUnit::GetLocationData() const { if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { if (const auto *contribution = entry->getContribution( GetVersion() >= 5 ? llvm::DW_SECT_LOCLISTS : llvm::DW_SECT_EXT_LOC)) - return DWARFDataExtractor(data, contribution->getOffset32(), + return DWARFDataExtractor(data, contribution->getOffset(), contribution->getLength32()); return DWARFDataExtractor(); } @@ -540,7 +541,7 @@ DWARFDataExtractor DWARFUnit::GetRnglistData() const { if (const llvm::DWARFUnitIndex::Entry *entry = m_header.GetIndexEntry()) { if (const auto *contribution = entry->getContribution(llvm::DW_SECT_RNGLISTS)) - return DWARFDataExtractor(data, contribution->getOffset32(), + return DWARFDataExtractor(data, contribution->getOffset(), contribution->getLength32()); GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( "Failed to find range list contribution for CU with signature {0:x16}", @@ -563,7 +564,7 @@ DWARFUnit::GetRnglistTable() { m_rnglist_table_done = true; if (auto table_or_error = ParseListTableHeader<llvm::DWARFDebugRnglistTable>( - GetRnglistData().GetAsLLVM(), m_ranges_base, DWARF32)) + GetRnglistData().GetAsLLVMDWARF(), m_ranges_base, DWARF32)) m_rnglist_table = std::move(table_or_error.get()); else GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError( @@ -935,12 +936,13 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, llvm::inconvertibleErrorCode(), "DWARF package index missing abbreviation column"); } - header.m_abbr_offset = abbr_entry->getOffset32(); + header.m_abbr_offset = abbr_entry->getOffset(); } bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1); bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version); - bool addr_size_OK = (header.m_addr_size == 4) || (header.m_addr_size == 8); + bool addr_size_OK = (header.m_addr_size == 2) || (header.m_addr_size == 4) || + (header.m_addr_size == 8); bool type_offset_OK = !header.IsTypeUnit() || (header.m_type_offset <= header.GetLength()); @@ -1031,16 +1033,14 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { if (!debug_ranges) return llvm::make_error<llvm::object::GenericBinaryError>( "No debug_ranges section"); - DWARFRangeList ranges; - debug_ranges->FindRanges(this, offset, ranges); - return ranges; + return debug_ranges->FindRanges(this, offset); } if (!GetRnglistTable()) return llvm::createStringError(std::errc::invalid_argument, "missing or invalid range list table"); - llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVM(); + llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVMDWARF(); // As DW_AT_rnglists_base may be missing we need to call setAddressSize. data.setAddressSize(m_header.GetAddressByteSize()); 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 a70628a3866a..bc55b093e894 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -223,6 +223,8 @@ public: uint8_t GetUnitType() const { return m_header.GetUnitType(); } bool IsTypeUnit() const { return m_header.IsTypeUnit(); } + /// Note that this check only works for DWARF5+. + bool IsSkeletonUnit() const { return GetUnitType() == llvm::dwarf::DW_UT_skeleton; } std::optional<uint64_t> GetStringOffsetSectionItem(uint32_t index) const; 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 68adb3705100..af2d6c554140 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -23,8 +23,8 @@ llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names, DWARFDataExtractor debug_str, SymbolFileDWARF &dwarf) { - auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVM(), - debug_str.GetAsLLVM()); + auto index_up = std::make_unique<DebugNames>(debug_names.GetAsLLVMDWARF(), + debug_str.GetAsLLVM()); if (llvm::Error E = index_up->extract()) return std::move(E); @@ -54,7 +54,7 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) { cu = &cu->GetNonSkeletonUnit(); if (std::optional<uint64_t> die_offset = entry.getDIEUnitOffset()) - return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(), + return DIERef(cu->GetSymbolFileDWARF().GetFileIndex(), DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset); return std::nullopt; @@ -62,7 +62,7 @@ DebugNamesDWARFIndex::ToDIERef(const DebugNames::Entry &entry) { bool DebugNamesDWARFIndex::ProcessEntry( const DebugNames::Entry &entry, - llvm::function_ref<bool(DWARFDIE die)> callback, llvm::StringRef name) { + llvm::function_ref<bool(DWARFDIE die)> callback) { std::optional<DIERef> ref = ToDIERef(entry); if (!ref) return true; @@ -92,7 +92,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables( if (entry.tag() != DW_TAG_variable) continue; - if (!ProcessEntry(entry, callback, basename.GetStringRef())) + if (!ProcessEntry(entry, callback)) return; } @@ -104,7 +104,8 @@ void DebugNamesDWARFIndex::GetGlobalVariables( llvm::function_ref<bool(DWARFDIE die)> callback) { for (const DebugNames::NameIndex &ni: *m_debug_names_up) { for (DebugNames::NameTableEntry nte: ni) { - if (!regex.Execute(nte.getString())) + Mangled mangled_name(nte.getString()); + if (!mangled_name.NameMatches(regex)) continue; uint64_t entry_offset = nte.getEntryOffset(); @@ -113,8 +114,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables( if (entry_or->tag() != DW_TAG_variable) continue; - if (!ProcessEntry(*entry_or, callback, - llvm::StringRef(nte.getString()))) + if (!ProcessEntry(*entry_or, callback)) return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); @@ -126,7 +126,6 @@ void DebugNamesDWARFIndex::GetGlobalVariables( void DebugNamesDWARFIndex::GetGlobalVariables( DWARFUnit &cu, llvm::function_ref<bool(DWARFDIE die)> callback) { - lldbassert(!cu.GetSymbolFileDWARF().GetDwoNum()); uint64_t cu_offset = cu.GetOffset(); bool found_entry_for_cu = false; for (const DebugNames::NameIndex &ni: *m_debug_names_up) { @@ -140,8 +139,7 @@ void DebugNamesDWARFIndex::GetGlobalVariables( continue; found_entry_for_cu = true; - if (!ProcessEntry(*entry_or, callback, - llvm::StringRef(nte.getString()))) + if (!ProcessEntry(*entry_or, callback)) return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); @@ -203,7 +201,7 @@ void DebugNamesDWARFIndex::GetTypes( for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { if (isType(entry.tag())) { - if (!ProcessEntry(entry, callback, name.GetStringRef())) + if (!ProcessEntry(entry, callback)) return; } } @@ -217,7 +215,7 @@ void DebugNamesDWARFIndex::GetTypes( auto name = context[0].name; for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name)) { if (entry.tag() == context[0].tag) { - if (!ProcessEntry(entry, callback, name)) + if (!ProcessEntry(entry, callback)) return; } } @@ -229,8 +227,10 @@ void DebugNamesDWARFIndex::GetNamespaces( ConstString name, llvm::function_ref<bool(DWARFDIE die)> callback) { for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { - if (entry.tag() == DW_TAG_namespace) { - if (!ProcessEntry(entry, callback, name.GetStringRef())) + dwarf::Tag entry_tag = entry.tag(); + if (entry_tag == DW_TAG_namespace || + entry_tag == DW_TAG_imported_declaration) { + if (!ProcessEntry(entry, callback)) return; } } @@ -279,8 +279,7 @@ void DebugNamesDWARFIndex::GetFunctions( if (tag != DW_TAG_subprogram && tag != DW_TAG_inlined_subroutine) continue; - if (!ProcessEntry(*entry_or, callback, - llvm::StringRef(nte.getString()))) + if (!ProcessEntry(*entry_or, callback)) return; } MaybeLogLookupError(entry_or.takeError(), ni, nte.getString()); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h index 21a3d8dcc0e3..abbd700f1603 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.h @@ -80,8 +80,7 @@ private: std::optional<DIERef> ToDIERef(const DebugNames::Entry &entry); bool ProcessEntry(const DebugNames::Entry &entry, - llvm::function_ref<bool(DWARFDIE die)> callback, - llvm::StringRef name); + llvm::function_ref<bool(DWARFDIE die)> callback); static void MaybeLogLookupError(llvm::Error error, const DebugNames::NameIndex &ni, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp deleted file mode 100644 index c31a3d8ce913..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ /dev/null @@ -1,593 +0,0 @@ -//===-- HashedNameToDIE.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 "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) { - const size_t count = die_info_array.size(); - for (size_t i = 0; i < count; ++i) - if (!callback(DIERef(die_info_array[i]))) - return false; - return true; -} - -void DWARFMappedHash::ExtractDIEArray( - const DIEInfoArray &die_info_array, const dw_tag_t tag, - llvm::function_ref<bool(DIERef ref)> callback) { - if (tag == 0) { - ExtractDIEArray(die_info_array, callback); - return; - } - - const size_t count = die_info_array.size(); - for (size_t i = 0; i < count; ++i) { - const dw_tag_t die_tag = die_info_array[i].tag; - bool tag_matches = die_tag == 0 || tag == die_tag; - if (!tag_matches) { - if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) - tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type; - } - if (tag_matches) { - if (!callback(DIERef(die_info_array[i]))) - return; - } - } -} - -void DWARFMappedHash::ExtractDIEArray( - const DIEInfoArray &die_info_array, const dw_tag_t tag, - const uint32_t qualified_name_hash, - llvm::function_ref<bool(DIERef ref)> callback) { - if (tag == 0) { - ExtractDIEArray(die_info_array, callback); - return; - } - - const size_t count = die_info_array.size(); - for (size_t i = 0; i < count; ++i) { - if (qualified_name_hash != die_info_array[i].qualified_name_hash) - continue; - const dw_tag_t die_tag = die_info_array[i].tag; - bool tag_matches = die_tag == 0 || tag == die_tag; - if (!tag_matches) { - if (die_tag == DW_TAG_class_type || die_tag == DW_TAG_structure_type) - tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type; - } - if (tag_matches) { - if (!callback(DIERef(die_info_array[i]))) - return; - } - } -} - -void DWARFMappedHash::ExtractClassOrStructDIEArray( - const DIEInfoArray &die_info_array, - bool return_implementation_only_if_available, - llvm::function_ref<bool(DIERef ref)> callback) { - const size_t count = die_info_array.size(); - for (size_t i = 0; i < count; ++i) { - const dw_tag_t die_tag = die_info_array[i].tag; - if (!(die_tag == 0 || die_tag == DW_TAG_class_type || - die_tag == DW_TAG_structure_type)) - continue; - bool is_implementation = - (die_info_array[i].type_flags & eTypeFlagClassIsImplementation) != 0; - if (is_implementation != return_implementation_only_if_available) - continue; - if (return_implementation_only_if_available) { - // We found the one true definition for this class, so only return - // that - callback(DIERef(die_info_array[i])); - return; - } - if (!callback(DIERef(die_info_array[i]))) - return; - } -} - -void DWARFMappedHash::ExtractTypesFromDIEArray( - const DIEInfoArray &die_info_array, uint32_t type_flag_mask, - uint32_t type_flag_value, llvm::function_ref<bool(DIERef ref)> callback) { - const size_t count = die_info_array.size(); - for (size_t i = 0; i < count; ++i) { - if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value) { - if (!callback(DIERef(die_info_array[i]))) - return; - } - } -} - -const char *DWARFMappedHash::GetAtomTypeName(uint16_t atom) { - switch (atom) { - case eAtomTypeNULL: - return "NULL"; - case eAtomTypeDIEOffset: - return "die-offset"; - case eAtomTypeCUOffset: - return "cu-offset"; - case eAtomTypeTag: - return "die-tag"; - case eAtomTypeNameFlags: - return "name-flags"; - case eAtomTypeTypeFlags: - return "type-flags"; - case eAtomTypeQualNameHash: - return "qualified-name-hash"; - } - return "<invalid>"; -} - -DWARFMappedHash::DIEInfo::DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, - uint32_t h) - : die_offset(o), tag(t), type_flags(f), qualified_name_hash(h) {} - -DWARFMappedHash::Prologue::Prologue(dw_offset_t _die_base_offset) - : die_base_offset(_die_base_offset), atoms() { - // Define an array of DIE offsets by first defining an array, and then define - // the atom type for the array, in this case we have an array of DIE offsets. - AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4); -} - -void DWARFMappedHash::Prologue::ClearAtoms() { - hash_data_has_fixed_byte_size = true; - min_hash_data_byte_size = 0; - atom_mask = 0; - atoms.clear(); -} - -bool DWARFMappedHash::Prologue::ContainsAtom(AtomType atom_type) const { - return (atom_mask & (1u << atom_type)) != 0; -} - -void DWARFMappedHash::Prologue::Clear() { - die_base_offset = 0; - ClearAtoms(); -} - -void DWARFMappedHash::Prologue::AppendAtom(AtomType type, dw_form_t form) { - atoms.push_back({type, form}); - atom_mask |= 1u << type; - switch (form) { - case DW_FORM_indirect: - case DW_FORM_exprloc: - case DW_FORM_flag_present: - case DW_FORM_ref_sig8: - llvm_unreachable("Unhandled atom form"); - - case DW_FORM_addrx: - case DW_FORM_string: - case DW_FORM_block: - case DW_FORM_block1: - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_ref_udata: - case DW_FORM_GNU_addr_index: - case DW_FORM_GNU_str_index: - hash_data_has_fixed_byte_size = false; - [[fallthrough]]; - case DW_FORM_flag: - case DW_FORM_data1: - case DW_FORM_ref1: - case DW_FORM_sec_offset: - min_hash_data_byte_size += 1; - break; - - case DW_FORM_block2: - hash_data_has_fixed_byte_size = false; - [[fallthrough]]; - case DW_FORM_data2: - case DW_FORM_ref2: - min_hash_data_byte_size += 2; - break; - - case DW_FORM_block4: - hash_data_has_fixed_byte_size = false; - [[fallthrough]]; - case DW_FORM_data4: - case DW_FORM_ref4: - case DW_FORM_addr: - case DW_FORM_ref_addr: - case DW_FORM_strp: - min_hash_data_byte_size += 4; - break; - - case DW_FORM_data8: - case DW_FORM_ref8: - min_hash_data_byte_size += 8; - break; - } -} - -lldb::offset_t -DWARFMappedHash::Prologue::Read(const lldb_private::DataExtractor &data, - lldb::offset_t offset) { - ClearAtoms(); - - die_base_offset = data.GetU32(&offset); - - const uint32_t atom_count = data.GetU32(&offset); - if (atom_count == 0x00060003u) { - // Old format, deal with contents of old pre-release format. - while (data.GetU32(&offset)) { - /* do nothing */; - } - - // Hardcode to the only known value for now. - AppendAtom(eAtomTypeDIEOffset, DW_FORM_data4); - } else { - for (uint32_t i = 0; i < atom_count; ++i) { - AtomType type = (AtomType)data.GetU16(&offset); - dw_form_t form = (dw_form_t)data.GetU16(&offset); - AppendAtom(type, form); - } - } - return offset; -} - -size_t DWARFMappedHash::Prologue::GetByteSize() const { - // Add an extra count to the atoms size for the zero termination Atom that - // gets written to disk. - return sizeof(die_base_offset) + sizeof(uint32_t) + - atoms.size() * sizeof(Atom); -} - -size_t DWARFMappedHash::Prologue::GetMinimumHashDataByteSize() const { - return min_hash_data_byte_size; -} - -bool DWARFMappedHash::Prologue::HashDataHasFixedByteSize() const { - return hash_data_has_fixed_byte_size; -} - -size_t DWARFMappedHash::Header::GetByteSize(const HeaderData &header_data) { - return header_data.GetByteSize(); -} - -lldb::offset_t DWARFMappedHash::Header::Read(lldb_private::DataExtractor &data, - lldb::offset_t offset) { - offset = MappedHash::Header<Prologue>::Read(data, offset); - if (offset != UINT32_MAX) { - offset = header_data.Read(data, offset); - } - return offset; -} - -bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, - DIEInfo &hash_data) const { - const size_t num_atoms = header_data.atoms.size(); - if (num_atoms == 0) - return false; - - for (size_t i = 0; i < num_atoms; ++i) { - DWARFFormValue form_value(nullptr, header_data.atoms[i].form); - - if (!form_value.ExtractValue(data, offset_ptr)) - return false; - - switch (header_data.atoms[i].type) { - case eAtomTypeDIEOffset: // DIE offset, check form for encoding - hash_data.die_offset = - DWARFFormValue::IsDataForm(form_value.Form()) - ? form_value.Unsigned() - : form_value.Reference(header_data.die_base_offset); - break; - - case eAtomTypeTag: // DW_TAG value for the DIE - hash_data.tag = (dw_tag_t)form_value.Unsigned(); - break; - - case eAtomTypeTypeFlags: // Flags from enum TypeFlags - hash_data.type_flags = (uint32_t)form_value.Unsigned(); - break; - - case eAtomTypeQualNameHash: // Flags from enum TypeFlags - hash_data.qualified_name_hash = form_value.Unsigned(); - break; - - default: - // We can always skip atoms we don't know about. - break; - } - } - return hash_data.die_offset != DW_INVALID_OFFSET; -} - -DWARFMappedHash::MemoryTable::MemoryTable( - lldb_private::DWARFDataExtractor &table_data, - const lldb_private::DWARFDataExtractor &string_table, const char *name) - : MappedHash::MemoryTable<uint32_t, Header, DIEInfoArray>(table_data), - m_data(table_data), m_string_table(string_table), m_name(name) {} - -const char * -DWARFMappedHash::MemoryTable::GetStringForKeyType(KeyType key) const { - // The key in the DWARF table is the .debug_str offset for the string - return m_string_table.PeekCStr(key); -} - -bool DWARFMappedHash::MemoryTable::ReadHashData(uint32_t hash_data_offset, - HashData &hash_data) const { - lldb::offset_t offset = hash_data_offset; - // Skip string table offset that contains offset of hash name in .debug_str. - offset += 4; - const uint32_t count = m_data.GetU32(&offset); - if (count > 0) { - hash_data.resize(count); - for (uint32_t i = 0; i < count; ++i) { - if (!m_header.Read(m_data, &offset, hash_data[i])) - return false; - } - } else - hash_data.clear(); - return true; -} - -DWARFMappedHash::MemoryTable::Result -DWARFMappedHash::MemoryTable::GetHashDataForName( - llvm::StringRef name, lldb::offset_t *hash_data_offset_ptr, - Pair &pair) const { - pair.key = m_data.GetU32(hash_data_offset_ptr); - pair.value.clear(); - - // If the key is zero, this terminates our chain of HashData objects for this - // hash value. - if (pair.key == 0) - return eResultEndOfHashData; - - // There definitely should be a string for this string offset, if there - // isn't, there is something wrong, return and error. - const char *strp_cstr = m_string_table.PeekCStr(pair.key); - if (strp_cstr == nullptr) { - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } - - const uint32_t count = m_data.GetU32(hash_data_offset_ptr); - const size_t min_total_hash_data_size = - count * m_header.header_data.GetMinimumHashDataByteSize(); - if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr, - min_total_hash_data_size)) { - // We have at least one HashData entry, and we have enough data to parse at - // least "count" HashData entries. - - // First make sure the entire C string matches... - const bool match = name == strp_cstr; - - if (!match && m_header.header_data.HashDataHasFixedByteSize()) { - // If the string doesn't match and we have fixed size data, we can just - // add the total byte size of all HashData objects to the hash data - // offset and be done... - *hash_data_offset_ptr += min_total_hash_data_size; - } else { - // If the string does match, or we don't have fixed size data then we - // need to read the hash data as a stream. If the string matches we also - // append all HashData objects to the value array. - for (uint32_t i = 0; i < count; ++i) { - DIEInfo die_info; - if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) { - // Only happened if the HashData of the string matched... - if (match) - pair.value.push_back(die_info); - } else { - // Something went wrong while reading the data. - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } - } - } - // Return the correct response depending on if the string matched or not... - if (match) { - // The key (cstring) matches and we have lookup results! - return eResultKeyMatch; - } else { - // The key doesn't match, this function will get called again for the - // next key/value or the key terminator which in our case is a zero - // .debug_str offset. - return eResultKeyMismatch; - } - } else { - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } -} - -DWARFMappedHash::MemoryTable::Result -DWARFMappedHash::MemoryTable::AppendHashDataForRegularExpression( - const lldb_private::RegularExpression ®ex, - lldb::offset_t *hash_data_offset_ptr, Pair &pair) const { - pair.key = m_data.GetU32(hash_data_offset_ptr); - // If the key is zero, this terminates our chain of HashData objects for this - // hash value. - if (pair.key == 0) - return eResultEndOfHashData; - - // There definitely should be a string for this string offset, if there - // isn't, there is something wrong, return and error. - const char *strp_cstr = m_string_table.PeekCStr(pair.key); - if (strp_cstr == nullptr) - return eResultError; - - const uint32_t count = m_data.GetU32(hash_data_offset_ptr); - const size_t min_total_hash_data_size = - count * m_header.header_data.GetMinimumHashDataByteSize(); - if (count > 0 && m_data.ValidOffsetForDataOfSize(*hash_data_offset_ptr, - min_total_hash_data_size)) { - const bool match = regex.Execute(llvm::StringRef(strp_cstr)); - - if (!match && m_header.header_data.HashDataHasFixedByteSize()) { - // If the regex doesn't match and we have fixed size data, we can just - // add the total byte size of all HashData objects to the hash data - // offset and be done... - *hash_data_offset_ptr += min_total_hash_data_size; - } else { - // If the string does match, or we don't have fixed size data then we - // need to read the hash data as a stream. If the string matches we also - // append all HashData objects to the value array. - for (uint32_t i = 0; i < count; ++i) { - DIEInfo die_info; - if (m_header.Read(m_data, hash_data_offset_ptr, die_info)) { - // Only happened if the HashData of the string matched... - if (match) - pair.value.push_back(die_info); - } else { - // Something went wrong while reading the data - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } - } - } - // Return the correct response depending on if the string matched or not... - if (match) { - // The key (cstring) matches and we have lookup results! - return eResultKeyMatch; - } else { - // The key doesn't match, this function will get called again for the - // next key/value or the key terminator which in our case is a zero - // .debug_str offset. - return eResultKeyMismatch; - } - } else { - *hash_data_offset_ptr = UINT32_MAX; - return eResultError; - } -} - -void DWARFMappedHash::MemoryTable::AppendAllDIEsThatMatchingRegex( - const lldb_private::RegularExpression ®ex, - DIEInfoArray &die_info_array) const { - const uint32_t hash_count = m_header.hashes_count; - Pair pair; - for (uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) { - lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx); - while (hash_data_offset != UINT32_MAX) { - const lldb::offset_t prev_hash_data_offset = hash_data_offset; - Result hash_result = - AppendHashDataForRegularExpression(regex, &hash_data_offset, pair); - if (prev_hash_data_offset == hash_data_offset) - break; - - // Check the result of getting our hash data. - switch (hash_result) { - case eResultKeyMatch: - case eResultKeyMismatch: - // Whether we matches or not, it doesn't matter, we keep looking. - break; - - case eResultEndOfHashData: - case eResultError: - hash_data_offset = UINT32_MAX; - break; - } - } - } - die_info_array.swap(pair.value); -} - -void DWARFMappedHash::MemoryTable::AppendAllDIEsInRange( - const uint32_t die_offset_start, const uint32_t die_offset_end, - DIEInfoArray &die_info_array) const { - const uint32_t hash_count = m_header.hashes_count; - for (uint32_t offset_idx = 0; offset_idx < hash_count; ++offset_idx) { - bool done = false; - lldb::offset_t hash_data_offset = GetHashDataOffset(offset_idx); - while (!done && hash_data_offset != UINT32_MAX) { - KeyType key = m_data.GetU32(&hash_data_offset); - // If the key is zero, this terminates our chain of HashData objects for - // this hash value. - if (key == 0) - break; - - const uint32_t count = m_data.GetU32(&hash_data_offset); - for (uint32_t i = 0; i < count; ++i) { - DIEInfo die_info; - if (m_header.Read(m_data, &hash_data_offset, die_info)) { - if (die_info.die_offset == 0) - done = true; - if (die_offset_start <= die_info.die_offset && - die_info.die_offset < die_offset_end) - die_info_array.push_back(die_info); - } - } - } - } -} - -bool DWARFMappedHash::MemoryTable::FindByName( - llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback) { - if (name.empty()) - return true; - - DIEInfoArray die_info_array; - FindByName(name, die_info_array); - return DWARFMappedHash::ExtractDIEArray(die_info_array, callback); -} - -void DWARFMappedHash::MemoryTable::FindByNameAndTag( - llvm::StringRef name, const dw_tag_t tag, - llvm::function_ref<bool(DIERef ref)> callback) { - DIEInfoArray die_info_array; - FindByName(name, die_info_array); - DWARFMappedHash::ExtractDIEArray(die_info_array, tag, callback); -} - -void DWARFMappedHash::MemoryTable::FindByNameAndTagAndQualifiedNameHash( - llvm::StringRef name, const dw_tag_t tag, - const uint32_t qualified_name_hash, - llvm::function_ref<bool(DIERef ref)> callback) { - DIEInfoArray die_info_array; - FindByName(name, die_info_array); - DWARFMappedHash::ExtractDIEArray(die_info_array, tag, qualified_name_hash, - callback); -} - -void DWARFMappedHash::MemoryTable::FindCompleteObjCClassByName( - llvm::StringRef name, llvm::function_ref<bool(DIERef ref)> callback, - bool must_be_implementation) { - DIEInfoArray die_info_array; - FindByName(name, die_info_array); - if (must_be_implementation && - GetHeader().header_data.ContainsAtom(eAtomTypeTypeFlags)) { - // If we have two atoms, then we have the DIE offset and the type flags - // so we can find the objective C class efficiently. - DWARFMappedHash::ExtractTypesFromDIEArray( - die_info_array, UINT32_MAX, eTypeFlagClassIsImplementation, callback); - return; - } - // We don't only want the one true definition, so try and see what we can - // find, and only return class or struct DIEs. If we do have the full - // implementation, then return it alone, else return all possible - // matches. - bool found_implementation = false; - DWARFMappedHash::ExtractClassOrStructDIEArray( - die_info_array, true /*return_implementation_only_if_available*/, - [&](DIERef ref) { - found_implementation = true; - // Here the return value does not matter as we are called at most once. - return callback(ref); - }); - if (found_implementation) - return; - DWARFMappedHash::ExtractClassOrStructDIEArray( - die_info_array, false /*return_implementation_only_if_available*/, - callback); -} - -void DWARFMappedHash::MemoryTable::FindByName(llvm::StringRef name, - DIEInfoArray &die_info_array) { - if (name.empty()) - return; - - Pair kv_pair; - if (Find(name, kv_pair)) - die_info_array.swap(kv_pair.value); -} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h deleted file mode 100644 index 0006949865de..000000000000 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h +++ /dev/null @@ -1,201 +0,0 @@ -//===-- HashedNameToDIE.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_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H -#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H - -#include <vector> - -#include "lldb/Core/MappedHash.h" -#include "lldb/Core/dwarf.h" -#include "lldb/Utility/RegularExpression.h" -#include "lldb/lldb-defines.h" - -#include "DWARFDefines.h" -#include "DWARFFormValue.h" -#include "NameToDIE.h" - -class DWARFMappedHash { -public: - enum AtomType : uint16_t { - eAtomTypeNULL = 0u, - /// DIE offset, check form for encoding. - eAtomTypeDIEOffset = 1u, - /// DIE offset of the compiler unit header that contains the item in - /// question. - eAtomTypeCUOffset = 2u, - /// DW_TAG_xxx value, should be encoded as DW_FORM_data1 (if no tags exceed - /// 255) or DW_FORM_data2. - eAtomTypeTag = 3u, - // Flags from enum NameFlags. - eAtomTypeNameFlags = 4u, - // Flags from enum TypeFlags. - eAtomTypeTypeFlags = 5u, - /// A 32 bit hash of the full qualified name (since all hash entries are - /// basename only) For example a type like "std::vector<int>::iterator" - /// would have a name of "iterator" and a 32 bit hash for - /// "std::vector<int>::iterator" to allow us to not have to pull in debug - /// info for a type when we know the fully qualified name. - eAtomTypeQualNameHash = 6u - }; - - /// Bit definitions for the eAtomTypeTypeFlags flags. - enum TypeFlags { - /// Always set for C++, only set for ObjC if this is the - /// @implementation for class. - eTypeFlagClassIsImplementation = (1u << 1) - }; - - struct DIEInfo { - dw_offset_t die_offset = DW_INVALID_OFFSET; - dw_tag_t tag = llvm::dwarf::DW_TAG_null; - - /// Any flags for this DIEInfo. - uint32_t type_flags = 0; - - /// A 32 bit hash of the fully qualified name. - uint32_t qualified_name_hash = 0; - - DIEInfo() = default; - DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h); - - explicit operator DIERef() const { - return DIERef(std::nullopt, DIERef::Section::DebugInfo, die_offset); - } - }; - - struct Atom { - AtomType type; - dw_form_t form; - }; - - typedef std::vector<DIEInfo> DIEInfoArray; - typedef std::vector<Atom> AtomArray; - - class Prologue { - public: - Prologue(dw_offset_t _die_base_offset = 0); - - void ClearAtoms(); - - bool ContainsAtom(AtomType atom_type) const; - - void Clear(); - - void AppendAtom(AtomType type, dw_form_t form); - - lldb::offset_t Read(const lldb_private::DataExtractor &data, - lldb::offset_t offset); - - size_t GetByteSize() const; - - size_t GetMinimumHashDataByteSize() const; - - bool HashDataHasFixedByteSize() const; - - /// DIE offset base so die offsets in hash_data can be CU relative. - dw_offset_t die_base_offset; - AtomArray atoms; - uint32_t atom_mask = 0; - size_t min_hash_data_byte_size = 0; - bool hash_data_has_fixed_byte_size = true; - }; - - class Header : public MappedHash::Header<Prologue> { - public: - size_t GetByteSize(const HeaderData &header_data) override; - - lldb::offset_t Read(lldb_private::DataExtractor &data, - lldb::offset_t offset) override; - - bool Read(const lldb_private::DWARFDataExtractor &data, - lldb::offset_t *offset_ptr, DIEInfo &hash_data) const; - }; - - /// A class for reading and using a saved hash table from a block of data in - /// memory. - class MemoryTable - : public MappedHash::MemoryTable<uint32_t, DWARFMappedHash::Header, - DIEInfoArray> { - public: - MemoryTable(lldb_private::DWARFDataExtractor &table_data, - const lldb_private::DWARFDataExtractor &string_table, - const char *name); - - const char *GetStringForKeyType(KeyType key) const override; - - bool ReadHashData(uint32_t hash_data_offset, - HashData &hash_data) const override; - - void - AppendAllDIEsThatMatchingRegex(const lldb_private::RegularExpression ®ex, - DIEInfoArray &die_info_array) const; - - void AppendAllDIEsInRange(const uint32_t die_offset_start, - const uint32_t die_offset_end, - DIEInfoArray &die_info_array) const; - - bool FindByName(llvm::StringRef name, - llvm::function_ref<bool(DIERef ref)> callback); - - void FindByNameAndTag(llvm::StringRef name, const dw_tag_t tag, - llvm::function_ref<bool(DIERef ref)> callback); - - void FindByNameAndTagAndQualifiedNameHash( - llvm::StringRef name, const dw_tag_t tag, - const uint32_t qualified_name_hash, - llvm::function_ref<bool(DIERef ref)> callback); - - void - FindCompleteObjCClassByName(llvm::StringRef name, - llvm::function_ref<bool(DIERef ref)> callback, - bool must_be_implementation); - - protected: - Result AppendHashDataForRegularExpression( - const lldb_private::RegularExpression ®ex, - lldb::offset_t *hash_data_offset_ptr, Pair &pair) const; - - void FindByName(llvm::StringRef name, DIEInfoArray &die_info_array); - - Result GetHashDataForName(llvm::StringRef name, - lldb::offset_t *hash_data_offset_ptr, - Pair &pair) const override; - - lldb_private::DWARFDataExtractor m_data; - lldb_private::DWARFDataExtractor m_string_table; - std::string m_name; - }; - - static bool ExtractDIEArray(const DIEInfoArray &die_info_array, - llvm::function_ref<bool(DIERef ref)> callback); - -protected: - static void ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - llvm::function_ref<bool(DIERef ref)> callback); - - static void ExtractDIEArray(const DIEInfoArray &die_info_array, - const dw_tag_t tag, - const uint32_t qualified_name_hash, - llvm::function_ref<bool(DIERef ref)> callback); - - static void - ExtractClassOrStructDIEArray(const DIEInfoArray &die_info_array, - bool return_implementation_only_if_available, - llvm::function_ref<bool(DIERef ref)> callback); - - static void - ExtractTypesFromDIEArray(const DIEInfoArray &die_info_array, - uint32_t type_flag_mask, uint32_t type_flag_value, - llvm::function_ref<bool(DIERef ref)> callback); - - static const char *GetAtomTypeName(uint16_t atom); -}; - -#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_HASHEDNAMETODIE_H 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 a31622fc8b99..57b962ff60df 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -162,12 +162,13 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, // though as some functions have template parameter types and other things // that cause extra copies of types to be included, but we should find these // types in the .dwo file only as methods could have return types removed and - // we don't have to index incomplete types from the skeletone compile unit. + // we don't have to index incomplete types from the skeleton compile unit. if (unit.GetDWOId()) { + // Index the .dwo or dwp instead of the skeleton unit. if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) { // Type units in a dwp file are indexed separately, so we just need to - // process the split unit here. However, if the split unit is in a dwo file, - // then we need to process type units here. + // process the split unit here. However, if the split unit is in a dwo + // file, then we need to process type units here. if (dwo_symbol_file == dwp) { IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set); } else { @@ -175,11 +176,22 @@ void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set); } + return; } - } else { - // We either have a normal compile unit which we want to index. - IndexUnitImpl(unit, cu_language, set); + // This was a DWARF5 skeleton CU and the .dwo file couldn't be located. + if (unit.GetVersion() >= 5 && unit.IsSkeletonUnit()) + return; + + // Either this is a DWARF 4 + fission CU with the .dwo file + // missing, or it's a -gmodules pch or pcm. Try to detect the + // latter by checking whether the first DIE is a DW_TAG_module. + // If it's a pch/pcm, continue indexing it. + if (unit.GetDIE(unit.GetFirstDIEOffset()).GetFirstChild().Tag() != + llvm::dwarf::DW_TAG_module) + return; } + // We have a normal compile unit which we want to index. + IndexUnitImpl(unit, cu_language, set); } void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, @@ -196,6 +208,7 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, case DW_TAG_enumeration_type: case DW_TAG_inlined_subroutine: case DW_TAG_namespace: + case DW_TAG_imported_declaration: case DW_TAG_string_type: case DW_TAG_structure_type: case DW_TAG_subprogram: @@ -210,60 +223,58 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, continue; } - DWARFAttributes attributes; const char *name = nullptr; const char *mangled_cstr = nullptr; bool is_declaration = false; - // bool is_artificial = false; bool has_address = false; bool has_location_or_const_value = false; bool is_global_or_static_variable = false; DWARFFormValue specification_die_form; - const size_t num_attributes = die.GetAttributes(&unit, attributes); - if (num_attributes > 0) { - for (uint32_t i = 0; i < num_attributes; ++i) { - dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - switch (attr) { - case DW_AT_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - name = form_value.AsCString(); - break; - - case DW_AT_declaration: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - is_declaration = form_value.Unsigned() != 0; - break; - - case DW_AT_MIPS_linkage_name: - case DW_AT_linkage_name: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - mangled_cstr = form_value.AsCString(); - break; - - case DW_AT_low_pc: - case DW_AT_high_pc: - case DW_AT_ranges: - has_address = true; - break; - - case DW_AT_entry_pc: - has_address = true; - break; - - case DW_AT_location: - case DW_AT_const_value: - has_location_or_const_value = true; - is_global_or_static_variable = die.IsGlobalOrStaticScopeVariable(); - - break; - - case DW_AT_specification: - if (attributes.ExtractFormValueAtIndex(i, form_value)) - specification_die_form = form_value; - break; - } + DWARFAttributes attributes = die.GetAttributes(&unit); + for (size_t i = 0; i < attributes.Size(); ++i) { + dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + switch (attr) { + default: + break; + case DW_AT_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + name = form_value.AsCString(); + break; + + case DW_AT_declaration: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + is_declaration = form_value.Unsigned() != 0; + break; + + case DW_AT_MIPS_linkage_name: + case DW_AT_linkage_name: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + mangled_cstr = form_value.AsCString(); + break; + + case DW_AT_low_pc: + case DW_AT_high_pc: + case DW_AT_ranges: + has_address = true; + break; + + case DW_AT_entry_pc: + has_address = true; + break; + + case DW_AT_location: + case DW_AT_const_value: + has_location_or_const_value = true; + is_global_or_static_variable = die.IsGlobalOrStaticScopeVariable(); + + break; + + case DW_AT_specification: + if (attributes.ExtractFormValueAtIndex(i, form_value)) + specification_die_form = form_value; + break; } } @@ -276,15 +287,16 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, bool is_objc_method = false; if (cu_language == eLanguageTypeObjC || cu_language == eLanguageTypeObjC_plus_plus) { - ObjCLanguage::MethodName objc_method(name, true); - if (objc_method.IsValid(true)) { + std::optional<const ObjCLanguage::MethodName> objc_method = + ObjCLanguage::MethodName::Create(name, true); + if (objc_method) { is_objc_method = true; ConstString class_name_with_category( - objc_method.GetClassNameWithCategory()); - ConstString objc_selector_name(objc_method.GetSelector()); + objc_method->GetClassNameWithCategory()); + ConstString objc_selector_name(objc_method->GetSelector()); ConstString objc_fullname_no_category_name( - objc_method.GetFullNameWithoutCategory(true)); - ConstString class_name_no_category(objc_method.GetClassName()); + objc_method->GetFullNameWithoutCategory().c_str()); + ConstString class_name_no_category(objc_method->GetClassName()); set.function_fullnames.Insert(ConstString(name), ref); if (class_name_with_category) set.objc_class_selectors.Insert(class_name_with_category, ref); @@ -342,6 +354,7 @@ void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit, break; case DW_TAG_namespace: + case DW_TAG_imported_declaration: if (name) set.namespaces.Insert(ConstString(name), ref); break; @@ -387,7 +400,6 @@ void ManualDWARFIndex::GetGlobalVariables( void ManualDWARFIndex::GetGlobalVariables( DWARFUnit &unit, llvm::function_ref<bool(DWARFDIE die)> callback) { - lldbassert(!unit.GetSymbolFileDWARF().GetDwoNum()); Index(); m_set.globals.FindAllEntriesForUnit(unit, DIERefCallback(callback)); } @@ -525,7 +537,10 @@ enum DataID { kDataIDEnd = 255u, }; -constexpr uint32_t CURRENT_CACHE_VERSION = 1; + +// Version 2 changes the encoding of DIERef objects used in the DWARF manual +// index name tables. See DIERef class for details. +constexpr uint32_t CURRENT_CACHE_VERSION = 2; bool ManualDWARFIndex::IndexSet::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr) { 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 d6cee149f404..89e628f5eaf1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -50,12 +50,11 @@ bool NameToDIE::Find(const RegularExpression ®ex, void NameToDIE::FindAllEntriesForUnit( DWARFUnit &s_unit, llvm::function_ref<bool(DIERef ref)> callback) const { - lldbassert(!s_unit.GetSymbolFileDWARF().GetDwoNum()); const DWARFUnit &ns_unit = s_unit.GetNonSkeletonUnit(); const uint32_t size = m_map.GetSize(); for (uint32_t i = 0; i < size; ++i) { const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i); - if (ns_unit.GetSymbolFileDWARF().GetDwoNum() == die_ref.dwo_num() && + if (ns_unit.GetSymbolFileDWARF().GetFileIndex() == die_ref.file_index() && ns_unit.GetDebugSection() == die_ref.section() && ns_unit.GetOffset() <= die_ref.die_offset() && die_ref.die_offset() < ns_unit.GetNextUnitOffset()) { 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 544c9e08d504..6e5482dba9d2 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -125,8 +125,7 @@ public: } bool IgnoreFileIndexes() const { - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, ePropertyIgnoreIndexes, false); + return GetPropertyAtIndexAs<bool>(ePropertyIgnoreIndexes, false); } }; @@ -143,7 +142,7 @@ ParseLLVMLineTable(lldb_private::DWARFContext &context, dw_offset_t unit_offset) { Log *log = GetLog(DWARFLog::DebugInfo); - llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM(); + llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVMDWARF(); llvm::DWARFContext &ctx = context.GetAsLLVM(); llvm::Expected<const llvm::DWARFDebugLine::LineTable *> line_table = line.getOrParseLineTable( @@ -167,7 +166,7 @@ static bool ParseLLVMLineTablePrologue(lldb_private::DWARFContext &context, dw_offset_t unit_offset) { Log *log = GetLog(DWARFLog::DebugInfo); bool success = true; - llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVM(); + llvm::DWARFDataExtractor data = context.getOrLoadLineData().GetAsLLVMDWARF(); llvm::DWARFContext &ctx = context.GetAsLLVM(); uint64_t offset = line_offset; llvm::Error error = prologue.parse( @@ -251,8 +250,7 @@ void SymbolFileDWARF::DebuggerInitialize(Debugger &debugger) { const bool is_global_setting = true; PluginManager::CreateSettingForSymbolFilePlugin( debugger, GetGlobalPluginProperties().GetValueProperties(), - ConstString("Properties for the dwarf symbol-file plug-in."), - is_global_setting); + "Properties for the dwarf symbol-file plug-in.", is_global_setting); } } @@ -408,11 +406,8 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) { SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp, SectionList *dwo_section_list) - : SymbolFileCommon(std::move(objfile_sp)), - UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to - // when this class parses .o files to - // contain the .o file index/ID - m_debug_map_module_wp(), m_debug_map_symfile(nullptr), + : SymbolFileCommon(std::move(objfile_sp)), m_debug_map_module_wp(), + m_debug_map_symfile(nullptr), m_context(m_objfile_sp->GetModule()->GetSectionList(), dwo_section_list), m_fetched_external_modules(false), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} @@ -587,6 +582,14 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { } } + constexpr uint64_t MaxDebugInfoSize = (1ull) << DW_DIE_OFFSET_MAX_BITSIZE; + if (debug_info_file_size >= MaxDebugInfoSize) { + m_objfile_sp->GetModule()->ReportWarning( + "SymbolFileDWARF can't load this DWARF. It's larger then {0:x+16}", + MaxDebugInfoSize); + return 0; + } + if (debug_abbrev_file_size > 0 && debug_info_file_size > 0) abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes; @@ -827,7 +830,7 @@ 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(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to parse function"); + "Unable to parse function: {0}"); return nullptr; } auto ts = *type_system_or_err; @@ -837,9 +840,9 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, if (!dwarf_ast) return nullptr; - DWARFRangeList ranges; - if (die.GetDIE()->GetAttributeAddressRanges(die.GetCU(), ranges, - /*check_hi_lo_pc=*/true) == 0) + DWARFRangeList ranges = die.GetDIE()->GetAttributeAddressRanges( + die.GetCU(), /*check_hi_lo_pc=*/true); + if (ranges.IsEmpty()) return nullptr; // Union of all ranges in the function DIE (if the function is @@ -875,7 +878,7 @@ SymbolFileDWARF::ConstructFunctionDemangledName(const DWARFDIE &die) { auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to construct demangled name for function"); + "Unable to construct demangled name for function: {0}"); return ConstString(); } @@ -1055,14 +1058,15 @@ SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) { FileSpecList &list = iter_bool.first->second; if (iter_bool.second) { uint64_t line_table_offset = offset; - llvm::DWARFDataExtractor data = m_context.getOrLoadLineData().GetAsLLVM(); + llvm::DWARFDataExtractor data = + m_context.getOrLoadLineData().GetAsLLVMDWARF(); llvm::DWARFContext &ctx = m_context.GetAsLLVM(); llvm::DWARFDebugLine::Prologue prologue; auto report = [](llvm::Error error) { Log *log = GetLog(DWARFLog::DebugInfo); LLDB_LOG_ERROR(log, std::move(error), "SymbolFileDWARF::GetTypeUnitSupportFiles failed to parse " - "the line table prologue"); + "the line table prologue: {0}"); }; ElapsedTime elapsed(m_parse_time); llvm::Error error = prologue.parse(data, &line_table_offset, report, ctx); @@ -1279,12 +1283,12 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( const char *name = nullptr; const char *mangled_name = nullptr; - int decl_file = 0; - int decl_line = 0; - int decl_column = 0; - int call_file = 0; - int call_line = 0; - int call_column = 0; + std::optional<int> decl_file; + std::optional<int> decl_line; + std::optional<int> decl_column; + std::optional<int> call_file; + std::optional<int> call_line; + std::optional<int> call_column; if (die.GetDIENamesAndRanges(name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column, nullptr)) { @@ -1314,7 +1318,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( range.GetByteSize())); else { GetObjectFile()->GetModule()->ReportError( - "{0x:+8}: adding range [{1:x16}-{2:x16}) which has a base " + "{0:x8}: adding range [{1:x16}-{2:x16}) which has a base " "that is less than the function's low PC {3:x16}. Please file " "a bug and attach the file at the " "start of this error message", @@ -1327,16 +1331,18 @@ size_t SymbolFileDWARF::ParseBlocksRecursive( if (tag != DW_TAG_subprogram && (name != nullptr || mangled_name != nullptr)) { std::unique_ptr<Declaration> decl_up; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) + if (decl_file || decl_line || decl_column) decl_up = std::make_unique<Declaration>( - comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column); + comp_unit.GetSupportFiles().GetFileSpecAtIndex( + decl_file ? *decl_file : 0), + decl_line ? *decl_line : 0, decl_column ? *decl_column : 0); std::unique_ptr<Declaration> call_up; - if (call_file != 0 || call_line != 0 || call_column != 0) + if (call_file || call_line || call_column) call_up = std::make_unique<Declaration>( - comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file), - call_line, call_column); + comp_unit.GetSupportFiles().GetFileSpecAtIndex( + call_file ? *call_file : 0), + call_line ? *call_line : 0, call_column ? *call_column : 0); block->SetInlinedFunctionInfo(name, mangled_name, decl_up.get(), call_up.get()); @@ -1396,62 +1402,8 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) { decl_ctx); } -user_id_t SymbolFileDWARF::GetUID(DIERef ref) { - if (GetDebugMapSymfile()) - return GetID() | ref.die_offset(); - - 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; -} - -std::optional<SymbolFileDWARF::DecodedUID> -SymbolFileDWARF::DecodeUID(lldb::user_id_t uid) { - // This method can be called without going through the symbol vendor so we - // need to lock the module. - std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we - // must make sure we use the correct DWARF file when resolving things. On - // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple - // SymbolFileDWARF classes, one for each .o file. We can often end up with - // references to other DWARF objects and we must be ready to receive a - // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF - // instance. - if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) { - SymbolFileDWARF *dwarf = debug_map->GetSymbolFileByOSOIndex( - debug_map->GetOSOIndexFromUserID(uid)); - return DecodedUID{ - *dwarf, {std::nullopt, DIERef::Section::DebugInfo, dw_offset_t(uid)}}; - } - dw_offset_t die_offset = uid; - if (die_offset == DW_INVALID_OFFSET) - return std::nullopt; - - DIERef::Section section = - uid >> 63 ? DIERef::Section::DebugTypes : DIERef::Section::DebugInfo; - - std::optional<uint32_t> dwo_num; - bool dwo_valid = uid >> 62 & 1; - if (dwo_valid) - dwo_num = uid >> 32 & 0x3fffffff; - - return DecodedUID{*this, {dwo_num, section, die_offset}}; -} - DWARFDIE -SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { - // This method can be called without going through the symbol vendor so we - // need to lock the module. - std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - - std::optional<DecodedUID> decoded = DecodeUID(uid); - - if (decoded) - return decoded->dwarf.GetDIE(decoded->ref); - - return DWARFDIE(); -} +SymbolFileDWARF::GetDIE(lldb::user_id_t uid) { return GetDIE(DIERef(uid)); } CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { // This method can be called without going through the symbol vendor so we @@ -1685,23 +1637,48 @@ bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { lldb::ModuleSP SymbolFileDWARF::GetExternalModule(ConstString name) { UpdateExternalModuleListIfNeeded(); const auto &pos = m_external_type_modules.find(name); - if (pos != m_external_type_modules.end()) - return pos->second; - else + if (pos == m_external_type_modules.end()) return lldb::ModuleSP(); + return pos->second; } DWARFDIE SymbolFileDWARF::GetDIE(const DIERef &die_ref) { - if (die_ref.dwo_num()) { - SymbolFileDWARF *dwarf = *die_ref.dwo_num() == 0x3fffffff - ? m_dwp_symfile.get() - : this->DebugInfo() - .GetUnitAtIndex(*die_ref.dwo_num()) - ->GetDwoSymbolFile(); - return dwarf->DebugInfo().GetDIE(die_ref); + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + + SymbolFileDWARF *symbol_file = nullptr; + + // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we + // must make sure we use the correct DWARF file when resolving things. On + // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple + // SymbolFileDWARF classes, one for each .o file. We can often end up with + // references to other DWARF objects and we must be ready to receive a + // "lldb::user_id_t" that specifies a DIE from another SymbolFileDWARF + // instance. + std::optional<uint32_t> file_index = die_ref.file_index(); + if (file_index) { + if (SymbolFileDWARFDebugMap *debug_map = GetDebugMapSymfile()) { + symbol_file = debug_map->GetSymbolFileByOSOIndex(*file_index); // OSO case + if (symbol_file) + return symbol_file->DebugInfo().GetDIE(die_ref); + return DWARFDIE(); + } + + if (*file_index == DIERef::k_file_index_mask) + symbol_file = m_dwp_symfile.get(); // DWP case + else + symbol_file = this->DebugInfo() + .GetUnitAtIndex(*die_ref.file_index()) + ->GetDwoSymbolFile(); // DWO case + } else if (die_ref.die_offset() == DW_INVALID_OFFSET) { + return DWARFDIE(); } + if (symbol_file) + return symbol_file->GetDIE(die_ref); + return DebugInfo().GetDIE(die_ref); } @@ -2154,7 +2131,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( decl_ctx_type_system->GetMinimumLanguage(nullptr)); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to match namespace decl using TypeSystem"); + "Unable to match namespace decl using TypeSystem: {0}"); return false; } @@ -2222,8 +2199,14 @@ void SymbolFileDWARF::FindGlobalVariables( if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { CompilerDeclContext actual_parent_decl_ctx = dwarf_ast->GetDeclContextContainingUIDFromDWARF(die); + + /// If the actual namespace is inline (i.e., had a DW_AT_export_symbols) + /// and a child (possibly through other layers of inline namespaces) + /// of the namespace referred to by 'basename', allow the lookup to + /// succeed. if (!actual_parent_decl_ctx || - actual_parent_decl_ctx != parent_decl_ctx) + (actual_parent_decl_ctx != parent_decl_ctx && + !parent_decl_ctx.IsContainedInLookup(actual_parent_decl_ctx))) return true; } } @@ -2339,12 +2322,19 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, } bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext &decl_ctx, - const DWARFDIE &die) { + const DWARFDIE &die, + bool only_root_namespaces) { // If we have no parent decl context to match this DIE matches, and if the // parent decl context isn't valid, we aren't trying to look for any // particular decl context so any die matches. - if (!decl_ctx.IsValid()) + if (!decl_ctx.IsValid()) { + // ...But if we are only checking root decl contexts, confirm that the + // 'die' is a top-level context. + if (only_root_namespaces) + return die.GetParent().Tag() == dwarf::DW_TAG_compile_unit; + return true; + } if (die) { if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) { @@ -2647,7 +2637,8 @@ void SymbolFileDWARF::FindTypes( CompilerDeclContext SymbolFileDWARF::FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); Log *log = GetLog(DWARFLog::Lookups); @@ -2663,7 +2654,7 @@ SymbolFileDWARF::FindNamespace(ConstString name, return namespace_decl_ctx; m_index->GetNamespaces(name, [&](DWARFDIE die) { - if (!DIEInDeclContext(parent_decl_ctx, die)) + if (!DIEInDeclContext(parent_decl_ctx, die, only_root_namespaces)) return true; // The containing decl contexts don't match DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()); @@ -2972,8 +2963,8 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { if (log) { GetObjectFile()->GetModule()->LogMessage( log, - "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%" - "s, name='{0}')", + "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag={0}, " + "name='{1}')", DW_TAG_value_to_name(tag), die.GetName()); } @@ -2986,7 +2977,7 @@ SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(const DWARFDIE &die) { auto type_system_or_err = GetTypeSystemForLanguage(language); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Cannot get TypeSystem for language {}", + "Cannot get TypeSystem for language {1}: {0}", Language::GetNameForLanguageType(language)); } else { type_system = *type_system_or_err; @@ -3109,7 +3100,7 @@ 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(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to parse type"); + "Unable to parse type: {0}"); return {}; } auto ts = *type_system_or_err; @@ -3184,7 +3175,7 @@ size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) { return 0; size_t functions_added = 0; - const dw_offset_t function_die_offset = func.GetID(); + const dw_offset_t function_die_offset = DIERef(func.GetID()).die_offset(); DWARFDIE function_die = dwarf_cu->GetNonSkeletonUnit().GetDIE(function_die_offset); if (function_die) { @@ -3218,10 +3209,9 @@ size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { DWARFDIE function_die = GetDIE(sc.function->GetID()); dw_addr_t func_lo_pc = LLDB_INVALID_ADDRESS; - DWARFRangeList ranges; - if (function_die.GetDIE()->GetAttributeAddressRanges( - function_die.GetCU(), ranges, - /*check_hi_lo_pc=*/true)) + DWARFRangeList ranges = function_die.GetDIE()->GetAttributeAddressRanges( + function_die.GetCU(), /*check_hi_lo_pc=*/true); + if (!ranges.IsEmpty()) func_lo_pc = ranges.GetMinRangeBase(0); if (func_lo_pc != LLDB_INVALID_ADDRESS) { const size_t num_variables = @@ -3279,6 +3269,92 @@ VariableSP SymbolFileDWARF::ParseVariableDIECached(const SymbolContext &sc, return var_sp; } +/// Creates a DWARFExpressionList from an DW_AT_location form_value. +static DWARFExpressionList GetExprListFromAtLocation(DWARFFormValue form_value, + ModuleSP module, + const DWARFDIE &die, + const addr_t func_low_pc) { + if (DWARFFormValue::IsBlockForm(form_value.Form())) { + const DWARFDataExtractor &data = die.GetData(); + + uint32_t block_offset = form_value.BlockData() - data.GetDataStart(); + uint32_t block_length = form_value.Unsigned(); + return DWARFExpressionList( + module, DataExtractor(data, block_offset, block_length), die.GetCU()); + } + + DWARFExpressionList location_list(module, DWARFExpression(), die.GetCU()); + DataExtractor data = die.GetCU()->GetLocationData(); + dw_offset_t offset = form_value.Unsigned(); + if (form_value.Form() == DW_FORM_loclistx) + offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1); + if (data.ValidOffset(offset)) { + data = DataExtractor(data, offset, data.GetByteSize() - offset); + const DWARFUnit *dwarf_cu = form_value.GetUnit(); + if (DWARFExpression::ParseDWARFLocationList(dwarf_cu, data, &location_list)) + location_list.SetFuncFileAddress(func_low_pc); + } + + return location_list; +} + +/// Creates a DWARFExpressionList from an DW_AT_const_value. This is either a +/// block form, or a string, or a data form. For data forms, this returns an +/// empty list, as we cannot initialize it properly without a SymbolFileType. +static DWARFExpressionList +GetExprListFromAtConstValue(DWARFFormValue form_value, ModuleSP module, + const DWARFDIE &die) { + const DWARFDataExtractor &debug_info_data = die.GetData(); + if (DWARFFormValue::IsBlockForm(form_value.Form())) { + // Retrieve the value as a block expression. + uint32_t block_offset = + form_value.BlockData() - debug_info_data.GetDataStart(); + uint32_t block_length = form_value.Unsigned(); + return DWARFExpressionList( + module, DataExtractor(debug_info_data, block_offset, block_length), + die.GetCU()); + } + if (const char *str = form_value.AsCString()) + return DWARFExpressionList(module, + DataExtractor(str, strlen(str) + 1, + die.GetCU()->GetByteOrder(), + die.GetCU()->GetAddressByteSize()), + die.GetCU()); + return DWARFExpressionList(module, DWARFExpression(), die.GetCU()); +} + +/// Global variables that are not initialized may have their address set to +/// zero. Since multiple variables may have this address, we cannot apply the +/// OSO relink address approach we normally use. +/// However, the executable will have a matching symbol with a good address; +/// this function attempts to find the correct address by looking into the +/// executable's symbol table. If it succeeds, the expr_list is updated with +/// the new address and the executable's symbol is returned. +static Symbol *fixupExternalAddrZeroVariable( + SymbolFileDWARFDebugMap &debug_map_symfile, llvm::StringRef name, + DWARFExpressionList &expr_list, const DWARFDIE &die) { + ObjectFile *debug_map_objfile = debug_map_symfile.GetObjectFile(); + if (!debug_map_objfile) + return nullptr; + + Symtab *debug_map_symtab = debug_map_objfile->GetSymtab(); + if (!debug_map_symtab) + return nullptr; + Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType( + ConstString(name), eSymbolTypeData, Symtab::eDebugYes, + Symtab::eVisibilityExtern); + if (!exe_symbol || !exe_symbol->ValueIsAddress()) + return nullptr; + const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress(); + if (exe_file_addr == LLDB_INVALID_ADDRESS) + return nullptr; + + DWARFExpression *location = expr_list.GetMutableExpressionAtAddress(); + if (location->Update_DW_OP_addr(die.GetCU(), exe_file_addr)) + return exe_symbol; + return nullptr; +} + VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, const DWARFDIE &die, const lldb::addr_t func_low_pc) { @@ -3295,19 +3371,17 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, (tag != DW_TAG_formal_parameter || !sc.function)) return nullptr; - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); + DWARFAttributes attributes = die.GetAttributes(); const char *name = nullptr; const char *mangled = nullptr; Declaration decl; DWARFFormValue type_die_form; - DWARFExpressionList location_list(module, DWARFExpression(), die.GetCU()); bool is_external = false; bool is_artificial = false; DWARFFormValue const_value_form, location_form; Variable::RangeList scope_ranges; - for (size_t i = 0; i < num_attributes; ++i) { + for (size_t i = 0; i < attributes.Size(); ++i) { dw_attr_t attr = attributes.AttributeAtIndex(i); DWARFFormValue form_value; @@ -3366,57 +3440,16 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, // for static constexpr member variables -- DW_AT_const_value will be // present in the class declaration and DW_AT_location in the DIE defining // the member. - bool location_is_const_value_data = false; - bool has_explicit_location = location_form.IsValid(); - bool use_type_size_for_value = false; - if (location_form.IsValid()) { - if (DWARFFormValue::IsBlockForm(location_form.Form())) { - const DWARFDataExtractor &data = die.GetData(); - - uint32_t block_offset = location_form.BlockData() - data.GetDataStart(); - uint32_t block_length = location_form.Unsigned(); - location_list = DWARFExpressionList( - module, DataExtractor(data, block_offset, block_length), die.GetCU()); - } else { - DataExtractor data = die.GetCU()->GetLocationData(); - dw_offset_t offset = location_form.Unsigned(); - if (location_form.Form() == DW_FORM_loclistx) - offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1); - if (data.ValidOffset(offset)) { - data = DataExtractor(data, offset, data.GetByteSize() - offset); - const DWARFUnit *dwarf_cu = location_form.GetUnit(); - if (DWARFExpression::ParseDWARFLocationList(dwarf_cu, data, - &location_list)) - location_list.SetFuncFileAddress(func_low_pc); - } - } - } else if (const_value_form.IsValid()) { - location_is_const_value_data = true; - // The constant value will be either a block, a data value or a - // string. - const DWARFDataExtractor &debug_info_data = die.GetData(); - if (DWARFFormValue::IsBlockForm(const_value_form.Form())) { - // Retrieve the value as a block expression. - uint32_t block_offset = - const_value_form.BlockData() - debug_info_data.GetDataStart(); - uint32_t block_length = const_value_form.Unsigned(); - location_list = DWARFExpressionList( - module, DataExtractor(debug_info_data, block_offset, block_length), - die.GetCU()); - } else if (DWARFFormValue::IsDataForm(const_value_form.Form())) { - // Constant value size does not have to match the size of the - // variable. We will fetch the size of the type after we create - // it. - use_type_size_for_value = true; - } else if (const char *str = const_value_form.AsCString()) { - uint32_t string_length = strlen(str) + 1; - location_list = DWARFExpressionList( - module, - DataExtractor(str, string_length, die.GetCU()->GetByteOrder(), - die.GetCU()->GetAddressByteSize()), - die.GetCU()); - } - } + bool location_is_const_value_data = + const_value_form.IsValid() && !location_form.IsValid(); + + DWARFExpressionList location_list = [&] { + if (location_form.IsValid()) + return GetExprListFromAtLocation(location_form, module, die, func_low_pc); + if (const_value_form.IsValid()) + return GetExprListFromAtConstValue(const_value_form, module, die); + return DWARFExpressionList(module, DWARFExpression(), die.GetCU()); + }(); const DWARFDIE parent_context_die = GetDeclContextDIEContainingDIE(die); const DWARFDIE sc_parent_die = GetParentSymbolContextDIE(die); @@ -3459,6 +3492,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, // Clang likes to combine small global variables into the same symbol // with locations like: DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus // so we need to look through the whole expression. + bool has_explicit_location = location_form.IsValid(); bool is_static_lifetime = has_explicit_mangled || (has_explicit_location && !location_list.IsValid()); @@ -3468,8 +3502,8 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, bool op_error = false; const DWARFExpression* location = location_list.GetAlwaysValidExpr(); if (location) - location_DW_OP_addr = location->GetLocation_DW_OP_addr( - location_form.GetUnit(), 0, op_error); + location_DW_OP_addr = + location->GetLocation_DW_OP_addr(location_form.GetUnit(), op_error); if (op_error) { StreamString strm; location->DumpLocation(&strm, eDescriptionLevelFull, nullptr); @@ -3494,49 +3528,14 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, scope = eValueTypeVariableStatic; if (debug_map_symfile) { - // When leaving the DWARF in the .o files on darwin, when we have a - // global variable that wasn't initialized, the .o file might not - // have allocated a virtual address for the global variable. In - // this case it will have created a symbol for the global variable - // that is undefined/data and external and the value will be the - // byte size of the variable. When we do the address map in - // SymbolFileDWARFDebugMap we rely on having an address, we need to - // do some magic here so we can get the correct address for our - // global variable. The address for all of these entries will be - // zero, and there will be an undefined symbol in this object file, - // and the executable will have a matching symbol with a good - // address. So here we dig up the correct address and replace it in - // the location for the variable, and set the variable's symbol - // context scope to be that of the main executable so the file - // address will resolve correctly. bool linked_oso_file_addr = false; + if (is_external && location_DW_OP_addr == 0) { - // we have a possible uninitialized extern global - ConstString const_name(mangled ? mangled : name); - ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile(); - if (debug_map_objfile) { - Symtab *debug_map_symtab = debug_map_objfile->GetSymtab(); - if (debug_map_symtab) { - Symbol *exe_symbol = - debug_map_symtab->FindFirstSymbolWithNameAndType( - const_name, eSymbolTypeData, Symtab::eDebugYes, - Symtab::eVisibilityExtern); - if (exe_symbol) { - if (exe_symbol->ValueIsAddress()) { - const addr_t exe_file_addr = - exe_symbol->GetAddressRef().GetFileAddress(); - if (exe_file_addr != LLDB_INVALID_ADDRESS) { - DWARFExpression *location = - location_list.GetMutableExpressionAtAddress(); - if (location->Update_DW_OP_addr(die.GetCU(), - exe_file_addr)) { - linked_oso_file_addr = true; - symbol_context_scope = exe_symbol; - } - } - } - } - } + if (Symbol *exe_symbol = fixupExternalAddrZeroVariable( + *debug_map_symfile, mangled ? mangled : name, location_list, + die)) { + linked_oso_file_addr = true; + symbol_context_scope = exe_symbol; } } @@ -3606,8 +3605,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, } auto type_sp = std::make_shared<SymbolFileType>( - *this, GetUID(type_die_form.Reference())); + *this, type_die_form.Reference().GetID()); + bool use_type_size_for_value = + location_is_const_value_data && + DWARFFormValue::IsDataForm(const_value_form.Form()); if (use_type_size_for_value && type_sp->GetType()) { DWARFExpression *location = location_list.GetMutableExpressionAtAddress(); location->UpdateValue(const_value_form.Unsigned(), @@ -3905,8 +3907,7 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { std::optional<DWARFExpressionList> LocationInCallee; std::optional<DWARFExpressionList> LocationInCaller; - DWARFAttributes attributes; - const size_t num_attributes = child.GetAttributes(attributes); + DWARFAttributes attributes = child.GetAttributes(); // Parse the location at index \p attr_index within this call site parameter // DIE, or return std::nullopt on failure. @@ -3925,7 +3926,7 @@ CollectCallSiteParameters(ModuleSP module, DWARFDIE call_site_die) { child.GetCU()); }; - for (size_t i = 0; i < num_attributes; ++i) { + for (size_t i = 0; i < attributes.Size(); ++i) { dw_attr_t attr = attributes.AttributeAtIndex(i); if (attr == DW_AT_location) LocationInCallee = parse_simple_location(i); @@ -3976,10 +3977,8 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { // Second DW_AT_low_pc may come from DW_TAG_subprogram referenced by // DW_TAG_GNU_call_site's DW_AT_abstract_origin overwriting our 'low_pc'. // So do not inherit attributes from DW_AT_abstract_origin. - DWARFAttributes attributes; - const size_t num_attributes = - child.GetAttributes(attributes, DWARFDIE::Recurse::no); - for (size_t i = 0; i < num_attributes; ++i) { + DWARFAttributes attributes = child.GetAttributes(DWARFDIE::Recurse::no); + for (size_t i = 0; i < attributes.Size(); ++i) { DWARFFormValue form_value; if (!attributes.ExtractFormValueAtIndex(i, form_value)) { LLDB_LOG(log, "CollectCallEdges: Could not extract TAG_call_site form"); @@ -4102,7 +4101,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { } std::vector<std::unique_ptr<lldb_private::CallEdge>> -SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { +SymbolFileDWARF::ParseCallEdgesInFunction(lldb_private::UserID func_id) { // ParseCallEdgesInFunction must be called at the behest of an exclusively // locked lldb::Function instance. Storage for parsed call edges is owned by // the lldb::Function instance: locking at the SymbolFile level would be too @@ -4160,8 +4159,8 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() { dwp_file_data_offset); if (!dwp_obj_file) return; - m_dwp_symfile = - std::make_shared<SymbolFileDWARFDwo>(*this, dwp_obj_file, 0x3fffffff); + m_dwp_symfile = std::make_shared<SymbolFileDWARFDwo>( + *this, dwp_obj_file, DIERef::k_file_index_mask); } }); return m_dwp_symfile; @@ -4176,7 +4175,7 @@ DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) { auto type_system_or_err = GetTypeSystem(unit); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to get DWARFASTParser"); + "Unable to get DWARFASTParser: {0}"); return nullptr; } if (auto ts = *type_system_or_err) @@ -4217,8 +4216,6 @@ LanguageType SymbolFileDWARF::LanguageTypeFromDWARF(uint64_t val) { switch (val) { case DW_LANG_Mips_Assembler: return eLanguageTypeMipsAssembler; - case DW_LANG_GOOGLE_RenderScript: - return eLanguageTypeExtRenderScript; default: return static_cast<LanguageType>(val); } @@ -4272,3 +4269,29 @@ Status SymbolFileDWARF::CalculateFrameVariableError(StackFrame &frame) { return Status("no variable information is available in debug info for this " "compile unit"); } + +void SymbolFileDWARF::GetCompileOptions( + std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) { + + const uint32_t num_compile_units = GetNumCompileUnits(); + + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) { + lldb::CompUnitSP comp_unit = GetCompileUnitAtIndex(cu_idx); + if (!comp_unit) + continue; + + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit.get()); + if (!dwarf_cu) + continue; + + const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly(); + if (!die) + continue; + + const char *flags = die.GetAttributeValueAsString(DW_AT_APPLE_flags, NULL); + + if (!flags) + continue; + args.insert({comp_unit, Args(flags)}); + } +} 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 f4dd9dffdb30..191a5abcf265 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -40,8 +40,6 @@ // Forward Declarations for this DWARF plugin class DebugMapModule; -class DWARFAbbreviationDeclaration; -class DWARFAbbreviationDeclarationSet; class DWARFCompileUnit; class DWARFDebugAbbrev; class DWARFDebugAranges; @@ -55,11 +53,11 @@ class DWARFTypeUnit; class SymbolFileDWARFDebugMap; class SymbolFileDWARFDwo; class SymbolFileDWARFDwp; +class UserID; #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) -class SymbolFileDWARF : public lldb_private::SymbolFileCommon, - public lldb_private::UserID { +class SymbolFileDWARF : public lldb_private::SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -214,9 +212,10 @@ public: llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(lldb::LanguageType language) override; - lldb_private::CompilerDeclContext FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext &parent_decl_ctx) override; + lldb_private::CompilerDeclContext + FindNamespace(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; void PreloadSymbols() override; @@ -265,31 +264,19 @@ public: DWARFDIE GetDIE(lldb::user_id_t uid); - lldb::user_id_t GetUID(const DWARFBaseDIE &die) { - return GetUID(die.GetDIERef()); - } - - lldb::user_id_t GetUID(const std::optional<DIERef> &ref) { - return ref ? GetUID(*ref) : LLDB_INVALID_UID; - } - - lldb::user_id_t GetUID(DIERef ref); - std::shared_ptr<SymbolFileDWARFDwo> GetDwoSymbolFileForCompileUnit(DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die); - virtual std::optional<uint32_t> GetDwoNum() { return std::nullopt; } - /// If this is a DWARF object with a single CU, return its DW_AT_dwo_id. std::optional<uint64_t> GetDWOId(); static bool DIEInDeclContext(const lldb_private::CompilerDeclContext &parent_decl_ctx, - const DWARFDIE &die); + const DWARFDIE &die, bool only_root_namespaces = false); std::vector<std::unique_ptr<lldb_private::CallEdge>> - ParseCallEdgesInFunction(UserID func_id) override; + ParseCallEdgesInFunction(lldb_private::UserID func_id) override; void Dump(lldb_private::Stream &s) override; @@ -347,6 +334,11 @@ public: lldb_private::ConstString ConstructFunctionDemangledName(const DWARFDIE &die); + std::optional<uint64_t> GetFileIndex() const { return m_file_index; } + void SetFileIndex(std::optional<uint64_t> file_index) { + m_file_index = file_index; + } + protected: typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; @@ -521,12 +513,6 @@ protected: void BuildCuTranslationTable(); std::optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx); - struct DecodedUID { - SymbolFileDWARF &dwarf; - DIERef ref; - }; - std::optional<DecodedUID> DecodeUID(lldb::user_id_t uid); - void FindDwpSymbolFile(); const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu); @@ -536,6 +522,9 @@ protected: void InitializeFirstCodeAddress(); + void GetCompileOptions( + std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) override; + lldb::ModuleWP m_debug_map_module_wp; SymbolFileDWARFDebugMap *m_debug_map_symfile; @@ -580,6 +569,11 @@ protected: 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; + /// If this DWARF file a .DWO file or a DWARF .o file on mac when + /// no dSYM file is being used, this file index will be set to a + /// valid value that can be used in DIERef objects which will contain + /// an index that identifies the .DWO or .o file. + std::optional<uint64_t> m_file_index; }; #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 aeacf55896e0..bb66fbadfb64 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -32,6 +32,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/VariableList.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/ScopedPrinter.h" #include "lldb/Target/StackFrame.h" @@ -211,7 +212,7 @@ public: // Set the ID of the symbol file DWARF to the index of the OSO // shifted left by 32 bits to provide a unique prefix for any // UserID's that get created in the symbol file. - oso_symfile->SetID(((uint64_t)m_cu_idx + 1ull) << 32ull); + oso_symfile->SetFileIndex((uint64_t)m_cu_idx); } return symfile; } @@ -286,112 +287,105 @@ void SymbolFileDWARFDebugMap::InitOSO() { // we return the abilities of the first N_OSO's DWARF. Symtab *symtab = m_objfile_sp->GetSymtab(); - if (symtab) { - Log *log = GetLog(DWARFLog::DebugMap); - - std::vector<uint32_t> oso_indexes; - // When a mach-o symbol is encoded, the n_type field is encoded in bits - // 23:16, and the n_desc field is encoded in bits 15:0. - // - // To find all N_OSO entries that are part of the DWARF + debug map we find - // only object file symbols with the flags value as follows: bits 23:16 == - // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object - // file) - const uint32_t k_oso_symbol_flags_value = 0x660001u; - - const uint32_t oso_index_count = - symtab->AppendSymbolIndexesWithTypeAndFlagsValue( - eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); - - if (oso_index_count > 0) { - symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, - Symtab::eVisibilityAny, - m_func_indexes); - symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes, - Symtab::eVisibilityAny, - m_glob_indexes); - - symtab->SortSymbolIndexesByValue(m_func_indexes, true); - symtab->SortSymbolIndexesByValue(m_glob_indexes, true); - - for (uint32_t sym_idx : m_func_indexes) { - const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); - lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); - lldb::addr_t byte_size = symbol->GetByteSize(); - DebugMap::Entry debug_map_entry( - file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); - m_debug_map.Append(debug_map_entry); - } - for (uint32_t sym_idx : m_glob_indexes) { - const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); - lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); - lldb::addr_t byte_size = symbol->GetByteSize(); - DebugMap::Entry debug_map_entry( - file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); - m_debug_map.Append(debug_map_entry); - } - m_debug_map.Sort(); - - m_compile_unit_infos.resize(oso_index_count); - - for (uint32_t i = 0; i < oso_index_count; ++i) { - const uint32_t so_idx = oso_indexes[i] - 1; - const uint32_t oso_idx = oso_indexes[i]; - const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); - const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); - if (so_symbol && oso_symbol && - so_symbol->GetType() == eSymbolTypeSourceFile && - oso_symbol->GetType() == eSymbolTypeObjectFile) { - m_compile_unit_infos[i].so_file.SetFile( - so_symbol->GetName().AsCString(), FileSpec::Style::native); - m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); - m_compile_unit_infos[i].oso_mod_time = - llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0)); - uint32_t sibling_idx = so_symbol->GetSiblingIndex(); - // The sibling index can't be less that or equal to the current index - // "i" - if (sibling_idx == UINT32_MAX) { - m_objfile_sp->GetModule()->ReportError( - "N_SO in symbol with UID {0} has invalid sibling in debug " - "map, " - "please file a bug and attach the binary listed in this error", - so_symbol->GetID()); - } else { - const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1); - m_compile_unit_infos[i].first_symbol_index = so_idx; - m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; - m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); - m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); - - LLDB_LOGF(log, "Initialized OSO 0x%8.8x: file=%s", i, - oso_symbol->GetName().GetCString()); - } - } else { - if (oso_symbol == nullptr) - m_objfile_sp->GetModule()->ReportError( - "N_OSO symbol[{0}] can't be found, please file a bug and " - "attach " - "the binary listed in this error", - oso_idx); - else if (so_symbol == nullptr) - m_objfile_sp->GetModule()->ReportError( - "N_SO not found for N_OSO symbol[{0}], please file a bug and " - "attach the binary listed in this error", - oso_idx); - else if (so_symbol->GetType() != eSymbolTypeSourceFile) - m_objfile_sp->GetModule()->ReportError( - "N_SO has incorrect symbol type ({0}) for N_OSO " - "symbol[{1}], " - "please file a bug and attach the binary listed in this error", - so_symbol->GetType(), oso_idx); - else if (oso_symbol->GetType() != eSymbolTypeSourceFile) - m_objfile_sp->GetModule()->ReportError( - "N_OSO has incorrect symbol type ({0}) for N_OSO " - "symbol[{1}], " - "please file a bug and attach the binary listed in this error", - oso_symbol->GetType(), oso_idx); - } + if (!symtab) + return; + + Log *log = GetLog(DWARFLog::DebugMap); + + std::vector<uint32_t> oso_indexes; + // When a mach-o symbol is encoded, the n_type field is encoded in bits + // 23:16, and the n_desc field is encoded in bits 15:0. + // + // To find all N_OSO entries that are part of the DWARF + debug map we find + // only object file symbols with the flags value as follows: bits 23:16 == + // 0x66 (N_OSO) bits 15: 0 == 0x0001 (specifies this is a debug map object + // file) + const uint32_t k_oso_symbol_flags_value = 0x660001u; + + const uint32_t oso_index_count = + symtab->AppendSymbolIndexesWithTypeAndFlagsValue( + eSymbolTypeObjectFile, k_oso_symbol_flags_value, oso_indexes); + + if (oso_index_count == 0) + return; + + symtab->AppendSymbolIndexesWithType(eSymbolTypeCode, Symtab::eDebugYes, + Symtab::eVisibilityAny, m_func_indexes); + symtab->AppendSymbolIndexesWithType(eSymbolTypeData, Symtab::eDebugYes, + Symtab::eVisibilityAny, m_glob_indexes); + + symtab->SortSymbolIndexesByValue(m_func_indexes, true); + symtab->SortSymbolIndexesByValue(m_glob_indexes, true); + + for (uint32_t sym_idx : + llvm::concat<uint32_t>(m_func_indexes, m_glob_indexes)) { + const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); + lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); + lldb::addr_t byte_size = symbol->GetByteSize(); + DebugMap::Entry debug_map_entry(file_addr, byte_size, + OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); + m_debug_map.Append(debug_map_entry); + } + m_debug_map.Sort(); + + m_compile_unit_infos.resize(oso_index_count); + + for (uint32_t i = 0; i < oso_index_count; ++i) { + const uint32_t so_idx = oso_indexes[i] - 1; + const uint32_t oso_idx = oso_indexes[i]; + const Symbol *so_symbol = symtab->SymbolAtIndex(so_idx); + const Symbol *oso_symbol = symtab->SymbolAtIndex(oso_idx); + if (so_symbol && oso_symbol && + so_symbol->GetType() == eSymbolTypeSourceFile && + oso_symbol->GetType() == eSymbolTypeObjectFile) { + m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), + FileSpec::Style::native); + m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); + m_compile_unit_infos[i].oso_mod_time = + llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0)); + uint32_t sibling_idx = so_symbol->GetSiblingIndex(); + // The sibling index can't be less that or equal to the current index + // "i" + if (sibling_idx <= i || sibling_idx == UINT32_MAX) { + m_objfile_sp->GetModule()->ReportError( + "N_SO in symbol with UID {0} has invalid sibling in debug " + "map, " + "please file a bug and attach the binary listed in this error", + so_symbol->GetID()); + } else { + const Symbol *last_symbol = symtab->SymbolAtIndex(sibling_idx - 1); + m_compile_unit_infos[i].first_symbol_index = so_idx; + m_compile_unit_infos[i].last_symbol_index = sibling_idx - 1; + m_compile_unit_infos[i].first_symbol_id = so_symbol->GetID(); + m_compile_unit_infos[i].last_symbol_id = last_symbol->GetID(); + + LLDB_LOGF(log, "Initialized OSO 0x%8.8x: file=%s", i, + oso_symbol->GetName().GetCString()); } + } else { + if (oso_symbol == nullptr) + m_objfile_sp->GetModule()->ReportError( + "N_OSO symbol[{0}] can't be found, please file a bug and " + "attach " + "the binary listed in this error", + oso_idx); + else if (so_symbol == nullptr) + m_objfile_sp->GetModule()->ReportError( + "N_SO not found for N_OSO symbol[{0}], please file a bug and " + "attach the binary listed in this error", + oso_idx); + else if (so_symbol->GetType() != eSymbolTypeSourceFile) + m_objfile_sp->GetModule()->ReportError( + "N_SO has incorrect symbol type ({0}) for N_OSO " + "symbol[{1}], " + "please file a bug and attach the binary listed in this error", + so_symbol->GetType(), oso_idx); + else if (oso_symbol->GetType() != eSymbolTypeSourceFile) + m_objfile_sp->GetModule()->ReportError( + "N_OSO has incorrect symbol type ({0}) for N_OSO " + "symbol[{1}], " + "please file a bug and attach the binary listed in this error", + oso_symbol->GetType(), oso_idx); } } } @@ -471,18 +465,17 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( oso_arch, oso_object ? &oso_object : nullptr, 0, oso_object ? comp_unit_info->oso_mod_time : llvm::sys::TimePoint<>()); - if (!comp_unit_info->oso_sp->module_sp || !comp_unit_info->oso_sp->module_sp->GetObjectFile()) { - if (oso_object && FileSystem::Instance().Exists(oso_file)) { - // If we are loading a .o file from a .a file the "oso_object" will - // have a valid value name and if the .a file exists, either the .o - // file didn't exist in the .a file or the mod time didn't match. - comp_unit_info->oso_load_error.SetErrorStringWithFormat( - "\"%s\" object from the \"%s\" archive: " - "either the .o file doesn't exist in the archive or the " - "modification time (0x%8.8x) of the .o file doesn't match", - oso_object.AsCString(), oso_file.GetPath().c_str(), - (uint32_t)llvm::sys::toTimeT(comp_unit_info->oso_mod_time)); - } + if (oso_object && !comp_unit_info->oso_sp->module_sp->GetObjectFile() && + FileSystem::Instance().Exists(oso_file)) { + // If we are loading a .o file from a .a file the "oso_object" will + // have a valid value name and if the .a file exists, either the .o + // file didn't exist in the .a file or the mod time didn't match. + comp_unit_info->oso_load_error.SetErrorStringWithFormat( + "\"%s\" object from the \"%s\" archive: " + "either the .o file doesn't exist in the archive or the " + "modification time (0x%8.8x) of the .o file doesn't match", + oso_object.AsCString(), oso_file.GetPath().c_str(), + (uint32_t)llvm::sys::toTimeT(comp_unit_info->oso_mod_time)); } } } @@ -683,6 +676,17 @@ XcodeSDK SymbolFileDWARFDebugMap::ParseXcodeSDK(CompileUnit &comp_unit) { return {}; } +llvm::SmallSet<lldb::LanguageType, 4> +SymbolFileDWARFDebugMap::ParseAllLanguages( + lldb_private::CompileUnit &comp_unit) { + llvm::SmallSet<lldb::LanguageType, 4> langs; + auto *info = GetCompUnitInfo(comp_unit); + for (auto &comp_unit : info->compile_units_sps) { + langs.insert(comp_unit->GetLanguage()); + } + return langs; +} + size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); @@ -1121,7 +1125,8 @@ void SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, } std::vector<std::unique_ptr<lldb_private::CallEdge>> -SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) { +SymbolFileDWARFDebugMap::ParseCallEdgesInFunction( + lldb_private::UserID func_id) { uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID()); SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); if (oso_dwarf) @@ -1244,13 +1249,14 @@ void SymbolFileDWARFDebugMap::FindTypes( } CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( - lldb_private::ConstString name, - const CompilerDeclContext &parent_decl_ctx) { + lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); CompilerDeclContext matching_namespace; ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx); + matching_namespace = + oso_dwarf->FindNamespace(name, parent_decl_ctx, only_root_namespaces); return (bool)matching_namespace; }); @@ -1468,7 +1474,8 @@ SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data, for (size_t idx = 0; idx < file_range_map.GetSize(); idx++) { const FileRangeMap::Entry *entry = file_range_map.GetEntryAtIndex(idx); if (entry) { - debug_aranges->AppendRange(dwarf2Data->GetID(), entry->GetRangeBase(), + debug_aranges->AppendRange(*dwarf2Data->GetFileIndex(), + entry->GetRangeBase(), entry->GetRangeEnd()); num_line_entries_added++; } @@ -1536,3 +1543,12 @@ Status SymbolFileDWARFDebugMap::CalculateFrameVariableError(StackFrame &frame) { } return Status(); } + +void SymbolFileDWARFDebugMap::GetCompileOptions( + std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) { + + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + oso_dwarf->GetCompileOptions(args); + return false; + }); +} 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 5b364e423a6a..881fd4c45ff0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -9,6 +9,7 @@ #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARFDEBUGMAP_H +#include "DIERef.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Utility/RangeMap.h" #include "llvm/Support/Chrono.h" @@ -61,6 +62,8 @@ public: ParseLanguage(lldb_private::CompileUnit &comp_unit) override; lldb_private::XcodeSDK ParseXcodeSDK(lldb_private::CompileUnit &comp_unit) override; + llvm::SmallSet<lldb::LanguageType, 4> + ParseAllLanguages(lldb_private::CompileUnit &comp_unit) 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; @@ -133,9 +136,10 @@ public: lldb_private::LanguageSet languages, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, lldb_private::TypeMap &types) override; - lldb_private::CompilerDeclContext FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext &parent_decl_ctx) override; + lldb_private::CompilerDeclContext + FindNamespace(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; void GetTypes(lldb_private::SymbolContextScope *sc_scope, lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; @@ -150,6 +154,9 @@ public: // Statistics overrides. lldb_private::ModuleList GetDebugInfoModules() override; + void GetCompileOptions( + std::unordered_map<lldb::CompUnitSP, lldb_private::Args> &args) override; + protected: enum { kHaveInitializedOSOs = (1 << 0), kNumFlags }; @@ -209,7 +216,9 @@ protected: lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; static uint32_t GetOSOIndexFromUserID(lldb::user_id_t uid) { - return (uint32_t)((uid >> 32ull) - 1ull); + std::optional<uint32_t> OsoNum = DIERef(uid).file_index(); + lldbassert(OsoNum && "Invalid OSO Index"); + return *OsoNum; } static SymbolFileDWARF *GetSymbolFileAsSymbolFileDWARF(SymbolFile *sym_file); diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp index a1223a519fef..78c3c19684e1 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -29,7 +29,7 @@ SymbolFileDWARFDwo::SymbolFileDWARFDwo(SymbolFileDWARF &base_symbol_file, : SymbolFileDWARF(objfile, objfile->GetSectionList( /*update_module_section_list*/ false)), m_base_symbol_file(base_symbol_file) { - SetID(user_id_t(id) << 32); + SetFileIndex(id); // Parsing of the dwarf unit index is not thread-safe, so we need to prime it // to enable subsequent concurrent lookups. @@ -42,7 +42,7 @@ DWARFCompileUnit *SymbolFileDWARFDwo::GetDWOCompileUnitForHash(uint64_t hash) { if (auto *unit_contrib = entry->getContribution()) return llvm::dyn_cast_or_null<DWARFCompileUnit>( DebugInfo().GetUnitAtOffset(DIERef::Section::DebugInfo, - unit_contrib->getOffset32())); + unit_contrib->getOffset())); } return nullptr; } @@ -137,7 +137,7 @@ SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) { DWARFDIE SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) { - if (die_ref.dwo_num() == GetDwoNum()) + if (die_ref.file_index() == GetFileIndex()) return DebugInfo().GetDIE(die_ref); return GetBaseSymbolFile().GetDIE(die_ref); } diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h index 3edf004d683e..e98ea49d939b 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -41,8 +41,6 @@ public: DWARFDIE GetDIE(const DIERef &die_ref) override; - std::optional<uint32_t> GetDwoNum() override { return GetID() >> 32; } - lldb::offset_t GetVendorDWARFOpcodeSize(const lldb_private::DataExtractor &data, const lldb::offset_t data_offset, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/JSON/SymbolFileJSON.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/JSON/SymbolFileJSON.cpp new file mode 100644 index 000000000000..1f3ca27417e4 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/JSON/SymbolFileJSON.cpp @@ -0,0 +1,105 @@ +//===-- SymbolFileJSON.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 "SymbolFileJSON.h" + +#include "Plugins/ObjectFile/JSON/ObjectFileJSON.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/Symtab.h" +#include "lldb/Symbol/TypeList.h" +#include "lldb/Utility/LLDBLog.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Timer.h" +#include "llvm/Support/MemoryBuffer.h" + +#include <memory> +#include <optional> + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; + +LLDB_PLUGIN_DEFINE(SymbolFileJSON) + +char SymbolFileJSON::ID; + +SymbolFileJSON::SymbolFileJSON(lldb::ObjectFileSP objfile_sp) + : SymbolFileCommon(std::move(objfile_sp)) {} + +void SymbolFileJSON::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance); +} + +void SymbolFileJSON::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +llvm::StringRef SymbolFileJSON::GetPluginDescriptionStatic() { + return "Reads debug symbols from a JSON symbol table."; +} + +SymbolFile *SymbolFileJSON::CreateInstance(ObjectFileSP objfile_sp) { + return new SymbolFileJSON(std::move(objfile_sp)); +} + +uint32_t SymbolFileJSON::CalculateAbilities() { + if (!m_objfile_sp || !llvm::isa<ObjectFileJSON>(*m_objfile_sp)) + return 0; + + return GlobalVariables | Functions; +} + +uint32_t SymbolFileJSON::ResolveSymbolContext(const Address &so_addr, + SymbolContextItem resolve_scope, + SymbolContext &sc) { + std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); + if (m_objfile_sp->GetSymtab() == nullptr) + return 0; + + uint32_t resolved_flags = 0; + if (resolve_scope & eSymbolContextSymbol) { + sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress( + so_addr.GetFileAddress()); + if (sc.symbol) + resolved_flags |= eSymbolContextSymbol; + } + return resolved_flags; +} + +CompUnitSP SymbolFileJSON::ParseCompileUnitAtIndex(uint32_t idx) { return {}; } + +void SymbolFileJSON::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask, + lldb_private::TypeList &type_list) {} + +void SymbolFileJSON::AddSymbols(Symtab &symtab) { + if (!m_objfile_sp) + return; + + Symtab *json_symtab = m_objfile_sp->GetSymtab(); + if (!json_symtab) + return; + + if (&symtab == json_symtab) + return; + + // Merge the two symbol tables. + const size_t num_new_symbols = json_symtab->GetNumSymbols(); + for (size_t i = 0; i < num_new_symbols; ++i) { + Symbol *s = json_symtab->SymbolAtIndex(i); + symtab.AddSymbol(*s); + } + symtab.Finalize(); +} diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/JSON/SymbolFileJSON.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/JSON/SymbolFileJSON.h new file mode 100644 index 000000000000..4dd0d65da465 --- /dev/null +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/JSON/SymbolFileJSON.h @@ -0,0 +1,110 @@ +//===-- SymbolFileJSON.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_SYMBOLFILE_JSON_SYMBOLFILEJSON_H +#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_JSON_SYMBOLFILEJSON_H + +#include <map> +#include <optional> +#include <vector> + +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/SymbolFile.h" + +namespace lldb_private { + +class SymbolFileJSON : public lldb_private::SymbolFileCommon { + /// LLVM RTTI support. + static char ID; + +public: + /// LLVM RTTI support. + /// \{ + bool isA(const void *ClassID) const override { + return ClassID == &ID || SymbolFileCommon::isA(ClassID); + } + static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } + /// \} + + SymbolFileJSON(lldb::ObjectFileSP objfile_sp); + + static void Initialize(); + + static void Terminate(); + + static llvm::StringRef GetPluginNameStatic() { return "JSON"; } + + static llvm::StringRef GetPluginDescriptionStatic(); + + static lldb_private::SymbolFile * + CreateInstance(lldb::ObjectFileSP objfile_sp); + + llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } + + uint32_t CalculateAbilities() override; + + lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { + return lldb::eLanguageTypeUnknown; + } + + size_t ParseFunctions(CompileUnit &comp_unit) override { return 0; } + + bool ParseLineTable(CompileUnit &comp_unit) override { return false; } + + bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } + + bool ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) override { + return false; + } + + size_t ParseTypes(CompileUnit &cu) override { return 0; } + + bool ParseImportedModules( + const SymbolContext &sc, + std::vector<lldb_private::SourceModule> &imported_modules) override { + return false; + } + + size_t ParseBlocksRecursive(Function &func) override { return 0; } + + size_t ParseVariablesForContext(const SymbolContext &sc) override { + return 0; + } + + uint32_t CalculateNumCompileUnits() override { return 0; } + + lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; + + Type *ResolveTypeUID(lldb::user_id_t type_uid) override { return nullptr; } + std::optional<ArrayInfo> GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override { + return std::nullopt; + } + + bool CompleteType(CompilerType &compiler_type) override { return false; } + + uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, + lldb::SymbolContextItem resolve_scope, + lldb_private::SymbolContext &sc) override; + + void GetTypes(lldb_private::SymbolContextScope *sc_scope, + lldb::TypeClass type_mask, + lldb_private::TypeList &type_list) override; + + void AddSymbols(Symtab &symtab) override; + +private: + lldb::addr_t GetBaseFileAddress(); + + std::vector<std::pair<uint64_t, std::string>> m_symbols; +}; +} // namespace lldb_private + +#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_JSON_SYMBOLFILEJSON_H diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h index 1ed4fde9df32..4717fdcf11e3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h @@ -9,8 +9,8 @@ #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_CODEVIEWREGISTERMAPPING_H #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_CODEVIEWREGISTERMAPPING_H -#include "llvm/ADT/Triple.h" #include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/TargetParser/Triple.h" namespace lldb_private { namespace npdb { 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 e2e06491e8c1..06cb720b1e9f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -162,9 +162,13 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { ParseExtendedInfo(m_index, *cci); ParseInlineeLineTableForCompileUnit(*cci); - cci->m_strings.initialize(cci->m_debug_stream.getSubsectionsArray()); - PDBStringTable &strings = cantFail(m_index.pdb().getStringTable()); - cci->m_strings.setStrings(strings.getStringTable()); + auto strings = m_index.pdb().getStringTable(); + if (strings) { + cci->m_strings.initialize(cci->m_debug_stream.getSubsectionsArray()); + cci->m_strings.setStrings(strings->getStringTable()); + } else { + consumeError(strings.takeError()); + } // We want the main source file to always comes first. Note that we can't // just push_back the main file onto the front because `GetMainSourceFile` diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h index c6e382d3825c..3e6766a204dd 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h @@ -13,6 +13,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IntervalMap.h" +#include "llvm/ADT/SmallString.h" #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" #include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 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 1e9e1be62e3b..c7ff25e904ab 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -14,17 +14,18 @@ #include "llvm/DebugInfo/PDB/Native/TpiStream.h" #include "llvm/Demangle/MicrosoftDemangle.h" +#include "PdbUtil.h" #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h" #include "Plugins/ExpressionParser/Clang/ClangUtil.h" #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" +#include "SymbolFileNativePDB.h" +#include "UdtRecordCompleter.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/LLDBAssert.h" -#include "PdbUtil.h" -#include "UdtRecordCompleter.h" -#include "SymbolFileNativePDB.h" #include <optional> +#include <string_view> using namespace lldb_private; using namespace lldb_private::npdb; @@ -174,7 +175,7 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { return CreateDeclInfoForUndecoratedName(record.Name); llvm::ms_demangle::Demangler demangler; - StringView sv(record.UniqueName.begin(), record.UniqueName.size()); + std::string_view sv(record.UniqueName.begin(), record.UniqueName.size()); llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); if (demangler.Error) return {m_clang.GetTranslationUnitDecl(), std::string(record.UniqueName)}; diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h index fb979b877143..f6849f2083cc 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h @@ -10,7 +10,7 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBFPOPROGRAMTODWARFEXPRESSION_H #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" namespace lldb_private { class Stream; 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 164bfa8b3726..888bd89a7262 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -703,8 +703,12 @@ static bool GetFrameDataProgram(PdbIndex &index, if (frame_data_it == new_fpo_data.end()) return false; - PDBStringTable &strings = cantFail(index.pdb().getStringTable()); - out_program = cantFail(strings.getStringForID(frame_data_it->FrameFunc)); + auto strings = index.pdb().getStringTable(); + if (!strings) { + consumeError(strings.takeError()); + return false; + } + out_program = cantFail(strings->getStringForID(frame_data_it->FrameFunc)); return true; } 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 82d3707acfa4..f14fb32621b3 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -57,6 +57,7 @@ #include "PdbUtil.h" #include "UdtRecordCompleter.h" #include <optional> +#include <string_view> using namespace lldb; using namespace lldb_private; @@ -76,6 +77,10 @@ static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { return lldb::LanguageType::eLanguageTypeSwift; case PDB_Lang::Rust: return lldb::LanguageType::eLanguageTypeRust; + case PDB_Lang::ObjC: + return lldb::LanguageType::eLanguageTypeObjC; + case PDB_Lang::ObjCpp: + return lldb::LanguageType::eLanguageTypeObjC_plus_plus; default: return lldb::LanguageType::eLanguageTypeUnknown; } @@ -353,7 +358,7 @@ void SymbolFileNativePDB::InitializeObject() { lldb::eLanguageTypeC_plus_plus); if (auto err = ts_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Failed to initialize"); + "Failed to initialize: {0}"); } else { if (auto ts = *ts_or_err) ts->SetSymbolFile(this); @@ -627,7 +632,7 @@ static std::string GetUnqualifiedTypeName(const TagRecord &record) { } llvm::ms_demangle::Demangler demangler; - StringView sv(record.UniqueName.begin(), record.UniqueName.size()); + std::string_view sv(record.UniqueName.begin(), record.UniqueName.size()); llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); if (demangler.Error) return std::string(record.Name); @@ -1341,6 +1346,9 @@ bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) { llvm::Expected<uint32_t> SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, uint32_t file_id) { + if (!cii.m_strings.hasChecksums() || !cii.m_strings.hasStrings()) + return llvm::make_error<RawError>(raw_error_code::no_entry); + 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 @@ -1389,7 +1397,7 @@ bool SymbolFileNativePDB::ParseImportedModules( void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, Address func_addr) { lldb::user_id_t opaque_uid = toOpaqueUid(id); - if (m_inline_sites.find(opaque_uid) != m_inline_sites.end()) + if (m_inline_sites.contains(opaque_uid)) return; addr_t func_base = func_addr.GetFileAddress(); @@ -2126,9 +2134,8 @@ void SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, TypeClass type_mask, lldb_private::TypeList &type_list) {} -CompilerDeclContext -SymbolFileNativePDB::FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) { +CompilerDeclContext SymbolFileNativePDB::FindNamespace( + ConstString name, const CompilerDeclContext &parent_decl_ctx, bool) { return {}; } 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 90cd5251679e..bf64cd330c1f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -152,9 +152,9 @@ public: llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(lldb::LanguageType language) override; - CompilerDeclContext - FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) override; + CompilerDeclContext FindNamespace(ConstString name, + const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 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 c9236da4842c..5efa5bccb85f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -190,8 +190,7 @@ static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type, return compiler_type.GetTypeName(); } -static bool GetDeclarationForSymbol(const PDBSymbol &symbol, - Declaration &decl) { +static bool AddSourceInfoToDecl(const PDBSymbol &symbol, Declaration &decl) { auto &raw_sym = symbol.getRawSymbol(); auto first_line_up = raw_sym.getSrcLineOnTypeDefn(); @@ -408,8 +407,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { // symbols in PDB for types with const or volatile modifiers, but we need // to create only one declaration for them all. Type::ResolveState type_resolve_state; - CompilerType clang_type = m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>( - ConstString(name), decl_context); + CompilerType clang_type = + m_ast.GetTypeForIdentifier<clang::CXXRecordDecl>(name, decl_context); if (!clang_type.IsValid()) { auto access = GetAccessibilityForUdt(*udt); @@ -464,7 +463,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (udt->isVolatileType()) clang_type = clang_type.AddVolatileModifier(); - GetDeclarationForSymbol(type, decl); + AddSourceInfoToDecl(type, decl); return m_ast.GetSymbolFile()->MakeType( type.getSymIndexId(), ConstString(name), udt->getLength(), nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type, @@ -480,8 +479,8 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { uint64_t bytes = enum_type->getLength(); // Check if such an enum already exists in the current context - CompilerType ast_enum = m_ast.GetTypeForIdentifier<clang::EnumDecl>( - ConstString(name), decl_context); + CompilerType ast_enum = + m_ast.GetTypeForIdentifier<clang::EnumDecl>(name, decl_context); if (!ast_enum.IsValid()) { auto underlying_type_up = enum_type->getUnderlyingType(); if (!underlying_type_up) @@ -533,7 +532,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (enum_type->isVolatileType()) ast_enum = ast_enum.AddVolatileModifier(); - GetDeclarationForSymbol(type, decl); + AddSourceInfoToDecl(type, decl); return m_ast.GetSymbolFile()->MakeType( type.getSymIndexId(), ConstString(name), bytes, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ast_enum, @@ -558,8 +557,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { // Check if such a typedef already exists in the current context CompilerType ast_typedef = - m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(ConstString(name), - decl_ctx); + m_ast.GetTypeForIdentifier<clang::TypedefNameDecl>(name, decl_ctx); if (!ast_typedef.IsValid()) { CompilerType target_ast_type = target_type->GetFullCompilerType(); @@ -579,7 +577,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (type_def->isVolatileType()) ast_typedef = ast_typedef.AddVolatileModifier(); - GetDeclarationForSymbol(type, decl); + AddSourceInfoToDecl(type, decl); std::optional<uint64_t> size; if (type_def->getLength()) size = type_def->getLength(); @@ -659,7 +657,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { m_ast.CreateFunctionType(return_ast_type, arg_list.data(), arg_list.size(), is_variadic, type_quals, cc); - GetDeclarationForSymbol(type, decl); + AddSourceInfoToDecl(type, decl); return m_ast.GetSymbolFile()->MakeType( type.getSymIndexId(), ConstString(name), std::nullopt, nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, @@ -1300,6 +1298,15 @@ void PDBASTParser::AddRecordMembers( // Query the symbol's value as the variable initializer if valid. if (member_comp_type.IsConst()) { auto value = member->getValue(); + if (value.Type == llvm::pdb::Empty) { + LLDB_LOG(GetLog(LLDBLog::AST), + "Class '{0}' has member '{1}' of type '{2}' with an unknown " + "constant size.", + record_type.GetTypeName(), member_name, + member_comp_type.GetTypeName()); + continue; + } + clang::QualType qual_type = decl->getType(); unsigned type_width = m_ast.getASTContext().getIntWidth(qual_type); unsigned constant_width = value.getBitWidth(); 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 cb75dd59d366..78eabc35ebf9 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -80,6 +80,10 @@ lldb::LanguageType TranslateLanguage(PDB_Lang lang) { return lldb::LanguageType::eLanguageTypeSwift; case PDB_Lang::Rust: return lldb::LanguageType::eLanguageTypeRust; + case PDB_Lang::ObjC: + return lldb::LanguageType::eLanguageTypeObjC; + case PDB_Lang::ObjCpp: + return lldb::LanguageType::eLanguageTypeObjC_plus_plus; default: return lldb::LanguageType::eLanguageTypeUnknown; } @@ -315,7 +319,7 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func, auto type_system_or_err = GetTypeSystemForLanguage(lang); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to parse PDBFunc"); + "Unable to parse PDBFunc: {0}"); return nullptr; } @@ -566,7 +570,7 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to ResolveTypeUID"); + "Unable to ResolveTypeUID: {0}"); return nullptr; } @@ -603,7 +607,7 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to get dynamic array info for UID"); + "Unable to get dynamic array info for UID: {0}"); return false; } auto ts = *type_system_or_err; @@ -625,7 +629,7 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to get decl for UID"); + "Unable to get decl for UID: {0}"); return CompilerDecl(); } auto ts = *type_system_or_err; @@ -655,7 +659,7 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to get DeclContext for UID"); + "Unable to get DeclContext for UID: {0}"); return CompilerDeclContext(); } @@ -686,7 +690,7 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to get DeclContext containing UID"); + "Unable to get DeclContext containing UID: {0}"); return CompilerDeclContext(); } @@ -716,7 +720,7 @@ void SymbolFilePDB::ParseDeclsForContext( GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to parse decls for context"); + "Unable to parse decls for context: {0}"); return; } @@ -1465,7 +1469,7 @@ void SymbolFilePDB::DumpClangAST(Stream &s) { GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to dump ClangAST"); + "Unable to dump ClangAST: {0}"); return; } @@ -1678,7 +1682,7 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() { GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to get PDB AST parser"); + "Unable to get PDB AST parser: {0}"); return nullptr; } @@ -1693,13 +1697,13 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() { lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace(lldb_private::ConstString name, - const CompilerDeclContext &parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx, bool) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), - "Unable to find namespace {}", name.AsCString()); + "Unable to find namespace {1}: {0}", name.AsCString()); return CompilerDeclContext(); } auto ts = *type_system_or_err; @@ -1976,7 +1980,7 @@ SymbolFilePDB::GetMangledForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func) { } else if (!func_undecorated_name.empty()) { mangled.SetDemangledName(ConstString(func_undecorated_name)); } else if (!func_name.empty()) - mangled.SetValue(ConstString(func_name), false); + mangled.SetValue(ConstString(func_name)); return mangled; } @@ -1994,7 +1998,7 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile( if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR( GetLog(LLDBLog::Symbols), std::move(err), - "Unable to determine if DeclContext matches this symbol file"); + "Unable to determine if DeclContext matches this symbol file: {0}"); 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 992bafd6a377..5b98c6e8b486 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -157,9 +157,10 @@ public: llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(lldb::LanguageType language) override; - lldb_private::CompilerDeclContext FindNamespace( - lldb_private::ConstString name, - const lldb_private::CompilerDeclContext &parent_decl_ctx) override; + lldb_private::CompilerDeclContext + FindNamespace(lldb_private::ConstString name, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) override; llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 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 4cf4b5f37079..1bbc4de9c942 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -93,14 +93,11 @@ protected: lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; - typedef std::map<lldb_private::ConstString, lldb::TypeSP> TypeMap; - lldb_private::Symtab::IndexCollection m_source_indexes; lldb_private::Symtab::IndexCollection m_func_indexes; lldb_private::Symtab::IndexCollection m_code_indexes; lldb_private::Symtab::IndexCollection m_data_indexes; lldb_private::Symtab::NameToIndexMap m_objc_class_name_to_index; - TypeMap m_objc_class_types; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_SYMTAB_SYMBOLFILESYMTAB_H 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 61e06cdfa02d..55a663bb1b96 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -111,6 +111,9 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp, SectionList *module_section_list = module_sp->GetSectionList(); SectionList *objfile_section_list = dsym_objfile_sp->GetSectionList(); + if (!module_section_list || !objfile_section_list) + return nullptr; + static const SectionType g_sections[] = { eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, diff --git a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp index 6290843a8987..91b10ea64535 100644 --- a/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/SymbolVendor/wasm/SymbolVendorWasm.cpp @@ -109,6 +109,9 @@ SymbolVendorWasm::CreateInstance(const lldb::ModuleSP &module_sp, SectionList *module_section_list = module_sp->GetSectionList(); SectionList *objfile_section_list = sym_objfile_sp->GetSectionList(); + if (!module_section_list || !objfile_section_list) + return nullptr; + static const SectionType g_sections[] = { eSectionTypeDWARFDebugAbbrev, eSectionTypeDWARFDebugAddr, eSectionTypeDWARFDebugAranges, eSectionTypeDWARFDebugCuIndex, 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 58cd2290a8b7..17f8f51bdf0e 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 @@ -186,14 +186,12 @@ void DecodedThread::AppendInstruction(const pt_insn &insn) { } void DecodedThread::AppendError(const IntelPTError &error) { - CreateNewTraceItem(lldb::eTraceItemKindError).error = - ConstString(error.message()).AsCString(); + CreateNewTraceItem(lldb::eTraceItemKindError).error = error.message(); m_error_stats.RecordError(/*fatal=*/false); } void DecodedThread::AppendCustomError(StringRef err, bool fatal) { - CreateNewTraceItem(lldb::eTraceItemKindError).error = - ConstString(err).AsCString(); + CreateNewTraceItem(lldb::eTraceItemKindError).error = err.str(); m_error_stats.RecordError(fatal); } @@ -238,7 +236,9 @@ DecodedThread::GetItemKindByIndex(uint64_t item_index) const { return static_cast<lldb::TraceItemKind>(m_item_kinds[item_index]); } -const char *DecodedThread::GetErrorByIndex(uint64_t item_index) const { +llvm::StringRef DecodedThread::GetErrorByIndex(uint64_t item_index) const { + if (item_index >= m_item_data.size()) + return llvm::StringRef(); return m_item_data[item_index].error; } 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 b2a674aca182..5745cdb67ab6 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 @@ -159,7 +159,7 @@ public: /// \return /// The error associated with a given trace item. - const char *GetErrorByIndex(uint64_t item_index) const; + llvm::StringRef GetErrorByIndex(uint64_t item_index) const; /// \return /// The trace item kind given an item index. @@ -275,7 +275,7 @@ private: lldb::TraceEvent event; /// The string message of this item if it's an error - const char *error; + std::string error; }; /// Create a new trace item. 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 32e0bad0d19b..66d342196cf1 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 @@ -95,7 +95,7 @@ lldb::TraceItemKind TraceCursorIntelPT::GetItemKind() const { return m_decoded_thread_sp->GetItemKindByIndex(m_pos); } -const char *TraceCursorIntelPT::GetError() const { +llvm::StringRef TraceCursorIntelPT::GetError() const { return m_decoded_thread_sp->GetErrorByIndex(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 173426faacce..14240d9d0028 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 @@ -28,7 +28,7 @@ public: bool HasValue() const override; - const char *GetError() const override; + llvm::StringRef GetError() const override; lldb::addr_t GetLoadAddress() const override; 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 7b307a095688..bcac731713bb 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 @@ -88,8 +88,7 @@ void TraceIntelPT::DebuggerInitialize(Debugger &debugger) { const bool is_global_setting = true; PluginManager::CreateSettingForTracePlugin( debugger, GetGlobalProperties().GetValueProperties(), - ConstString("Properties for the intel-pt trace plug-in."), - is_global_setting); + "Properties for the intel-pt trace plug-in.", is_global_setting); } } 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 13c63f2f7e37..abe158168268 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.cpp @@ -69,7 +69,7 @@ size_t IHTRLayer::GetLayerId() const { return m_layer_id; } void HTRBlockLayer::AppendNewBlock(size_t block_id, HTRBlock &&block) { m_block_id_trace.emplace_back(block_id); - m_block_defs.emplace(block_id, block); + m_block_defs.emplace(block_id, std::move(block)); } void HTRBlockLayer::AppendRepeatedBlock(size_t block_id) { diff --git a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.h b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.h index 58a9262370a8..66aa19be1a46 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.h +++ b/contrib/llvm-project/lldb/source/Plugins/TraceExporter/common/TraceHTR.h @@ -215,7 +215,7 @@ public: /// /// \param[in] func_name /// The name of the function the 'call' instruction is calling if it can - /// be determined, None otherwise. + /// be determined, std::nullopt otherwise. void AddCallInstructionMetadata(lldb::addr_t load_addr, std::optional<ConstString> func_name); 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 93249527270e..c7430882adb5 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp @@ -8,6 +8,8 @@ #include "TypeSystemClang.h" +#include "clang/AST/DeclBase.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" @@ -55,7 +57,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolFile.h" @@ -70,6 +71,7 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Scalar.h" +#include "lldb/Utility/ThreadSafeDenseMap.h" #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" @@ -108,7 +110,6 @@ TypeSystemClangSupportsLanguage(lldb::LanguageType language) { lldb_private::Language::LanguageIsPascal(language) || // Use Clang for Rust until there is a proper language plugin for it language == eLanguageTypeRust || - language == eLanguageTypeExtRenderScript || // Use Clang for D until there is a proper language plugin for it language == eLanguageTypeD || // Open Dylan compiler debug info is designed to be Clang-compatible @@ -398,6 +399,7 @@ bool TypeSystemClang::IsOperator(llvm::StringRef name, .Case("=", clang::OO_Equal) .Case("==", clang::OO_EqualEqual) .Case("<", clang::OO_Less) + .Case("<=>", clang::OO_Spaceship) .Case("<<", clang::OO_LessLess) .Case("<<=", clang::OO_LessLessEqual) .Case("<=", clang::OO_LessEqual) @@ -483,9 +485,6 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { case clang::Language::OpenCLCXX: LangStd = LangStandard::lang_openclcpp10; break; - case clang::Language::CUDA: - LangStd = LangStandard::lang_cuda; - break; case clang::Language::Asm: case clang::Language::C: case clang::Language::ObjC: @@ -495,8 +494,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { case clang::Language::ObjCXX: LangStd = LangStandard::lang_gnucxx98; break; + case clang::Language::CUDA: case clang::Language::HIP: - LangStd = LangStandard::lang_hip; + LangStd = LangStandard::lang_gnucxx17; break; case clang::Language::HLSL: LangStd = LangStandard::lang_hlsl; @@ -509,6 +509,9 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { Opts.C99 = Std.isC99(); Opts.CPlusPlus = Std.isCPlusPlus(); Opts.CPlusPlus11 = Std.isCPlusPlus11(); + Opts.CPlusPlus14 = Std.isCPlusPlus14(); + Opts.CPlusPlus17 = Std.isCPlusPlus17(); + Opts.CPlusPlus20 = Std.isCPlusPlus20(); Opts.Digraphs = Std.hasDigraphs(); Opts.GNUMode = Std.isGNUMode(); Opts.GNUInline = !Std.isC99(); @@ -626,6 +629,8 @@ LanguageSet TypeSystemClang::GetSupportedLanguagesForTypes() { languages.Insert(lldb::eLanguageTypeC_plus_plus_11); languages.Insert(lldb::eLanguageTypeC11); languages.Insert(lldb::eLanguageTypeC_plus_plus_14); + languages.Insert(lldb::eLanguageTypeC_plus_plus_17); + languages.Insert(lldb::eLanguageTypeC_plus_plus_20); return languages; } @@ -636,6 +641,8 @@ LanguageSet TypeSystemClang::GetSupportedLanguagesForExpressions() { languages.Insert(lldb::eLanguageTypeC_plus_plus_03); languages.Insert(lldb::eLanguageTypeC_plus_plus_11); languages.Insert(lldb::eLanguageTypeC_plus_plus_14); + languages.Insert(lldb::eLanguageTypeC_plus_plus_17); + languages.Insert(lldb::eLanguageTypeC_plus_plus_20); return languages; } @@ -855,70 +862,62 @@ TypeSystemClang::GetBuiltinTypeForEncodingAndBitSize(Encoding encoding, return CompilerType(); } -lldb::BasicType -TypeSystemClang::GetBasicTypeEnumeration(ConstString name) { - if (name) { - typedef UniqueCStringMap<lldb::BasicType> TypeNameToBasicTypeMap; - static TypeNameToBasicTypeMap g_type_map; - static llvm::once_flag g_once_flag; - llvm::call_once(g_once_flag, []() { +lldb::BasicType TypeSystemClang::GetBasicTypeEnumeration(llvm::StringRef name) { + static const llvm::StringMap<lldb::BasicType> g_type_map = { // "void" - g_type_map.Append(ConstString("void"), eBasicTypeVoid); + {"void", eBasicTypeVoid}, // "char" - g_type_map.Append(ConstString("char"), eBasicTypeChar); - g_type_map.Append(ConstString("signed char"), eBasicTypeSignedChar); - g_type_map.Append(ConstString("unsigned char"), eBasicTypeUnsignedChar); - g_type_map.Append(ConstString("wchar_t"), eBasicTypeWChar); - g_type_map.Append(ConstString("signed wchar_t"), eBasicTypeSignedWChar); - g_type_map.Append(ConstString("unsigned wchar_t"), - eBasicTypeUnsignedWChar); + {"char", eBasicTypeChar}, + {"signed char", eBasicTypeSignedChar}, + {"unsigned char", eBasicTypeUnsignedChar}, + {"wchar_t", eBasicTypeWChar}, + {"signed wchar_t", eBasicTypeSignedWChar}, + {"unsigned wchar_t", eBasicTypeUnsignedWChar}, + // "short" - g_type_map.Append(ConstString("short"), eBasicTypeShort); - g_type_map.Append(ConstString("short int"), eBasicTypeShort); - g_type_map.Append(ConstString("unsigned short"), eBasicTypeUnsignedShort); - g_type_map.Append(ConstString("unsigned short int"), - eBasicTypeUnsignedShort); + {"short", eBasicTypeShort}, + {"short int", eBasicTypeShort}, + {"unsigned short", eBasicTypeUnsignedShort}, + {"unsigned short int", eBasicTypeUnsignedShort}, // "int" - g_type_map.Append(ConstString("int"), eBasicTypeInt); - g_type_map.Append(ConstString("signed int"), eBasicTypeInt); - g_type_map.Append(ConstString("unsigned int"), eBasicTypeUnsignedInt); - g_type_map.Append(ConstString("unsigned"), eBasicTypeUnsignedInt); + {"int", eBasicTypeInt}, + {"signed int", eBasicTypeInt}, + {"unsigned int", eBasicTypeUnsignedInt}, + {"unsigned", eBasicTypeUnsignedInt}, // "long" - g_type_map.Append(ConstString("long"), eBasicTypeLong); - g_type_map.Append(ConstString("long int"), eBasicTypeLong); - g_type_map.Append(ConstString("unsigned long"), eBasicTypeUnsignedLong); - g_type_map.Append(ConstString("unsigned long int"), - eBasicTypeUnsignedLong); + {"long", eBasicTypeLong}, + {"long int", eBasicTypeLong}, + {"unsigned long", eBasicTypeUnsignedLong}, + {"unsigned long int", eBasicTypeUnsignedLong}, // "long long" - g_type_map.Append(ConstString("long long"), eBasicTypeLongLong); - g_type_map.Append(ConstString("long long int"), eBasicTypeLongLong); - g_type_map.Append(ConstString("unsigned long long"), - eBasicTypeUnsignedLongLong); - g_type_map.Append(ConstString("unsigned long long int"), - eBasicTypeUnsignedLongLong); + {"long long", eBasicTypeLongLong}, + {"long long int", eBasicTypeLongLong}, + {"unsigned long long", eBasicTypeUnsignedLongLong}, + {"unsigned long long int", eBasicTypeUnsignedLongLong}, // "int128" - g_type_map.Append(ConstString("__int128_t"), eBasicTypeInt128); - g_type_map.Append(ConstString("__uint128_t"), eBasicTypeUnsignedInt128); + {"__int128_t", eBasicTypeInt128}, + {"__uint128_t", eBasicTypeUnsignedInt128}, // Miscellaneous - g_type_map.Append(ConstString("bool"), eBasicTypeBool); - g_type_map.Append(ConstString("float"), eBasicTypeFloat); - g_type_map.Append(ConstString("double"), eBasicTypeDouble); - g_type_map.Append(ConstString("long double"), eBasicTypeLongDouble); - g_type_map.Append(ConstString("id"), eBasicTypeObjCID); - g_type_map.Append(ConstString("SEL"), eBasicTypeObjCSel); - g_type_map.Append(ConstString("nullptr"), eBasicTypeNullPtr); - g_type_map.Sort(); - }); - - return g_type_map.Find(name, eBasicTypeInvalid); - } - return eBasicTypeInvalid; + {"bool", eBasicTypeBool}, + {"float", eBasicTypeFloat}, + {"double", eBasicTypeDouble}, + {"long double", eBasicTypeLongDouble}, + {"id", eBasicTypeObjCID}, + {"SEL", eBasicTypeObjCSel}, + {"nullptr", eBasicTypeNullPtr}, + }; + + auto iter = g_type_map.find(name); + if (iter == g_type_map.end()) + return eBasicTypeInvalid; + + return iter->second; } uint32_t TypeSystemClang::GetPointerByteSize() { @@ -1379,18 +1378,21 @@ static TemplateParameterList *CreateTemplateParameterList( const bool parameter_pack = false; const bool is_typename = false; const unsigned depth = 0; - const size_t num_template_params = template_param_infos.args.size(); + const size_t num_template_params = template_param_infos.Size(); DeclContext *const decl_context = ast.getTranslationUnitDecl(); // Is this the right decl context?, + + auto const &args = template_param_infos.GetArgs(); + auto const &names = template_param_infos.GetNames(); for (size_t i = 0; i < num_template_params; ++i) { - const char *name = template_param_infos.names[i]; + const char *name = names[i]; IdentifierInfo *identifier_info = nullptr; if (name && name[0]) identifier_info = &ast.Idents.get(name); - if (IsValueParam(template_param_infos.args[i])) { - QualType template_param_type = - template_param_infos.args[i].getIntegralType(); + TemplateArgument const &targ = args[i]; + if (IsValueParam(targ)) { + QualType template_param_type = targ.getIntegralType(); template_param_decls.push_back(NonTypeTemplateParmDecl::Create( ast, decl_context, SourceLocation(), SourceLocation(), depth, i, identifier_info, template_param_type, parameter_pack, @@ -1402,16 +1404,16 @@ static TemplateParameterList *CreateTemplateParameterList( } } - if (template_param_infos.packed_args) { + if (template_param_infos.hasParameterPack()) { IdentifierInfo *identifier_info = nullptr; - if (template_param_infos.pack_name && template_param_infos.pack_name[0]) - identifier_info = &ast.Idents.get(template_param_infos.pack_name); + if (template_param_infos.HasPackName()) + identifier_info = &ast.Idents.get(template_param_infos.GetPackName()); const bool parameter_pack_true = true; - if (!template_param_infos.packed_args->args.empty() && - IsValueParam(template_param_infos.packed_args->args[0])) { + if (!template_param_infos.GetParameterPack().IsEmpty() && + IsValueParam(template_param_infos.GetParameterPack().Front())) { QualType template_param_type = - template_param_infos.packed_args->args[0].getIntegralType(); + template_param_infos.GetParameterPack().Front().getIntegralType(); template_param_decls.push_back(NonTypeTemplateParmDecl::Create( ast, decl_context, SourceLocation(), SourceLocation(), depth, num_template_params, identifier_info, template_param_type, @@ -1437,10 +1439,12 @@ std::string TypeSystemClang::PrintTemplateParams( clang::TemplateParameterList *template_param_list = CreateTemplateParameterList(getASTContext(), template_param_infos, ignore); - llvm::SmallVector<clang::TemplateArgument, 2> args = - template_param_infos.args; + llvm::SmallVector<clang::TemplateArgument, 2> args( + template_param_infos.GetArgs()); if (template_param_infos.hasParameterPack()) { - args.append(template_param_infos.packed_args->args); + llvm::ArrayRef<TemplateArgument> pack_args = + template_param_infos.GetParameterPackArgs(); + args.append(pack_args.begin(), pack_args.end()); } std::string str; llvm::raw_string_ostream os(str); @@ -1485,8 +1489,8 @@ clang::FunctionTemplateDecl *TypeSystemClang::CreateFunctionTemplateDecl( void TypeSystemClang::CreateFunctionTemplateSpecializationInfo( FunctionDecl *func_decl, clang::FunctionTemplateDecl *func_tmpl_decl, const TemplateParameterInfos &infos) { - TemplateArgumentList *template_args_ptr = - TemplateArgumentList::CreateCopy(func_decl->getASTContext(), infos.args); + TemplateArgumentList *template_args_ptr = TemplateArgumentList::CreateCopy( + func_decl->getASTContext(), infos.GetArgs()); func_decl->setFunctionTemplateSpecialization(func_tmpl_decl, template_args_ptr, nullptr); @@ -1557,7 +1561,7 @@ static bool ClassTemplateAllowsToInstantiationArgs( // The found template needs to have compatible non-pack template arguments. // E.g., ensure that <typename, typename> != <typename>. // The pack parameters are compared later. - if (non_pack_params != instantiation_values.args.size()) + if (non_pack_params != instantiation_values.Size()) return false; // Ensure that <typename...> != <typename>. @@ -1568,14 +1572,15 @@ static bool ClassTemplateAllowsToInstantiationArgs( // parameter value. The special case of having an empty parameter pack value // always fits to a pack parameter. // E.g., ensure that <int...> != <typename...>. - if (pack_parameter && !instantiation_values.packed_args->args.empty() && + if (pack_parameter && !instantiation_values.GetParameterPack().IsEmpty() && !TemplateParameterAllowsValue( - *pack_parameter, instantiation_values.packed_args->args.front())) + *pack_parameter, instantiation_values.GetParameterPack().Front())) return false; // Compare all the non-pack parameters now. // E.g., ensure that <int> != <long>. - for (const auto pair : llvm::zip_first(instantiation_values.args, params)) { + for (const auto pair : + llvm::zip_first(instantiation_values.GetArgs(), params)) { const TemplateArgument &passed_arg = std::get<0>(pair); NamedDecl *found_param = std::get<1>(pair); if (!TemplateParameterAllowsValue(found_param, passed_arg)) @@ -1688,13 +1693,14 @@ TypeSystemClang::CreateClassTemplateSpecializationDecl( const TemplateParameterInfos &template_param_infos) { ASTContext &ast = getASTContext(); llvm::SmallVector<clang::TemplateArgument, 2> args( - template_param_infos.args.size() + - (template_param_infos.packed_args ? 1 : 0)); - std::copy(template_param_infos.args.begin(), template_param_infos.args.end(), - args.begin()); - if (template_param_infos.packed_args) { + template_param_infos.Size() + + (template_param_infos.hasParameterPack() ? 1 : 0)); + + auto const &orig_args = template_param_infos.GetArgs(); + std::copy(orig_args.begin(), orig_args.end(), args.begin()); + if (template_param_infos.hasParameterPack()) { args[args.size() - 1] = TemplateArgument::CreatePackCopy( - ast, template_param_infos.packed_args->args); + ast, template_param_infos.GetParameterPackArgs()); } ClassTemplateSpecializationDecl *class_template_specialization_decl = ClassTemplateSpecializationDecl::CreateDeserialized(ast, 0); @@ -2300,12 +2306,12 @@ CompilerType TypeSystemClang::CreateArrayType(const CompilerType &element_type, } CompilerType TypeSystemClang::CreateStructForIdentifier( - ConstString type_name, + llvm::StringRef type_name, const std::initializer_list<std::pair<const char *, CompilerType>> &type_fields, bool packed) { CompilerType type; - if (!type_name.IsEmpty() && + if (!type_name.empty() && (type = GetTypeForIdentifier<clang::CXXRecordDecl>(type_name)) .IsValid()) { lldbassert(0 && "Trying to create a type for an existing name"); @@ -2313,8 +2319,7 @@ CompilerType TypeSystemClang::CreateStructForIdentifier( } type = CreateRecordType(nullptr, OptionalClangModuleID(), lldb::eAccessPublic, - type_name.GetCString(), clang::TTK_Struct, - lldb::eLanguageTypeC); + type_name, clang::TTK_Struct, lldb::eLanguageTypeC); StartTagDeclarationDefinition(type); for (const auto &field : type_fields) AddFieldToRecordType(type, field.first, field.second, lldb::eAccessPublic, @@ -2326,7 +2331,7 @@ CompilerType TypeSystemClang::CreateStructForIdentifier( } CompilerType TypeSystemClang::GetOrCreateStructForIdentifier( - ConstString type_name, + llvm::StringRef type_name, const std::initializer_list<std::pair<const char *, CompilerType>> &type_fields, bool packed) { @@ -3044,28 +3049,11 @@ bool TypeSystemClang::IsCStringType(lldb::opaque_compiler_type_t type, } bool TypeSystemClang::IsFunctionType(lldb::opaque_compiler_type_t type) { - if (type) { - clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); - - if (qual_type->isFunctionType()) { - return true; - } + auto isFunctionType = [&](clang::QualType qual_type) { + return qual_type->isFunctionType(); + }; - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) { - default: - break; - case clang::Type::LValueReference: - case clang::Type::RValueReference: { - const clang::ReferenceType *reference_type = - llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); - if (reference_type) - return IsFunctionType( - reference_type->getPointeeType().getAsOpaquePtr()); - } break; - } - } - return false; + return IsTypeImpl(type, isFunctionType); } // Used to detect "Homogeneous Floating-point Aggregates" @@ -3179,11 +3167,13 @@ TypeSystemClang::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, return CompilerType(); } -bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { +bool TypeSystemClang::IsTypeImpl( + lldb::opaque_compiler_type_t type, + llvm::function_ref<bool(clang::QualType)> predicate) const { if (type) { clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); - if (qual_type->isFunctionPointerType()) + if (predicate(qual_type)) return true; const clang::Type::TypeClass type_class = qual_type->getTypeClass(); @@ -3196,20 +3186,34 @@ bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { const clang::ReferenceType *reference_type = llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); if (reference_type) - return IsFunctionPointerType( - reference_type->getPointeeType().getAsOpaquePtr()); + return IsTypeImpl(reference_type->getPointeeType().getAsOpaquePtr(), predicate); } break; } } return false; } +bool TypeSystemClang::IsMemberFunctionPointerType( + lldb::opaque_compiler_type_t type) { + auto isMemberFunctionPointerType = [](clang::QualType qual_type) { + return qual_type->isMemberFunctionPointerType(); + }; + + return IsTypeImpl(type, isMemberFunctionPointerType); +} + +bool TypeSystemClang::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { + auto isFunctionPointerType = [](clang::QualType qual_type) { + return qual_type->isFunctionPointerType(); + }; + + return IsTypeImpl(type, isFunctionPointerType); +} + bool TypeSystemClang::IsBlockPointerType( lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) { - if (type) { - clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); - + auto isBlockPointerType = [&](clang::QualType qual_type) { if (qual_type->isBlockPointerType()) { if (function_pointer_type_ptr) { const clang::BlockPointerType *block_pointer_type = @@ -3222,23 +3226,10 @@ bool TypeSystemClang::IsBlockPointerType( return true; } - const clang::Type::TypeClass type_class = qual_type->getTypeClass(); - switch (type_class) { - default: - break; + return false; + }; - case clang::Type::LValueReference: - case clang::Type::RValueReference: { - const clang::ReferenceType *reference_type = - llvm::cast<clang::ReferenceType>(qual_type.getTypePtr()); - if (reference_type) - return IsBlockPointerType( - reference_type->getPointeeType().getAsOpaquePtr(), - function_pointer_type_ptr); - } break; - } - } - return false; + return IsTypeImpl(type, isBlockPointerType); } bool TypeSystemClang::IsIntegerType(lldb::opaque_compiler_type_t type, @@ -4757,7 +4748,7 @@ TypeSystemClang::GetBitSize(lldb::opaque_compiler_type_t type, static bool g_printed = false; if (!g_printed) { StreamString s; - DumpTypeDescription(type, &s); + DumpTypeDescription(type, s); llvm::outs() << "warning: trying to determine the size of type "; llvm::outs() << s.GetString() << "\n"; @@ -4980,10 +4971,10 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, case clang::BuiltinType::OCLIntelSubgroupAVCImeResult: case clang::BuiltinType::OCLIntelSubgroupAVCRefResult: case clang::BuiltinType::OCLIntelSubgroupAVCSicResult: - case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout: - case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout: - case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin: - case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin: + case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleReferenceStreamout: + case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualReferenceStreamout: + case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleReferenceStreamin: + case clang::BuiltinType::OCLIntelSubgroupAVCImeDualReferenceStreamin: break; // PowerPC -- Matrix Multiply Assist @@ -4993,6 +4984,9 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, // ARM -- Scalable Vector Extension case clang::BuiltinType::SveBool: + case clang::BuiltinType::SveBoolx2: + case clang::BuiltinType::SveBoolx4: + case clang::BuiltinType::SveCount: case clang::BuiltinType::SveInt8: case clang::BuiltinType::SveInt8x2: case clang::BuiltinType::SveInt8x3: @@ -5044,72 +5038,12 @@ lldb::Encoding TypeSystemClang::GetEncoding(lldb::opaque_compiler_type_t type, break; // RISC-V V builtin types. - case clang::BuiltinType::RvvInt8mf8: - case clang::BuiltinType::RvvInt8mf4: - case clang::BuiltinType::RvvInt8mf2: - case clang::BuiltinType::RvvInt8m1: - case clang::BuiltinType::RvvInt8m2: - case clang::BuiltinType::RvvInt8m4: - case clang::BuiltinType::RvvInt8m8: - case clang::BuiltinType::RvvUint8mf8: - case clang::BuiltinType::RvvUint8mf4: - case clang::BuiltinType::RvvUint8mf2: - case clang::BuiltinType::RvvUint8m1: - case clang::BuiltinType::RvvUint8m2: - case clang::BuiltinType::RvvUint8m4: - case clang::BuiltinType::RvvUint8m8: - case clang::BuiltinType::RvvInt16mf4: - case clang::BuiltinType::RvvInt16mf2: - case clang::BuiltinType::RvvInt16m1: - case clang::BuiltinType::RvvInt16m2: - case clang::BuiltinType::RvvInt16m4: - case clang::BuiltinType::RvvInt16m8: - case clang::BuiltinType::RvvUint16mf4: - case clang::BuiltinType::RvvUint16mf2: - case clang::BuiltinType::RvvUint16m1: - case clang::BuiltinType::RvvUint16m2: - case clang::BuiltinType::RvvUint16m4: - case clang::BuiltinType::RvvUint16m8: - case clang::BuiltinType::RvvInt32mf2: - case clang::BuiltinType::RvvInt32m1: - case clang::BuiltinType::RvvInt32m2: - case clang::BuiltinType::RvvInt32m4: - case clang::BuiltinType::RvvInt32m8: - case clang::BuiltinType::RvvUint32mf2: - case clang::BuiltinType::RvvUint32m1: - case clang::BuiltinType::RvvUint32m2: - case clang::BuiltinType::RvvUint32m4: - case clang::BuiltinType::RvvUint32m8: - case clang::BuiltinType::RvvInt64m1: - case clang::BuiltinType::RvvInt64m2: - case clang::BuiltinType::RvvInt64m4: - case clang::BuiltinType::RvvInt64m8: - case clang::BuiltinType::RvvUint64m1: - case clang::BuiltinType::RvvUint64m2: - case clang::BuiltinType::RvvUint64m4: - case clang::BuiltinType::RvvUint64m8: - case clang::BuiltinType::RvvFloat16mf4: - case clang::BuiltinType::RvvFloat16mf2: - case clang::BuiltinType::RvvFloat16m1: - case clang::BuiltinType::RvvFloat16m2: - case clang::BuiltinType::RvvFloat16m4: - case clang::BuiltinType::RvvFloat16m8: - case clang::BuiltinType::RvvFloat32mf2: - case clang::BuiltinType::RvvFloat32m1: - case clang::BuiltinType::RvvFloat32m2: - case clang::BuiltinType::RvvFloat32m4: - case clang::BuiltinType::RvvFloat32m8: - case clang::BuiltinType::RvvFloat64m1: - case clang::BuiltinType::RvvFloat64m2: - case clang::BuiltinType::RvvFloat64m4: - case clang::BuiltinType::RvvFloat64m8: - case clang::BuiltinType::RvvBool1: - case clang::BuiltinType::RvvBool2: - case clang::BuiltinType::RvvBool4: - case clang::BuiltinType::RvvBool8: - case clang::BuiltinType::RvvBool16: - case clang::BuiltinType::RvvBool32: - case clang::BuiltinType::RvvBool64: +#define RVV_TYPE(Name, Id, SingletonId) case clang::BuiltinType::Id: +#include "clang/Basic/RISCVVTypes.def" + break; + + // WebAssembly builtin types. + case clang::BuiltinType::WasmExternRef: break; case clang::BuiltinType::IncompleteMatrixIdx: @@ -5290,7 +5224,7 @@ lldb::Format TypeSystemClang::GetFormat(lldb::opaque_compiler_type_t type) { case clang::Type::RValueReference: return lldb::eFormatHex; case clang::Type::MemberPointer: - break; + return lldb::eFormatHex; case clang::Type::Complex: { if (qual_type->isComplexType()) return lldb::eFormatComplex; @@ -6718,9 +6652,9 @@ uint32_t TypeSystemClang::GetIndexForRecordChild( // index 1 is the child index for "m_b" within class A size_t TypeSystemClang::GetIndexOfChildMemberWithName( - lldb::opaque_compiler_type_t type, const char *name, + lldb::opaque_compiler_type_t type, llvm::StringRef name, bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) { - if (type && name && name[0]) { + if (type && !name.empty()) { clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); switch (type_class) { @@ -6738,7 +6672,6 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName( // Try and find a field that matches NAME clang::RecordDecl::field_iterator field, field_end; - llvm::StringRef name_sref(name); for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++child_idx) { @@ -6751,7 +6684,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName( return child_indexes.size(); child_indexes.pop_back(); - } else if (field_name.equals(name_sref)) { + } else if (field_name.equals(name)) { // We have to add on the number of base classes to this index! child_indexes.push_back( child_idx + TypeSystemClang::GetNumBaseClasses( @@ -6764,8 +6697,7 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName( const clang::RecordDecl *parent_record_decl = cxx_record_decl; // Didn't find things easily, lets let clang do its thang... - clang::IdentifierInfo &ident_ref = - getASTContext().Idents.get(name_sref); + clang::IdentifierInfo &ident_ref = getASTContext().Idents.get(name); clang::DeclarationName decl_name(&ident_ref); clang::CXXBasePaths paths; @@ -6958,9 +6890,9 @@ size_t TypeSystemClang::GetIndexOfChildMemberWithName( uint32_t TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, + llvm::StringRef name, bool omit_empty_base_classes) { - if (type && name && name[0]) { + if (type && !name.empty()) { clang::QualType qual_type = RemoveWrappingTypes(GetCanonicalQualType(type)); const clang::Type::TypeClass type_class = qual_type->getTypeClass(); @@ -7005,11 +6937,10 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, // Try and find a field that matches NAME clang::RecordDecl::field_iterator field, field_end; - llvm::StringRef name_sref(name); for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++child_idx) { - if (field->getName().equals(name_sref)) + if (field->getName().equals(name)) return child_idx; } } @@ -7018,7 +6949,6 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, case clang::Type::ObjCObject: case clang::Type::ObjCInterface: if (GetCompleteType(type)) { - llvm::StringRef name_sref(name); const clang::ObjCObjectType *objc_class_type = llvm::dyn_cast<clang::ObjCObjectType>(qual_type.getTypePtr()); assert(objc_class_type); @@ -7037,7 +6967,7 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, ivar_pos != ivar_end; ++ivar_pos, ++child_idx) { const clang::ObjCIvarDecl *ivar_decl = *ivar_pos; - if (ivar_decl->getName().equals(name_sref)) { + if (ivar_decl->getName().equals(name)) { if ((!omit_empty_base_classes && superclass_interface_decl) || (omit_empty_base_classes && ObjCDeclHasIVars(superclass_interface_decl, true))) @@ -7048,7 +6978,7 @@ TypeSystemClang::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, } if (superclass_interface_decl) { - if (superclass_interface_decl->getName().equals(name_sref)) + if (superclass_interface_decl->getName().equals(name)) return 0; } } @@ -8591,7 +8521,7 @@ void TypeSystemClang::DumpFromSymbolFile(Stream &s, } void TypeSystemClang::DumpValue( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, + lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream &s, lldb::Format format, const lldb_private::DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, @@ -8642,15 +8572,15 @@ void TypeSystemClang::DumpValue( field_byte_offset = field_bit_offset / 8; assert(field_bit_offset % 8 == 0); if (child_idx == 0) - s->PutChar('{'); + s.PutChar('{'); else - s->PutChar(','); + s.PutChar(','); clang::QualType base_class_qual_type = base_class->getType(); std::string base_class_type_name(base_class_qual_type.getAsString()); // Indent and print the base class type name - s->Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT), + s.Format("\n{0}{1}", llvm::fmt_repeat(" ", depth + DEPTH_INCREMENT), base_class_type_name); clang::TypeInfo base_class_type_info = @@ -8660,7 +8590,7 @@ void TypeSystemClang::DumpValue( CompilerType base_clang_type = GetType(base_class_qual_type); base_clang_type.DumpValue( exe_ctx, - s, // Stream to dump to + &s, // Stream to dump to base_clang_type .GetFormat(), // The format with which to display the member data, // Data buffer containing all bytes for this type @@ -8688,12 +8618,12 @@ void TypeSystemClang::DumpValue( // Print the starting squiggly bracket (if this is the first member) or // comma (for member 2 and beyond) for the struct/union/class member. if (child_idx == 0) - s->PutChar('{'); + s.PutChar('{'); else - s->PutChar(','); + s.PutChar(','); // Indent - s->Printf("\n%*s", depth + DEPTH_INCREMENT, ""); + s.Printf("\n%*s", depth + DEPTH_INCREMENT, ""); clang::QualType field_type = field->getType(); // Print the member type if requested @@ -8714,19 +8644,19 @@ void TypeSystemClang::DumpValue( if (show_types) { std::string field_type_name(field_type.getAsString()); if (field_bitfield_bit_size > 0) - s->Printf("(%s:%u) ", field_type_name.c_str(), - field_bitfield_bit_size); + s.Printf("(%s:%u) ", field_type_name.c_str(), + field_bitfield_bit_size); else - s->Printf("(%s) ", field_type_name.c_str()); + s.Printf("(%s) ", field_type_name.c_str()); } // Print the member name and equal sign - s->Printf("%s = ", field->getNameAsString().c_str()); + s.Printf("%s = ", field->getNameAsString().c_str()); // Dump the value of the member CompilerType field_clang_type = GetType(field_type); field_clang_type.DumpValue( exe_ctx, - s, // Stream to dump to + &s, // Stream to dump to field_clang_type .GetFormat(), // The format with which to display the member data, // Data buffer containing all bytes for this type @@ -8746,7 +8676,7 @@ void TypeSystemClang::DumpValue( // Indent the trailing squiggly bracket if (child_idx > 0) - s->Printf("\n%*s}", depth, ""); + s.Printf("\n%*s}", depth, ""); } return; @@ -8764,13 +8694,13 @@ void TypeSystemClang::DumpValue( enum_end_pos = enum_decl->enumerator_end(); enum_pos != enum_end_pos; ++enum_pos) { if (enum_pos->getInitVal() == enum_value) { - s->Printf("%s", enum_pos->getNameAsString().c_str()); + s.Printf("%s", enum_pos->getNameAsString().c_str()); return; } } // If we have gotten here we didn't get find the enumerator in the enum // decl, so just print the integer. - s->Printf("%" PRIi64, enum_value); + s.Printf("%" PRIi64, enum_value); } return; @@ -8796,11 +8726,11 @@ void TypeSystemClang::DumpValue( uint32_t element_stride = element_byte_size; if (is_array_of_characters) { - s->PutChar('"'); - DumpDataExtractor(data, s, data_byte_offset, lldb::eFormatChar, + s.PutChar('"'); + DumpDataExtractor(data, &s, data_byte_offset, lldb::eFormatChar, element_byte_size, element_count, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); - s->PutChar('"'); + s.PutChar('"'); return; } else { CompilerType element_clang_type = GetType(element_qual_type); @@ -8810,12 +8740,12 @@ void TypeSystemClang::DumpValue( // Print the starting squiggly bracket (if this is the first member) or // comman (for member 2 and beyong) for the struct/union/class member. if (element_idx == 0) - s->PutChar('{'); + s.PutChar('{'); else - s->PutChar(','); + s.PutChar(','); // Indent and print the index - s->Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx); + s.Printf("\n%*s[%u] ", depth + DEPTH_INCREMENT, "", element_idx); // Figure out the field offset within the current struct/union/class // type @@ -8824,7 +8754,7 @@ void TypeSystemClang::DumpValue( // Dump the value of the member element_clang_type.DumpValue( exe_ctx, - s, // Stream to dump to + &s, // Stream to dump to element_format, // The format with which to display the element data, // Data buffer containing all bytes for this type data_byte_offset + @@ -8843,7 +8773,7 @@ void TypeSystemClang::DumpValue( // Indent the trailing squiggly bracket if (element_idx > 0) - s->Printf("\n%*s}", depth, ""); + s.Printf("\n%*s}", depth, ""); } } return; @@ -8862,7 +8792,7 @@ void TypeSystemClang::DumpValue( return typedef_clang_type.DumpValue( exe_ctx, - s, // Stream to dump to + &s, // Stream to dump to typedef_format, // The format with which to display the element data, // Data buffer containing all bytes for this type data_byte_offset, // Offset into "data" where to grab value from @@ -8887,7 +8817,7 @@ void TypeSystemClang::DumpValue( return elaborated_clang_type.DumpValue( exe_ctx, - s, // Stream to dump to + &s, // Stream to dump to elaborated_format, // The format with which to display the element data, // Data buffer containing all bytes for this type data_byte_offset, // Offset into "data" where to grab value from @@ -8912,7 +8842,7 @@ void TypeSystemClang::DumpValue( return elaborated_clang_type.DumpValue( exe_ctx, - s, // Stream to dump to + &s, // Stream to dump to elaborated_format, // The format with which to display the element data, // Data buffer containing all bytes for this type data_byte_offset, // Offset into "data" where to grab value from @@ -8938,7 +8868,7 @@ void TypeSystemClang::DumpValue( return desugar_clang_type.DumpValue( exe_ctx, - s, // Stream to dump to + &s, // Stream to dump to desugar_format, // The format with which to display the element data, // Data buffer containing all bytes for this type data_byte_offset, // Offset into "data" where to grab value from @@ -8954,7 +8884,7 @@ void TypeSystemClang::DumpValue( default: // We are down to a scalar type that we just need to display. - DumpDataExtractor(data, s, data_byte_offset, format, data_byte_size, 1, + DumpDataExtractor(data, &s, data_byte_offset, format, data_byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset); @@ -8964,7 +8894,7 @@ void TypeSystemClang::DumpValue( } } -static bool DumpEnumValue(const clang::QualType &qual_type, Stream *s, +static bool DumpEnumValue(const clang::QualType &qual_type, Stream &s, const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size, uint32_t bitfield_bit_offset, uint32_t bitfield_bit_size) { @@ -8994,7 +8924,7 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream *s, ++num_enumerators; if (val == enum_svalue) { // Found an exact match, that's all we need to do. - s->PutCString(enumerator->getNameAsString()); + s.PutCString(enumerator->getNameAsString()); return true; } } @@ -9008,9 +8938,9 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream *s, // decimal. if (!can_be_bitfield) { if (qual_type->isSignedIntegerOrEnumerationType()) - s->Printf("%" PRIi64, enum_svalue); + s.Printf("%" PRIi64, enum_svalue); else - s->Printf("%" PRIu64, enum_uvalue); + s.Printf("%" PRIu64, enum_uvalue); return true; } @@ -9033,20 +8963,20 @@ static bool DumpEnumValue(const clang::QualType &qual_type, Stream *s, if ((remaining_value & val.first) != val.first) continue; remaining_value &= ~val.first; - s->PutCString(val.second); + s.PutCString(val.second); if (remaining_value) - s->PutCString(" | "); + s.PutCString(" | "); } // If there is a remainder that is not covered by the value, print it as hex. if (remaining_value) - s->Printf("0x%" PRIx64, remaining_value); + s.Printf("0x%" PRIx64, remaining_value); return true; } bool TypeSystemClang::DumpTypeValue( - lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, + lldb::opaque_compiler_type_t type, Stream &s, lldb::Format format, const lldb_private::DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) { @@ -9079,7 +9009,7 @@ bool TypeSystemClang::DumpTypeValue( uint64_t typedef_byte_size = typedef_type_info.Width / 8; return typedef_clang_type.DumpTypeValue( - s, + &s, format, // The format with which to display the element data, // Data buffer containing all bytes for this type byte_offset, // Offset into "data" where to grab value from @@ -9158,7 +9088,7 @@ bool TypeSystemClang::DumpTypeValue( byte_size = 4; break; } - return DumpDataExtractor(data, s, byte_offset, format, byte_size, + return DumpDataExtractor(data, &s, byte_offset, format, byte_size, item_count, UINT32_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, bitfield_bit_offset, exe_scope); @@ -9170,7 +9100,7 @@ bool TypeSystemClang::DumpTypeValue( } void TypeSystemClang::DumpSummary(lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, + ExecutionContext *exe_ctx, Stream &s, const lldb_private::DataExtractor &data, lldb::offset_t data_byte_offset, size_t data_byte_size) { @@ -9199,8 +9129,8 @@ void TypeSystemClang::DumpSummary(lldb::opaque_compiler_type_t type, if (len == 0) break; if (total_cstr_len == 0) - s->PutCString(" \""); - DumpDataExtractor(cstr_data, s, 0, lldb::eFormatChar, 1, len, + s.PutCString(" \""); + DumpDataExtractor(cstr_data, &s, 0, lldb::eFormatChar, 1, len, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); total_cstr_len += len; if (len < buf.size()) @@ -9208,7 +9138,7 @@ void TypeSystemClang::DumpSummary(lldb::opaque_compiler_type_t type, pointer_address += total_cstr_len; } if (total_cstr_len > 0) - s->PutChar('"'); + s.PutChar('"'); } } } @@ -9217,7 +9147,7 @@ void TypeSystemClang::DumpSummary(lldb::opaque_compiler_type_t type, void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, lldb::DescriptionLevel level) { StreamFile s(stdout, false); - DumpTypeDescription(type, &s, level); + DumpTypeDescription(type, s, level); CompilerType ct(weak_from_this(), type); const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr(); @@ -9228,7 +9158,7 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, } void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s, + Stream &s, lldb::DescriptionLevel level) { if (type) { clang::QualType qual_type = @@ -9257,7 +9187,7 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, else class_interface_decl->print(llvm_ostrm, getASTContext().getPrintingPolicy(), - s->GetIndentLevel()); + s.GetIndentLevel()); } break; case clang::Type::Typedef: { @@ -9270,8 +9200,8 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, else { std::string clang_typedef_name(GetTypeNameForDecl(typedef_decl)); if (!clang_typedef_name.empty()) { - s->PutCString("typedef "); - s->PutCString(clang_typedef_name); + s.PutCString("typedef "); + s.PutCString(clang_typedef_name); } } } break; @@ -9285,7 +9215,7 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, record_decl->dump(llvm_ostrm); else { record_decl->print(llvm_ostrm, getASTContext().getPrintingPolicy(), - s->GetIndentLevel()); + s.GetIndentLevel()); } } break; @@ -9304,14 +9234,14 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type, else { std::string clang_type_name(qual_type.getAsString()); if (!clang_type_name.empty()) - s->PutCString(clang_type_name); + s.PutCString(clang_type_name); } } } } if (buf.size() > 0) { - s->Write(buf.data(), buf.size()); + s.Write(buf.data(), buf.size()); } } } @@ -9758,43 +9688,21 @@ TypeSystemClang::DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) { return ConstString(); } -bool TypeSystemClang::DeclContextIsClassMethod( - void *opaque_decl_ctx, lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, ConstString *language_object_name_ptr) { - if (opaque_decl_ctx) { - clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; - if (ObjCMethodDecl *objc_method = - llvm::dyn_cast<clang::ObjCMethodDecl>(decl_ctx)) { - if (is_instance_method_ptr) - *is_instance_method_ptr = objc_method->isInstanceMethod(); - if (language_ptr) - *language_ptr = eLanguageTypeObjC; - if (language_object_name_ptr) - language_object_name_ptr->SetCString("self"); - return true; - } else if (CXXMethodDecl *cxx_method = - llvm::dyn_cast<clang::CXXMethodDecl>(decl_ctx)) { - if (is_instance_method_ptr) - *is_instance_method_ptr = cxx_method->isInstance(); - if (language_ptr) - *language_ptr = eLanguageTypeC_plus_plus; - if (language_object_name_ptr) - language_object_name_ptr->SetCString("this"); - return true; - } else if (clang::FunctionDecl *function_decl = - llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) { - ClangASTMetadata *metadata = GetMetadata(function_decl); - if (metadata && metadata->HasObjectPtr()) { - if (is_instance_method_ptr) - *is_instance_method_ptr = true; - if (language_ptr) - *language_ptr = eLanguageTypeObjC; - if (language_object_name_ptr) - language_object_name_ptr->SetCString(metadata->GetObjectPtrName()); - return true; - } - } +bool TypeSystemClang::DeclContextIsClassMethod(void *opaque_decl_ctx) { + if (!opaque_decl_ctx) + return false; + + clang::DeclContext *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; + if (llvm::isa<clang::ObjCMethodDecl>(decl_ctx)) { + return true; + } else if (llvm::isa<clang::CXXMethodDecl>(decl_ctx)) { + return true; + } else if (clang::FunctionDecl *fun_decl = + llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) { + if (ClangASTMetadata *metadata = GetMetadata(fun_decl)) + return metadata->HasObjectPtr(); } + return false; } @@ -9815,6 +9723,24 @@ bool TypeSystemClang::DeclContextIsContainedInLookup( return false; } +lldb::LanguageType +TypeSystemClang::DeclContextGetLanguage(void *opaque_decl_ctx) { + if (!opaque_decl_ctx) + return eLanguageTypeUnknown; + + auto *decl_ctx = (clang::DeclContext *)opaque_decl_ctx; + if (llvm::isa<clang::ObjCMethodDecl>(decl_ctx)) { + return eLanguageTypeObjC; + } else if (llvm::isa<clang::CXXMethodDecl>(decl_ctx)) { + return eLanguageTypeC_plus_plus; + } else if (auto *fun_decl = llvm::dyn_cast<clang::FunctionDecl>(decl_ctx)) { + if (ClangASTMetadata *metadata = GetMetadata(fun_decl)) + return metadata->GetObjectPtrLanguage(); + } + + return eLanguageTypeUnknown; +} + static bool IsClangDeclContext(const CompilerDeclContext &dc) { return dc.IsValid() && isa<TypeSystemClang>(dc.GetTypeSystem()); } 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 2e7ebe62f303..3105e5b2e80f 100644 --- a/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h +++ b/contrib/llvm-project/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h @@ -207,7 +207,7 @@ public: CompilerType GetBasicType(lldb::BasicType type); - static lldb::BasicType GetBasicTypeEnumeration(ConstString name); + static lldb::BasicType GetBasicTypeEnumeration(llvm::StringRef name); CompilerType GetBuiltinTypeForDWARFEncodingAndBitSize(llvm::StringRef type_name, @@ -252,43 +252,41 @@ public: template <typename RecordDeclType> CompilerType - GetTypeForIdentifier(ConstString type_name, + GetTypeForIdentifier(llvm::StringRef type_name, clang::DeclContext *decl_context = nullptr) { CompilerType compiler_type; - - if (type_name.GetLength()) { - clang::ASTContext &ast = getASTContext(); - if (!decl_context) - decl_context = ast.getTranslationUnitDecl(); - - clang::IdentifierInfo &myIdent = ast.Idents.get(type_name.GetCString()); - clang::DeclarationName myName = - ast.DeclarationNames.getIdentifier(&myIdent); - - clang::DeclContext::lookup_result result = decl_context->lookup(myName); - - if (!result.empty()) { - clang::NamedDecl *named_decl = *result.begin(); - if (const RecordDeclType *record_decl = - llvm::dyn_cast<RecordDeclType>(named_decl)) - compiler_type = - CompilerType(weak_from_this(), - clang::QualType(record_decl->getTypeForDecl(), 0) - .getAsOpaquePtr()); - } - } + if (type_name.empty()) + return compiler_type; + + clang::ASTContext &ast = getASTContext(); + if (!decl_context) + decl_context = ast.getTranslationUnitDecl(); + + clang::IdentifierInfo &myIdent = ast.Idents.get(type_name); + clang::DeclarationName myName = + ast.DeclarationNames.getIdentifier(&myIdent); + clang::DeclContext::lookup_result result = decl_context->lookup(myName); + if (result.empty()) + return compiler_type; + + clang::NamedDecl *named_decl = *result.begin(); + if (const RecordDeclType *record_decl = + llvm::dyn_cast<RecordDeclType>(named_decl)) + compiler_type = CompilerType( + weak_from_this(), + clang::QualType(record_decl->getTypeForDecl(), 0).getAsOpaquePtr()); return compiler_type; } CompilerType CreateStructForIdentifier( - ConstString type_name, + llvm::StringRef type_name, const std::initializer_list<std::pair<const char *, CompilerType>> &type_fields, bool packed = false); CompilerType GetOrCreateStructForIdentifier( - ConstString type_name, + llvm::StringRef type_name, const std::initializer_list<std::pair<const char *, CompilerType>> &type_fields, bool packed = false); @@ -331,17 +329,81 @@ public: class TemplateParameterInfos { public: + TemplateParameterInfos() = default; + TemplateParameterInfos(llvm::ArrayRef<const char *> names_in, + llvm::ArrayRef<clang::TemplateArgument> args_in) + : names(names_in), args(args_in) { + assert(names.size() == args_in.size()); + } + + TemplateParameterInfos(TemplateParameterInfos const &) = delete; + TemplateParameterInfos(TemplateParameterInfos &&) = delete; + + TemplateParameterInfos &operator=(TemplateParameterInfos const &) = delete; + TemplateParameterInfos &operator=(TemplateParameterInfos &&) = delete; + + ~TemplateParameterInfos() = default; + bool IsValid() const { // Having a pack name but no packed args doesn't make sense, so mark // these template parameters as invalid. if (pack_name && !packed_args) return false; return args.size() == names.size() && - (!packed_args || !packed_args->packed_args); + (!packed_args || !packed_args->packed_args); } + bool IsEmpty() const { return args.empty(); } + size_t Size() const { return args.size(); } + + llvm::ArrayRef<clang::TemplateArgument> GetArgs() const { return args; } + llvm::ArrayRef<const char *> GetNames() const { return names; } + + clang::TemplateArgument const &Front() const { + assert(!args.empty()); + return args.front(); + } + + void InsertArg(char const *name, clang::TemplateArgument arg) { + args.emplace_back(std::move(arg)); + names.push_back(name); + } + + // Parameter pack related + bool hasParameterPack() const { return static_cast<bool>(packed_args); } + TemplateParameterInfos const &GetParameterPack() const { + assert(packed_args != nullptr); + return *packed_args; + } + + TemplateParameterInfos &GetParameterPack() { + assert(packed_args != nullptr); + return *packed_args; + } + + llvm::ArrayRef<clang::TemplateArgument> GetParameterPackArgs() const { + assert(packed_args != nullptr); + return packed_args->GetArgs(); + } + + bool HasPackName() const { return pack_name && pack_name[0]; } + + llvm::StringRef GetPackName() const { + assert(HasPackName()); + return pack_name; + } + + void SetPackName(char const *name) { pack_name = name; } + + void SetParameterPack(std::unique_ptr<TemplateParameterInfos> args) { + packed_args = std::move(args); + } + + private: + /// Element 'names[i]' holds the template argument name + /// of 'args[i]' llvm::SmallVector<const char *, 2> names; llvm::SmallVector<clang::TemplateArgument, 2> args; @@ -517,14 +579,13 @@ public: ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override; - bool DeclContextIsClassMethod(void *opaque_decl_ctx, - lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) override; + bool DeclContextIsClassMethod(void *opaque_decl_ctx) override; bool DeclContextIsContainedInLookup(void *opaque_decl_ctx, void *other_opaque_decl_ctx) override; + lldb::LanguageType DeclContextGetLanguage(void *opaque_decl_ctx) override; + // Clang specific clang::DeclContext functions static clang::DeclContext * @@ -596,6 +657,8 @@ public: bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; + bool IsMemberFunctionPointerType(lldb::opaque_compiler_type_t type) override; + bool IsBlockPointerType(lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; @@ -771,10 +834,6 @@ public: lldb::BasicType GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; - static lldb::BasicType - GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type, - ConstString name); - void ForEachEnumerator( lldb::opaque_compiler_type_t type, std::function<bool(const CompilerType &integer_type, @@ -814,7 +873,7 @@ public: // Lookup a child given a name. This function will match base class names and // member member names in "clang_type" only, not descendants. uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, + llvm::StringRef name, bool omit_empty_base_classes) override; // Lookup a child member given a name. This function will match member names @@ -825,7 +884,8 @@ public: // so we catch all names that match a given child name, not just the first. size_t GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, - const char *name, bool omit_empty_base_classes, + llvm::StringRef name, + bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) override; bool IsTemplateType(lldb::opaque_compiler_type_t type) override; @@ -972,20 +1032,20 @@ public: void DumpFromSymbolFile(Stream &s, llvm::StringRef symbol_name); void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, lldb::Format format, const DataExtractor &data, + Stream &s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, bool show_summary, bool verbose, uint32_t depth) override; - bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, + bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream &s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) override; void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, const DataExtractor &data, + Stream &s, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size) override; void DumpTypeDescription( @@ -993,7 +1053,7 @@ public: lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; void DumpTypeDescription( - lldb::opaque_compiler_type_t type, Stream *s, + lldb::opaque_compiler_type_t type, Stream &s, lldb::DescriptionLevel level = lldb::eDescriptionLevelFull) override; static void DumpTypeName(const CompilerType &type); @@ -1085,6 +1145,9 @@ private: const clang::ClassTemplateSpecializationDecl * GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type); + bool IsTypeImpl(lldb::opaque_compiler_type_t type, + llvm::function_ref<bool(clang::QualType)> predicate) const; + // Classes that inherit from TypeSystemClang can see and modify these std::string m_target_triple; std::unique_ptr<clang::ASTContext> m_ast_up; 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 47fc210b5d64..7ff5cd2c23b0 100644 --- a/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -500,7 +500,7 @@ bool UnwindAssemblyInstEmulation::ReadRegister(EmulateInstruction *instruction, strm.Printf("UnwindAssemblyInstEmulation::ReadRegister (name = \"%s\") => " "synthetic_value = %i, value = ", reg_info->name, synthetic); - DumpRegisterValue(reg_value, &strm, reg_info, false, false, eFormatDefault); + DumpRegisterValue(reg_value, strm, *reg_info, false, false, eFormatDefault); log->PutString(strm.GetString()); } return true; @@ -526,7 +526,7 @@ bool UnwindAssemblyInstEmulation::WriteRegister( strm.Printf( "UnwindAssemblyInstEmulation::WriteRegister (name = \"%s\", value = ", reg_info->name); - DumpRegisterValue(reg_value, &strm, reg_info, false, false, eFormatDefault); + DumpRegisterValue(reg_value, strm, *reg_info, false, false, eFormatDefault); strm.PutCString(", context = "); context.Dump(strm, instruction); log->PutString(strm.GetString()); diff --git a/contrib/llvm-project/lldb/source/Symbol/ArmUnwindInfo.cpp b/contrib/llvm-project/lldb/source/Symbol/ArmUnwindInfo.cpp index 60935a33827f..6bc3bd6cc5ed 100644 --- a/contrib/llvm-project/lldb/source/Symbol/ArmUnwindInfo.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/ArmUnwindInfo.cpp @@ -78,7 +78,7 @@ uint8_t ArmUnwindInfo::GetByteAtOffset(const uint32_t *data, uint16_t offset) const { uint32_t value = data[offset / 4]; if (m_byte_order != endian::InlHostByteOrder()) - value = llvm::ByteSwap_32(value); + value = llvm::byteswap<uint32_t>(value); return (value >> ((3 - (offset % 4)) * 8)) & 0xff; } diff --git a/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp b/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp index 64b0aa4f62ad..c9039ea51ff7 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompactUnwindInfo.cpp @@ -155,7 +155,7 @@ FLAGS_ANONYMOUS_ENUM(){ #endif #define EXTRACT_BITS(value, mask) \ - ((value >> llvm::countTrailingZeros(static_cast<uint32_t>(mask))) & \ + ((value >> llvm::countr_zero(static_cast<uint32_t>(mask))) & \ (((1 << llvm::popcount(static_cast<uint32_t>(mask)))) - 1)) // constructor diff --git a/contrib/llvm-project/lldb/source/Symbol/CompilerDeclContext.cpp b/contrib/llvm-project/lldb/source/Symbol/CompilerDeclContext.cpp index a3af568e7c99..a188e60251f7 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompilerDeclContext.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompilerDeclContext.cpp @@ -34,16 +34,18 @@ ConstString CompilerDeclContext::GetScopeQualifiedName() const { return ConstString(); } -bool CompilerDeclContext::IsClassMethod(lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) { +bool CompilerDeclContext::IsClassMethod() { if (IsValid()) - return m_type_system->DeclContextIsClassMethod( - m_opaque_decl_ctx, language_ptr, is_instance_method_ptr, - language_object_name_ptr); + return m_type_system->DeclContextIsClassMethod(m_opaque_decl_ctx); return false; } +lldb::LanguageType CompilerDeclContext::GetLanguage() { + if (IsValid()) + return m_type_system->DeclContextGetLanguage(m_opaque_decl_ctx); + return {}; +} + bool CompilerDeclContext::IsContainedInLookup(CompilerDeclContext other) const { if (!IsValid()) return false; diff --git a/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp b/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp index 11a7d09680d3..90d17b921a96 100644 --- a/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/CompilerType.cpp @@ -154,6 +154,13 @@ bool CompilerType::IsFunctionPointerType() const { return false; } +bool CompilerType::IsMemberFunctionPointerType() const { + if (IsValid()) + if (auto type_system_sp = GetTypeSystem()) + return type_system_sp->IsMemberFunctionPointerType(m_type); + return false; +} + bool CompilerType::IsBlockPointerType( CompilerType *function_pointer_type_ptr) const { if (IsValid()) @@ -734,9 +741,9 @@ CompilerType CompilerType::GetChildCompilerTypeAtIndex( // index 1 is the child index for "m_b" within class A size_t CompilerType::GetIndexOfChildMemberWithName( - const char *name, bool omit_empty_base_classes, + llvm::StringRef name, bool omit_empty_base_classes, std::vector<uint32_t> &child_indexes) const { - if (IsValid() && name && name[0]) { + if (IsValid() && !name.empty()) { if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetIndexOfChildMemberWithName( m_type, name, omit_empty_base_classes, child_indexes); @@ -803,12 +810,12 @@ bool CompilerType::IsMeaninglessWithoutDynamicResolution() const { // matches can include base class names. uint32_t -CompilerType::GetIndexOfChildWithName(const char *name, +CompilerType::GetIndexOfChildWithName(llvm::StringRef name, bool omit_empty_base_classes) const { - if (IsValid() && name && name[0]) { + if (IsValid() && !name.empty()) { if (auto type_system_sp = GetTypeSystem()) return type_system_sp->GetIndexOfChildWithName(m_type, name, - omit_empty_base_classes); + omit_empty_base_classes); } return UINT32_MAX; } @@ -823,7 +830,7 @@ void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s, bool show_summary, bool verbose, uint32_t depth) { if (!IsValid()) if (auto type_system_sp = GetTypeSystem()) - type_system_sp->DumpValue(m_type, exe_ctx, s, format, data, + type_system_sp->DumpValue(m_type, exe_ctx, *s, format, data, data_byte_offset, data_byte_size, bitfield_bit_size, bitfield_bit_offset, show_types, show_summary, verbose, depth); @@ -837,9 +844,9 @@ bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format, ExecutionContextScope *exe_scope) { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) - return type_system_sp->DumpTypeValue(m_type, s, format, data, byte_offset, - byte_size, bitfield_bit_size, - bitfield_bit_offset, exe_scope); + return type_system_sp->DumpTypeValue( + m_type, *s, format, data, byte_offset, byte_size, bitfield_bit_size, + bitfield_bit_offset, exe_scope); return false; } @@ -849,7 +856,7 @@ void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s, size_t data_byte_size) { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) - type_system_sp->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset, + type_system_sp->DumpSummary(m_type, exe_ctx, *s, data, data_byte_offset, data_byte_size); } @@ -863,7 +870,7 @@ void CompilerType::DumpTypeDescription(Stream *s, lldb::DescriptionLevel level) const { if (IsValid()) if (auto type_system_sp = GetTypeSystem()) - type_system_sp->DumpTypeDescription(m_type, s, level); + type_system_sp->DumpTypeDescription(m_type, *s, level); } #ifndef NDEBUG diff --git a/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp index be9f64356b4e..dc54d13ae23c 100644 --- a/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/DWARFCallFrameInfo.cpp @@ -674,6 +674,11 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset, unwind_plan.GetRowAtIndex(0)->GetRegisterInfo(reg_num, reg_location)) row->SetRegisterInfo(reg_num, reg_location); + else { + // If the register was not set in the first row, remove the + // register info to keep the unmodified value from the caller. + row->RemoveRegisterInfo(reg_num); + } break; } } diff --git a/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp b/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp index cd8d520ada78..59b5d6125e04 100644 --- a/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/LineTable.cpp @@ -325,7 +325,7 @@ uint32_t LineTable::FindLineEntryIndexByFileIndex( start_idx, file_idx, src_location_spec, line_entry_ptr, file_idx_matcher); } -size_t LineTable::FineLineEntriesForFileIndex(uint32_t file_idx, bool append, +size_t LineTable::FindLineEntriesForFileIndex(uint32_t file_idx, bool append, SymbolContextList &sc_list) { if (!append) diff --git a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp index 7d24905be350..8c52df5f2a0a 100644 --- a/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/LocateSymbolFileMacOSX.cpp @@ -559,14 +559,17 @@ bool Symbols::DownloadObjectAndSymbolFile(ModuleSpec &module_spec, const UUID *uuid_ptr = module_spec.GetUUIDPtr(); const FileSpec *file_spec_ptr = module_spec.GetFileSpecPtr(); + // If \a dbgshell_command is set, the user has specified + // forced symbol lookup via that command. We'll get the + // path back from GetDsymForUUIDExecutable() later. llvm::StringRef dbgshell_command = GetDbgShellCommand(); - // When dbgshell_command is empty, the user has not enabled the use of an - // external program to find the symbols, don't run it for them. + // If forced lookup isn't set, by the user's \a dbgshell_command or + // by the \a force_lookup argument, exit this method. if (!force_lookup && dbgshell_command.empty()) return false; - // We need a UUID or valid (existing FileSpec. + // We need a UUID or valid existing FileSpec. if (!uuid_ptr && (!file_spec_ptr || !FileSystem::Instance().Exists(*file_spec_ptr))) return false; diff --git a/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp b/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp index 6d4fb22631bc..bebc9589418c 100644 --- a/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/ObjectFile.cpp @@ -356,6 +356,7 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) { case eSectionTypeDWARFAppleNamespaces: case eSectionTypeDWARFAppleObjC: case eSectionTypeDWARFGNUDebugAltLink: + case eSectionTypeCTF: return AddressClass::eDebug; case eSectionTypeEHFrame: case eSectionTypeARMexidx: @@ -761,3 +762,34 @@ uint32_t ObjectFile::GetCacheHash() { m_cache_hash = llvm::djbHash(strm.GetString()); return *m_cache_hash; } + +namespace llvm { +namespace json { + +bool fromJSON(const llvm::json::Value &value, + lldb_private::ObjectFile::Type &type, llvm::json::Path path) { + if (auto str = value.getAsString()) { + type = llvm::StringSwitch<ObjectFile::Type>(*str) + .Case("corefile", ObjectFile::eTypeCoreFile) + .Case("executable", ObjectFile::eTypeExecutable) + .Case("debuginfo", ObjectFile::eTypeDebugInfo) + .Case("dynamiclinker", ObjectFile::eTypeDynamicLinker) + .Case("objectfile", ObjectFile::eTypeObjectFile) + .Case("sharedlibrary", ObjectFile::eTypeSharedLibrary) + .Case("stublibrary", ObjectFile::eTypeStubLibrary) + .Case("jit", ObjectFile::eTypeJIT) + .Case("unknown", ObjectFile::eTypeUnknown) + .Default(ObjectFile::eTypeInvalid); + + if (type == ObjectFile::eTypeInvalid) { + path.report("invalid object type"); + return false; + } + + return true; + } + path.report("expected string"); + return false; +} +} // namespace json +} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp b/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp index 067b7b900d89..26b4c4d62ad9 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Symbol.cpp @@ -19,6 +19,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataEncoder.h" #include "lldb/Utility/Stream.h" +#include "llvm/ADT/StringSwitch.h" using namespace lldb; using namespace lldb_private; @@ -95,6 +96,55 @@ const Symbol &Symbol::operator=(const Symbol &rhs) { return *this; } +llvm::Expected<Symbol> Symbol::FromJSON(const JSONSymbol &symbol, + SectionList *section_list) { + if (!section_list) + return llvm::make_error<llvm::StringError>("no section list provided", + llvm::inconvertibleErrorCode()); + + if (!symbol.value && !symbol.address) + return llvm::make_error<llvm::StringError>( + "symbol must contain either a value or an address", + llvm::inconvertibleErrorCode()); + + if (symbol.value && symbol.address) + return llvm::make_error<llvm::StringError>( + "symbol cannot contain both a value and an address", + llvm::inconvertibleErrorCode()); + + const uint64_t size = symbol.size.value_or(0); + const bool is_artificial = false; + const bool is_trampoline = false; + const bool is_debug = false; + const bool external = false; + const bool size_is_valid = symbol.size.has_value(); + const bool contains_linker_annotations = false; + const uint32_t flags = 0; + + if (symbol.address) { + if (SectionSP section_sp = + section_list->FindSectionContainingFileAddress(*symbol.address)) { + const uint64_t offset = *symbol.address - section_sp->GetFileAddress(); + return Symbol(symbol.id.value_or(0), Mangled(symbol.name), + symbol.type.value_or(eSymbolTypeAny), external, is_debug, + is_trampoline, is_artificial, + AddressRange(section_sp, offset, size), size_is_valid, + contains_linker_annotations, flags); + } + return llvm::make_error<llvm::StringError>( + llvm::formatv("no section found for address: {0:x}", *symbol.address), + llvm::inconvertibleErrorCode()); + } + + // Absolute symbols encode the integer value in the m_offset of the + // AddressRange object and the section is set to nothing. + return Symbol(symbol.id.value_or(0), Mangled(symbol.name), + symbol.type.value_or(eSymbolTypeAny), external, is_debug, + is_trampoline, is_artificial, + AddressRange(SectionSP(), *symbol.value, size), size_is_valid, + contains_linker_annotations, flags); +} + void Symbol::Clear() { m_uid = UINT32_MAX; m_mangled.Clear(); @@ -438,15 +488,9 @@ Symbol *Symbol::ResolveReExportedSymbolInModuleSpec( lldb_private::SymbolContextList sc_list; module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list); - const size_t num_scs = sc_list.GetSize(); - if (num_scs > 0) { - for (size_t i = 0; i < num_scs; ++i) { - lldb_private::SymbolContext sc; - if (sc_list.GetContextAtIndex(i, sc)) { - if (sc.symbol->IsExternal()) - return sc.symbol; - } - } + for (const SymbolContext &sc : sc_list) { + if (sc.symbol->IsExternal()) + return sc.symbol; } // If we didn't find the symbol in this module, it may be because this // module re-exports some whole other library. We have to search those as @@ -622,14 +666,14 @@ bool Symbol::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, const bool is_addr = data.GetU8(offset_ptr) != 0; const uint64_t value = data.GetU64(offset_ptr); if (is_addr) { - m_addr_range.GetBaseAddress().ResolveAddressUsingFileSections( - value, section_list); + m_addr_range.GetBaseAddress().ResolveAddressUsingFileSections(value, + section_list); } else { m_addr_range.GetBaseAddress().Clear(); m_addr_range.GetBaseAddress().SetOffset(value); } m_addr_range.SetByteSize(data.GetU64(offset_ptr)); - m_flags = data.GetU32(offset_ptr); + m_flags = data.GetU32(offset_ptr); return true; } @@ -723,3 +767,77 @@ bool Symbol::operator==(const Symbol &rhs) const { return false; return true; } + +namespace llvm { +namespace json { + +bool fromJSON(const llvm::json::Value &value, lldb_private::JSONSymbol &symbol, + llvm::json::Path path) { + llvm::json::ObjectMapper o(value, path); + const bool mapped = o && o.map("value", symbol.value) && + o.map("address", symbol.address) && + o.map("size", symbol.size) && o.map("id", symbol.id) && + o.map("type", symbol.type) && o.map("name", symbol.name); + + if (!mapped) + return false; + + if (!symbol.value && !symbol.address) { + path.report("symbol must have either a value or an address"); + return false; + } + + if (symbol.value && symbol.address) { + path.report("symbol cannot have both a value and an address"); + return false; + } + + return true; +} + +bool fromJSON(const llvm::json::Value &value, lldb::SymbolType &type, + llvm::json::Path path) { + if (auto str = value.getAsString()) { + type = llvm::StringSwitch<lldb::SymbolType>(*str) + .Case("absolute", eSymbolTypeAbsolute) + .Case("code", eSymbolTypeCode) + .Case("resolver", eSymbolTypeResolver) + .Case("data", eSymbolTypeData) + .Case("trampoline", eSymbolTypeTrampoline) + .Case("runtime", eSymbolTypeRuntime) + .Case("exception", eSymbolTypeException) + .Case("sourcefile", eSymbolTypeSourceFile) + .Case("headerfile", eSymbolTypeHeaderFile) + .Case("objectfile", eSymbolTypeObjectFile) + .Case("commonblock", eSymbolTypeCommonBlock) + .Case("block", eSymbolTypeBlock) + .Case("local", eSymbolTypeLocal) + .Case("param", eSymbolTypeParam) + .Case("variable", eSymbolTypeVariable) + .Case("variableType", eSymbolTypeVariableType) + .Case("lineentry", eSymbolTypeLineEntry) + .Case("lineheader", eSymbolTypeLineHeader) + .Case("scopebegin", eSymbolTypeScopeBegin) + .Case("scopeend", eSymbolTypeScopeEnd) + .Case("additional,", eSymbolTypeAdditional) + .Case("compiler", eSymbolTypeCompiler) + .Case("instrumentation", eSymbolTypeInstrumentation) + .Case("undefined", eSymbolTypeUndefined) + .Case("objcclass", eSymbolTypeObjCClass) + .Case("objcmetaClass", eSymbolTypeObjCMetaClass) + .Case("objcivar", eSymbolTypeObjCIVar) + .Case("reexporte", eSymbolTypeReExported) + .Default(eSymbolTypeInvalid); + + if (type == eSymbolTypeInvalid) { + path.report("invalid symbol type"); + return false; + } + + return true; + } + path.report("expected string"); + return false; +} +} // namespace json +} // namespace llvm diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp index 2ccc248d839e..63968ec2d150 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolContext.cpp @@ -19,10 +19,12 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Variable.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" +#include "lldb/lldb-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -539,19 +541,20 @@ Block *SymbolContext::GetFunctionBlock() { return nullptr; } -bool SymbolContext::GetFunctionMethodInfo(lldb::LanguageType &language, - bool &is_instance_method, - ConstString &language_object_name) - -{ - Block *function_block = GetFunctionBlock(); - if (function_block) { - CompilerDeclContext decl_ctx = function_block->GetDeclContext(); - if (decl_ctx) - return decl_ctx.IsClassMethod(&language, &is_instance_method, - &language_object_name); - } - return false; +llvm::StringRef SymbolContext::GetInstanceVariableName() { + LanguageType lang_type = eLanguageTypeUnknown; + + if (Block *function_block = GetFunctionBlock()) + if (CompilerDeclContext decl_ctx = function_block->GetDeclContext()) + lang_type = decl_ctx.GetLanguage(); + + if (lang_type == eLanguageTypeUnknown) + lang_type = GetLanguage(); + + if (auto *lang = Language::FindPlugin(lang_type)) + return lang->GetInstanceVariableName(); + + return {}; } void SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list) const { @@ -768,14 +771,11 @@ const Symbol *SymbolContext::FindBestGlobalDataSymbol(ConstString name, Module *module = module_sp.get(); auto ProcessMatches = [this, &name, &target, - module](SymbolContextList &sc_list, + module](const SymbolContextList &sc_list, Status &error) -> const Symbol * { llvm::SmallVector<const Symbol *, 1> external_symbols; llvm::SmallVector<const Symbol *, 1> internal_symbols; - const uint32_t matches = sc_list.GetSize(); - for (uint32_t i = 0; i < matches; ++i) { - SymbolContext sym_ctx; - sc_list.GetContextAtIndex(i, sym_ctx); + for (const SymbolContext &sym_ctx : sc_list) { if (sym_ctx.symbol) { const Symbol *symbol = sym_ctx.symbol; const Address sym_address = symbol->GetAddress(); diff --git a/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp b/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp index aa3d23ccbf4d..d3694580194f 100644 --- a/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/SymbolFileOnDemand.cpp @@ -483,13 +483,16 @@ SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language) { CompilerDeclContext SymbolFileOnDemand::FindNamespace(ConstString name, - const CompilerDeclContext &parent_decl_ctx) { + const CompilerDeclContext &parent_decl_ctx, + bool only_root_namespaces) { if (!m_debug_info_enabled) { LLDB_LOG(GetLog(), "[{0}] {1}({2}) is skipped", GetSymbolFileName(), __FUNCTION__, name); - return SymbolFile::FindNamespace(name, parent_decl_ctx); + return SymbolFile::FindNamespace(name, parent_decl_ctx, + only_root_namespaces); } - return m_sym_file_impl->FindNamespace(name, parent_decl_ctx); + return m_sym_file_impl->FindNamespace(name, parent_decl_ctx, + only_root_namespaces); } std::vector<std::unique_ptr<lldb_private::CallEdge>> diff --git a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp index 40777e03be78..cf8732530c1a 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Symtab.cpp @@ -80,8 +80,7 @@ size_t Symtab::GetNumSymbols() const { } void Symtab::SectionFileAddressesChanged() { - auto &name_to_index = GetNameToSymbolIndexMap(lldb::eFunctionNameTypeNone); - name_to_index.Clear(); + m_file_addr_to_index.Clear(); m_file_addr_to_index_computed = false; } diff --git a/contrib/llvm-project/lldb/source/Symbol/Type.cpp b/contrib/llvm-project/lldb/source/Symbol/Type.cpp index f901c24298a3..66284eb73cad 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Type.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Type.cpp @@ -546,8 +546,9 @@ 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(GetLog(LLDBLog::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: {0}"); } else { CompilerType void_compiler_type; auto ts = *type_system_or_err; diff --git a/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp b/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp index 4eae2c98b12e..24f202930565 100644 --- a/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/TypeSystem.cpp @@ -36,6 +36,7 @@ size_t LanguageSet::Size() const { return bitvector.count(); } bool LanguageSet::Empty() const { return bitvector.none(); } bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; } +TypeSystem::TypeSystem() = default; TypeSystem::~TypeSystem() = default; static TypeSystemSP CreateInstanceHelper(lldb::LanguageType language, @@ -216,11 +217,21 @@ void TypeSystemMap::Clear() { void TypeSystemMap::ForEach( std::function<bool(lldb::TypeSystemSP)> const &callback) { - std::lock_guard<std::mutex> guard(m_mutex); + + // The callback may call into this function again causing + // us to lock m_mutex twice if we held it across the callback. + // Since we just care about guarding access to 'm_map', make + // a local copy and iterate over that instead. + collection map_snapshot; + { + std::lock_guard<std::mutex> guard(m_mutex); + map_snapshot = m_map; + } + // Use a std::set so we only call the callback once for each unique // TypeSystem instance. llvm::DenseSet<TypeSystem *> visited; - for (auto &pair : m_map) { + for (auto &pair : map_snapshot) { TypeSystem *type_system = pair.second.get(); if (!type_system || visited.count(type_system)) continue; diff --git a/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp b/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp index 268f95f71eb4..3c1a5187b110 100644 --- a/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/UnwindTable.cpp @@ -86,8 +86,8 @@ void UnwindTable::Initialize() { UnwindTable::~UnwindTable() = default; -std::optional<AddressRange> UnwindTable::GetAddressRange(const Address &addr, - SymbolContext &sc) { +std::optional<AddressRange> +UnwindTable::GetAddressRange(const Address &addr, const SymbolContext &sc) { AddressRange range; // First check the unwind info from the object file plugin @@ -150,9 +150,8 @@ UnwindTable::GetFuncUnwindersContainingAddress(const Address &addr, // don't add it to the UnwindTable. This is intended for use by target modules // show-unwind where we want to create new UnwindPlans, not re-use existing // ones. -FuncUnwindersSP -UnwindTable::GetUncachedFuncUnwindersContainingAddress(const Address &addr, - SymbolContext &sc) { +FuncUnwindersSP UnwindTable::GetUncachedFuncUnwindersContainingAddress( + const Address &addr, const SymbolContext &sc) { Initialize(); auto range_or = GetAddressRange(addr, sc); diff --git a/contrib/llvm-project/lldb/source/Symbol/Variable.cpp b/contrib/llvm-project/lldb/source/Symbol/Variable.cpp index 5e1996b13bcc..85ceadd20c61 100644 --- a/contrib/llvm-project/lldb/source/Symbol/Variable.cpp +++ b/contrib/llvm-project/lldb/source/Symbol/Variable.cpp @@ -380,9 +380,8 @@ Status Variable::GetValuesForVariableExpressionPath( llvm::SmallVector<llvm::StringRef, 2> matches; variable_list.Clear(); if (!g_regex.Execute(variable_expr_path, &matches)) { - error.SetErrorStringWithFormat( - "unable to extract a variable name from '%s'", - variable_expr_path.str().c_str()); + error.SetErrorStringWithFormatv( + "unable to extract a variable name from '{0}'", variable_expr_path); return error; } std::string variable_name = matches[1].str(); @@ -411,10 +410,9 @@ Status Variable::GetValuesForVariableExpressionPath( valobj_sp = variable_valobj_sp->GetValueForExpressionPath( variable_sub_expr_path); if (!valobj_sp) { - error.SetErrorStringWithFormat( - "invalid expression path '%s' for variable '%s'", - variable_sub_expr_path.str().c_str(), - var_sp->GetName().GetCString()); + error.SetErrorStringWithFormatv( + "invalid expression path '{0}' for variable '{1}'", + variable_sub_expr_path, var_sp->GetName().GetCString()); variable_list.RemoveVariableAtIndex(i); continue; } diff --git a/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp b/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp index 14c3faae38df..d577e20b3740 100644 --- a/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp +++ b/contrib/llvm-project/lldb/source/Target/DynamicRegisterInfo.cpp @@ -20,10 +20,17 @@ using namespace lldb; using namespace lldb_private; -DynamicRegisterInfo::DynamicRegisterInfo( - const lldb_private::StructuredData::Dictionary &dict, - const lldb_private::ArchSpec &arch) { - SetRegisterInfo(dict, arch); +std::unique_ptr<DynamicRegisterInfo> +DynamicRegisterInfo::Create(const StructuredData::Dictionary &dict, + const ArchSpec &arch) { + auto dyn_reg_info = std::make_unique<DynamicRegisterInfo>(); + if (!dyn_reg_info) + return nullptr; + + if (dyn_reg_info->SetRegisterInfo(dict, arch) == 0) + return nullptr; + + return dyn_reg_info; } DynamicRegisterInfo::DynamicRegisterInfo(DynamicRegisterInfo &&info) { @@ -238,17 +245,20 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, std::vector<uint32_t> invalidate_regs; memset(®_info, 0, sizeof(reg_info)); - ConstString name_val; - ConstString alt_name_val; - if (!reg_info_dict->GetValueForKeyAsString("name", name_val, nullptr)) { + llvm::StringRef name_val; + if (!reg_info_dict->GetValueForKeyAsString("name", name_val)) { Clear(); printf("error: registers must have valid names and offsets\n"); reg_info_dict->DumpToStdout(); return 0; } - reg_info.name = name_val.GetCString(); - reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val, nullptr); - reg_info.alt_name = alt_name_val.GetCString(); + reg_info.name = ConstString(name_val).GetCString(); + + llvm::StringRef alt_name_val; + if (reg_info_dict->GetValueForKeyAsString("alt-name", alt_name_val)) + reg_info.alt_name = ConstString(alt_name_val).GetCString(); + else + reg_info.alt_name = nullptr; llvm::Expected<uint32_t> byte_offset = ByteOffsetFromRegInfoDict(i, *reg_info_dict, byte_order); @@ -262,7 +272,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, return 0; } - int64_t bitsize = 0; + uint64_t bitsize = 0; if (!reg_info_dict->GetValueForKeyAsInteger("bitsize", bitsize)) { Clear(); printf("error: invalid or missing 'bitsize' key/value pair in register " @@ -296,7 +306,7 @@ DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, eEncodingUint); size_t set = 0; - if (!reg_info_dict->GetValueForKeyAsInteger<size_t>("set", set, -1) || + if (!reg_info_dict->GetValueForKeyAsInteger("set", set) || set >= m_sets.size()) { Clear(); printf("error: invalid 'set' value in register dictionary, valid values " @@ -407,7 +417,7 @@ size_t DynamicRegisterInfo::SetRegisterInfo( {reg.regnum_ehframe, reg.regnum_dwarf, reg.regnum_generic, reg.regnum_remote, local_regnum}, // value_regs and invalidate_regs are filled by Finalize() - nullptr, nullptr + nullptr, nullptr, reg.flags_type }; m_regs.push_back(reg_info); diff --git a/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp b/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp index a5288b81cd17..b1563d9ceb71 100644 --- a/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp +++ b/contrib/llvm-project/lldb/source/Target/ExecutionContext.cpp @@ -85,7 +85,8 @@ ExecutionContext::ExecutionContext(Target *t, if (m_process_sp) { m_thread_sp = m_process_sp->GetThreadList().GetSelectedThread(); if (m_thread_sp) - m_frame_sp = m_thread_sp->GetSelectedFrame(); + m_frame_sp = + m_thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); } } } @@ -517,7 +518,8 @@ void ExecutionContextRef::SetTargetPtr(Target *target, bool adopt_selected) { if (thread_sp) { SetThreadSP(thread_sp); - lldb::StackFrameSP frame_sp(thread_sp->GetSelectedFrame()); + lldb::StackFrameSP frame_sp( + thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame)); if (!frame_sp) frame_sp = thread_sp->GetStackFrameAtIndex(0); if (frame_sp) diff --git a/contrib/llvm-project/lldb/source/Target/Language.cpp b/contrib/llvm-project/lldb/source/Target/Language.cpp index 892d2a86437e..78785352676d 100644 --- a/contrib/llvm-project/lldb/source/Target/Language.cpp +++ b/contrib/llvm-project/lldb/source/Target/Language.cpp @@ -194,9 +194,27 @@ struct language_name_pair language_names[] = { {"c++14", eLanguageTypeC_plus_plus_14}, {"fortran03", eLanguageTypeFortran03}, {"fortran08", eLanguageTypeFortran08}, + {"renderscript", eLanguageTypeRenderScript}, + {"bliss", eLanguageTypeBLISS}, + {"kotlin", eLanguageTypeKotlin}, + {"zig", eLanguageTypeZig}, + {"crystal", eLanguageTypeCrystal}, + {"<invalid language>", + static_cast<LanguageType>( + 0x0029)}, // Not yet taken by any language in the DWARF spec + // and thus has no entry in LanguageType + {"c++17", eLanguageTypeC_plus_plus_17}, + {"c++20", eLanguageTypeC_plus_plus_20}, + {"c17", eLanguageTypeC17}, + {"fortran18", eLanguageTypeFortran18}, + {"ada2005", eLanguageTypeAda2005}, + {"ada2012", eLanguageTypeAda2012}, + {"HIP", eLanguageTypeHIP}, + {"assembly", eLanguageTypeAssembly}, + {"c-sharp", eLanguageTypeC_sharp}, + {"mojo", eLanguageTypeMojo}, // Vendor Extensions {"assembler", eLanguageTypeMipsAssembler}, - {"renderscript", eLanguageTypeExtRenderScript}, // Now synonyms, in arbitrary order {"objc", eLanguageTypeObjC}, {"objc++", eLanguageTypeObjC_plus_plus}, @@ -253,6 +271,8 @@ bool Language::LanguageIsCPlusPlus(LanguageType language) { case eLanguageTypeC_plus_plus_03: case eLanguageTypeC_plus_plus_11: case eLanguageTypeC_plus_plus_14: + case eLanguageTypeC_plus_plus_17: + case eLanguageTypeC_plus_plus_20: case eLanguageTypeObjC_plus_plus: return true; default: @@ -292,6 +312,8 @@ bool Language::LanguageIsCFamily(LanguageType language) { case eLanguageTypeC_plus_plus_03: case eLanguageTypeC_plus_plus_11: case eLanguageTypeC_plus_plus_14: + case eLanguageTypeC_plus_plus_17: + case eLanguageTypeC_plus_plus_20: case eLanguageTypeObjC_plus_plus: case eLanguageTypeObjC: return true; @@ -315,6 +337,8 @@ LanguageType Language::GetPrimaryLanguage(LanguageType language) { case eLanguageTypeC_plus_plus_03: case eLanguageTypeC_plus_plus_11: case eLanguageTypeC_plus_plus_14: + case eLanguageTypeC_plus_plus_17: + case eLanguageTypeC_plus_plus_20: return eLanguageTypeC_plus_plus; case eLanguageTypeC: case eLanguageTypeC89: @@ -350,7 +374,6 @@ LanguageType Language::GetPrimaryLanguage(LanguageType language) { case eLanguageTypeJulia: case eLanguageTypeDylan: case eLanguageTypeMipsAssembler: - case eLanguageTypeExtRenderScript: case eLanguageTypeUnknown: default: return language; @@ -432,19 +455,17 @@ bool Language::ImageListTypeScavenger::Find_Impl( return result; } -bool Language::GetFormatterPrefixSuffix(ValueObject &valobj, - ConstString type_hint, - std::string &prefix, - std::string &suffix) { - return false; +std::pair<llvm::StringRef, llvm::StringRef> +Language::GetFormatterPrefixSuffix(llvm::StringRef type_hint) { + return std::pair<llvm::StringRef, llvm::StringRef>(); } -bool Language::DemangledNameContainsPath(llvm::StringRef path, +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); + return demangled.GetStringRef().contains(path); } DumpValueObjectOptions::DeclPrintingHelper Language::GetDeclPrintingHelper() { diff --git a/contrib/llvm-project/lldb/source/Target/Memory.cpp b/contrib/llvm-project/lldb/source/Target/Memory.cpp index d4dedeea7c2c..45786415d23b 100644 --- a/contrib/llvm-project/lldb/source/Target/Memory.cpp +++ b/contrib/llvm-project/lldb/source/Target/Memory.cpp @@ -123,18 +123,55 @@ bool MemoryCache::RemoveInvalidRange(lldb::addr_t base_addr, return false; } +lldb::DataBufferSP MemoryCache::GetL2CacheLine(lldb::addr_t line_base_addr, + Status &error) { + // This function assumes that the address given is aligned correctly. + assert((line_base_addr % m_L2_cache_line_byte_size) == 0); + + std::lock_guard<std::recursive_mutex> guard(m_mutex); + auto pos = m_L2_cache.find(line_base_addr); + if (pos != m_L2_cache.end()) + return pos->second; + + auto data_buffer_heap_sp = + std::make_shared<DataBufferHeap>(m_L2_cache_line_byte_size, 0); + size_t process_bytes_read = m_process.ReadMemoryFromInferior( + line_base_addr, data_buffer_heap_sp->GetBytes(), + data_buffer_heap_sp->GetByteSize(), error); + + // If we failed a read, not much we can do. + if (process_bytes_read == 0) + return lldb::DataBufferSP(); + + // If we didn't get a complete read, we can still cache what we did get. + if (process_bytes_read < m_L2_cache_line_byte_size) + data_buffer_heap_sp->SetByteSize(process_bytes_read); + + m_L2_cache[line_base_addr] = data_buffer_heap_sp; + return data_buffer_heap_sp; +} + size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len, Status &error) { - size_t bytes_left = dst_len; - - // Check the L1 cache for a range that contain the entire memory read. If we - // find a range in the L1 cache that does, we use it. Else we fall back to - // reading memory in m_L2_cache_line_byte_size byte sized chunks. The L1 - // cache contains chunks of memory that are not required to be - // m_L2_cache_line_byte_size bytes in size, so we don't try anything tricky - // when reading from them (no partial reads from the L1 cache). + if (!dst || dst_len == 0) + return 0; std::lock_guard<std::recursive_mutex> guard(m_mutex); + // FIXME: We should do a more thorough check to make sure that we're not + // overlapping with any invalid ranges (e.g. Read 0x100 - 0x200 but there's an + // invalid range 0x180 - 0x280). `FindEntryThatContains` has an implementation + // that takes a range, but it only checks to see if the argument is contained + // by an existing invalid range. It cannot check if the argument contains + // invalid ranges and cannot check for overlaps. + if (m_invalid_ranges.FindEntryThatContains(addr)) { + error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, addr); + return 0; + } + + // Check the L1 cache for a range that contains the entire memory read. + // L1 cache contains chunks of memory that are not required to be the size of + // an L2 cache line. We avoid trying to do partial reads from the L1 cache to + // simplify the implementation. if (!m_L1_cache.empty()) { AddrRange read_range(addr, dst_len); BlockMap::iterator pos = m_L1_cache.upper_bound(addr); @@ -149,105 +186,82 @@ size_t MemoryCache::Read(addr_t addr, void *dst, size_t dst_len, } } - // If this memory read request is larger than the cache line size, then we - // (1) try to read as much of it at once as possible, and (2) don't add the - // data to the memory cache. We don't want to split a big read up into more - // separate reads than necessary, and with a large memory read request, it is - // unlikely that the caller function will ask for the next - // 4 bytes after the large memory read - so there's little benefit to saving - // it in the cache. - if (dst && dst_len > m_L2_cache_line_byte_size) { + // If the size of the read is greater than the size of an L2 cache line, we'll + // just read from the inferior. If that read is successful, we'll cache what + // we read in the L1 cache for future use. + if (dst_len > m_L2_cache_line_byte_size) { size_t bytes_read = m_process.ReadMemoryFromInferior(addr, dst, dst_len, error); - // Add this non block sized range to the L1 cache if we actually read - // anything if (bytes_read > 0) AddL1CacheData(addr, dst, bytes_read); return bytes_read; } - if (dst && bytes_left > 0) { - const uint32_t cache_line_byte_size = m_L2_cache_line_byte_size; - uint8_t *dst_buf = (uint8_t *)dst; - addr_t curr_addr = addr - (addr % cache_line_byte_size); - addr_t cache_offset = addr - curr_addr; - - while (bytes_left > 0) { - if (m_invalid_ranges.FindEntryThatContains(curr_addr)) { - error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, - curr_addr); - return dst_len - bytes_left; - } - - BlockMap::const_iterator pos = m_L2_cache.find(curr_addr); - BlockMap::const_iterator end = m_L2_cache.end(); - - if (pos != end) { - size_t curr_read_size = cache_line_byte_size - cache_offset; - if (curr_read_size > bytes_left) - curr_read_size = bytes_left; - - memcpy(dst_buf + dst_len - bytes_left, - pos->second->GetBytes() + cache_offset, curr_read_size); - - bytes_left -= curr_read_size; - curr_addr += curr_read_size + cache_offset; - cache_offset = 0; - - if (bytes_left > 0) { - // Get sequential cache page hits - for (++pos; (pos != end) && (bytes_left > 0); ++pos) { - assert((curr_addr % cache_line_byte_size) == 0); - - if (pos->first != curr_addr) - break; - - curr_read_size = pos->second->GetByteSize(); - if (curr_read_size > bytes_left) - curr_read_size = bytes_left; + // If the size of the read fits inside one L2 cache line, we'll try reading + // from the L2 cache. Note that if the range of memory we're reading sits + // between two contiguous cache lines, we'll touch two cache lines instead of + // just one. + + // We're going to have all of our loads and reads be cache line aligned. + addr_t cache_line_offset = addr % m_L2_cache_line_byte_size; + addr_t cache_line_base_addr = addr - cache_line_offset; + DataBufferSP first_cache_line = GetL2CacheLine(cache_line_base_addr, error); + // If we get nothing, then the read to the inferior likely failed. Nothing to + // do here. + if (!first_cache_line) + return 0; + + // If the cache line was not filled out completely and the offset is greater + // than what we have available, we can't do anything further here. + if (cache_line_offset >= first_cache_line->GetByteSize()) + return 0; + + uint8_t *dst_buf = (uint8_t *)dst; + size_t bytes_left = dst_len; + size_t read_size = first_cache_line->GetByteSize() - cache_line_offset; + if (read_size > bytes_left) + read_size = bytes_left; + + memcpy(dst_buf + dst_len - bytes_left, + first_cache_line->GetBytes() + cache_line_offset, read_size); + bytes_left -= read_size; + + // If the cache line was not filled out completely and we still have data to + // read, we can't do anything further. + if (first_cache_line->GetByteSize() < m_L2_cache_line_byte_size && + bytes_left > 0) + return dst_len - bytes_left; + + // We'll hit this scenario if our read straddles two cache lines. + if (bytes_left > 0) { + cache_line_base_addr += m_L2_cache_line_byte_size; + + // FIXME: Until we are able to more thoroughly check for invalid ranges, we + // will have to check the second line to see if it is in an invalid range as + // well. See the check near the beginning of the function for more details. + if (m_invalid_ranges.FindEntryThatContains(cache_line_base_addr)) { + error.SetErrorStringWithFormat("memory read failed for 0x%" PRIx64, + cache_line_base_addr); + return dst_len - bytes_left; + } - memcpy(dst_buf + dst_len - bytes_left, pos->second->GetBytes(), - curr_read_size); + DataBufferSP second_cache_line = + GetL2CacheLine(cache_line_base_addr, error); + if (!second_cache_line) + return dst_len - bytes_left; - bytes_left -= curr_read_size; - curr_addr += curr_read_size; + read_size = bytes_left; + if (read_size > second_cache_line->GetByteSize()) + read_size = second_cache_line->GetByteSize(); - // We have a cache page that succeeded to read some bytes but not - // an entire page. If this happens, we must cap off how much data - // we are able to read... - if (pos->second->GetByteSize() != cache_line_byte_size) - return dst_len - bytes_left; - } - } - } + memcpy(dst_buf + dst_len - bytes_left, second_cache_line->GetBytes(), + read_size); + bytes_left -= read_size; - // We need to read from the process - - if (bytes_left > 0) { - assert((curr_addr % cache_line_byte_size) == 0); - std::unique_ptr<DataBufferHeap> data_buffer_heap_up( - new DataBufferHeap(cache_line_byte_size, 0)); - size_t process_bytes_read = m_process.ReadMemoryFromInferior( - curr_addr, data_buffer_heap_up->GetBytes(), - data_buffer_heap_up->GetByteSize(), error); - if (process_bytes_read == 0) - return dst_len - bytes_left; - - if (process_bytes_read != cache_line_byte_size) { - if (process_bytes_read < data_buffer_heap_up->GetByteSize()) { - dst_len -= data_buffer_heap_up->GetByteSize() - process_bytes_read; - bytes_left = process_bytes_read; - } - data_buffer_heap_up->SetByteSize(process_bytes_read); - } - m_L2_cache[curr_addr] = DataBufferSP(data_buffer_heap_up.release()); - // We have read data and put it into the cache, continue through the - // loop again to get the data out of the cache... - } - } + return dst_len - bytes_left; } - return dst_len - bytes_left; + return dst_len; } AllocatedBlock::AllocatedBlock(lldb::addr_t addr, uint32_t byte_size, diff --git a/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp b/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp index 13bb50b362c6..c369018122a5 100644 --- a/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp +++ b/contrib/llvm-project/lldb/source/Target/PathMappingList.cpp @@ -48,6 +48,7 @@ PathMappingList::PathMappingList(const PathMappingList &rhs) const PathMappingList &PathMappingList::operator=(const PathMappingList &rhs) { if (this != &rhs) { + std::scoped_lock<std::recursive_mutex, std::recursive_mutex> locks(m_mutex, rhs.m_mutex); m_pairs = rhs.m_pairs; m_callback = nullptr; m_callback_baton = nullptr; @@ -60,6 +61,7 @@ PathMappingList::~PathMappingList() = default; void PathMappingList::Append(llvm::StringRef path, llvm::StringRef replacement, bool notify) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); ++m_mod_id; m_pairs.emplace_back(pair(NormalizePath(path), NormalizePath(replacement))); if (notify && m_callback) @@ -67,6 +69,7 @@ void PathMappingList::Append(llvm::StringRef path, llvm::StringRef replacement, } void PathMappingList::Append(const PathMappingList &rhs, bool notify) { + std::scoped_lock<std::recursive_mutex, std::recursive_mutex> locks(m_mutex, rhs.m_mutex); ++m_mod_id; if (!rhs.m_pairs.empty()) { const_iterator pos, end = rhs.m_pairs.end(); @@ -81,6 +84,7 @@ bool PathMappingList::AppendUnique(llvm::StringRef path, llvm::StringRef replacement, bool notify) { auto normalized_path = NormalizePath(path); auto normalized_replacement = NormalizePath(replacement); + std::lock_guard<std::recursive_mutex> lock(m_mutex); for (const auto &pair : m_pairs) { if (pair.first.GetStringRef().equals(normalized_path) && pair.second.GetStringRef().equals(normalized_replacement)) @@ -92,6 +96,7 @@ bool PathMappingList::AppendUnique(llvm::StringRef path, void PathMappingList::Insert(llvm::StringRef path, llvm::StringRef replacement, uint32_t index, bool notify) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); ++m_mod_id; iterator insert_iter; if (index >= m_pairs.size()) @@ -106,6 +111,7 @@ void PathMappingList::Insert(llvm::StringRef path, llvm::StringRef replacement, bool PathMappingList::Replace(llvm::StringRef path, llvm::StringRef replacement, uint32_t index, bool notify) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); if (index >= m_pairs.size()) return false; ++m_mod_id; @@ -116,6 +122,7 @@ bool PathMappingList::Replace(llvm::StringRef path, llvm::StringRef replacement, } bool PathMappingList::Remove(size_t index, bool notify) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); if (index >= m_pairs.size()) return false; @@ -130,6 +137,7 @@ bool PathMappingList::Remove(size_t index, bool notify) { // For clients which do not need the pair index dumped, pass a pair_index >= 0 // to only dump the indicated pair. void PathMappingList::Dump(Stream *s, int pair_index) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); unsigned int numPairs = m_pairs.size(); if (pair_index < 0) { @@ -147,6 +155,7 @@ void PathMappingList::Dump(Stream *s, int pair_index) { llvm::json::Value PathMappingList::ToJSON() { llvm::json::Array entries; + std::lock_guard<std::recursive_mutex> lock(m_mutex); for (const auto &pair : m_pairs) { llvm::json::Array entry{pair.first.GetStringRef().str(), pair.second.GetStringRef().str()}; @@ -156,6 +165,7 @@ llvm::json::Value PathMappingList::ToJSON() { } void PathMappingList::Clear(bool notify) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); if (!m_pairs.empty()) ++m_mod_id; m_pairs.clear(); @@ -186,6 +196,7 @@ static void AppendPathComponents(FileSpec &path, llvm::StringRef components, std::optional<FileSpec> PathMappingList::RemapPath(llvm::StringRef mapping_path, bool only_if_exists) const { + std::lock_guard<std::recursive_mutex> lock(m_mutex); if (m_pairs.empty() || mapping_path.empty()) return {}; LazyBool path_is_relative = eLazyBoolCalculate; @@ -224,6 +235,7 @@ std::optional<llvm::StringRef> PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) const { std::string path = file.GetPath(); llvm::StringRef path_ref(path); + std::lock_guard<std::recursive_mutex> lock(m_mutex); for (const auto &it : m_pairs) { llvm::StringRef removed_prefix = it.second.GetStringRef(); if (!path_ref.consume_front(it.second.GetStringRef())) @@ -252,6 +264,7 @@ PathMappingList::FindFile(const FileSpec &orig_spec) const { bool PathMappingList::Replace(llvm::StringRef path, llvm::StringRef new_path, bool notify) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); uint32_t idx = FindIndexForPath(path); if (idx < m_pairs.size()) { ++m_mod_id; @@ -264,6 +277,7 @@ bool PathMappingList::Replace(llvm::StringRef path, llvm::StringRef new_path, } bool PathMappingList::Remove(ConstString path, bool notify) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); iterator pos = FindIteratorForPath(path); if (pos != m_pairs.end()) { ++m_mod_id; @@ -277,6 +291,7 @@ bool PathMappingList::Remove(ConstString path, bool notify) { PathMappingList::const_iterator PathMappingList::FindIteratorForPath(ConstString path) const { + std::lock_guard<std::recursive_mutex> lock(m_mutex); const_iterator pos; const_iterator begin = m_pairs.begin(); const_iterator end = m_pairs.end(); @@ -290,6 +305,7 @@ PathMappingList::FindIteratorForPath(ConstString path) const { PathMappingList::iterator PathMappingList::FindIteratorForPath(ConstString path) { + std::lock_guard<std::recursive_mutex> lock(m_mutex); iterator pos; iterator begin = m_pairs.begin(); iterator end = m_pairs.end(); @@ -303,6 +319,7 @@ PathMappingList::FindIteratorForPath(ConstString path) { bool PathMappingList::GetPathsAtIndex(uint32_t idx, ConstString &path, ConstString &new_path) const { + std::lock_guard<std::recursive_mutex> lock(m_mutex); if (idx < m_pairs.size()) { path = m_pairs[idx].first; new_path = m_pairs[idx].second; @@ -313,6 +330,7 @@ bool PathMappingList::GetPathsAtIndex(uint32_t idx, ConstString &path, uint32_t PathMappingList::FindIndexForPath(llvm::StringRef orig_path) const { const ConstString path = ConstString(NormalizePath(orig_path)); + std::lock_guard<std::recursive_mutex> lock(m_mutex); const_iterator pos; const_iterator begin = m_pairs.begin(); const_iterator end = m_pairs.end(); diff --git a/contrib/llvm-project/lldb/source/Target/Platform.cpp b/contrib/llvm-project/lldb/source/Target/Platform.cpp index 1ddd7596280e..11a123fb6d58 100644 --- a/contrib/llvm-project/lldb/source/Target/Platform.cpp +++ b/contrib/llvm-project/lldb/source/Target/Platform.cpp @@ -99,29 +99,27 @@ PlatformProperties::PlatformProperties() { bool PlatformProperties::GetUseModuleCache() const { const auto idx = ePropertyUseModuleCache; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_platform_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_platform_properties[idx].default_uint_value != 0); } bool PlatformProperties::SetUseModuleCache(bool use_module_cache) { - return m_collection_sp->SetPropertyAtIndexAsBoolean( - nullptr, ePropertyUseModuleCache, use_module_cache); + return SetPropertyAtIndex(ePropertyUseModuleCache, use_module_cache); } FileSpec PlatformProperties::GetModuleCacheDirectory() const { - return m_collection_sp->GetPropertyAtIndexAsFileSpec( - nullptr, ePropertyModuleCacheDirectory); + return GetPropertyAtIndexAs<FileSpec>(ePropertyModuleCacheDirectory, {}); } bool PlatformProperties::SetModuleCacheDirectory(const FileSpec &dir_spec) { - return m_collection_sp->SetPropertyAtIndexAsFileSpec( - nullptr, ePropertyModuleCacheDirectory, dir_spec); + return m_collection_sp->SetPropertyAtIndex(ePropertyModuleCacheDirectory, + dir_spec); } void PlatformProperties::SetDefaultModuleCacheDirectory( const FileSpec &dir_spec) { auto f_spec_opt = m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec( - nullptr, false, ePropertyModuleCacheDirectory); + ePropertyModuleCacheDirectory); assert(f_spec_opt); f_spec_opt->SetDefaultValue(dir_spec); } @@ -160,7 +158,7 @@ Status Platform::GetFileWithUUID(const FileSpec &platform_file, FileSpecList Platform::LocateExecutableScriptingResources(Target *target, Module &module, - Stream *feedback_stream) { + Stream &feedback_stream) { return FileSpecList(); } @@ -212,11 +210,10 @@ Status Platform::GetSharedModule( Status error(eErrorTypeGeneric); ModuleSpec resolved_spec; // Check if we have sysroot set. - if (m_sdk_sysroot) { + if (!m_sdk_sysroot.empty()) { // Prepend sysroot to module spec. resolved_spec = spec; - resolved_spec.GetFileSpec().PrependPathComponent( - m_sdk_sysroot.GetStringRef()); + resolved_spec.GetFileSpec().PrependPathComponent(m_sdk_sysroot); // Try to get shared module with resolved spec. error = ModuleList::GetSharedModule(resolved_spec, module_sp, module_search_paths_ptr, old_modules, @@ -314,9 +311,9 @@ void Platform::GetStatus(Stream &strm) { strm.Printf(" Connected: %s\n", is_connected ? "yes" : "no"); } - if (GetSDKRootDirectory()) { - strm.Format(" Sysroot: {0}\n", GetSDKRootDirectory()); - } + if (const std::string &sdk_root = GetSDKRootDirectory(); !sdk_root.empty()) + strm.Format(" Sysroot: {0}\n", sdk_root); + if (GetWorkingDirectory()) { strm.Printf("WorkingDir: %s\n", GetWorkingDirectory().GetPath().c_str()); } @@ -435,7 +432,7 @@ RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, // make the new directory and get in there FileSpec dst_dir = rc_baton->dst; if (!dst_dir.GetFilename()) - dst_dir.SetFilename(src.GetLastPathComponent()); + dst_dir.SetFilename(src.GetFilename()); Status error = rc_baton->platform_ptr->MakeDirectory( dst_dir, lldb::eFilePermissionsDirectoryDefault); if (error.Fail()) { @@ -1063,7 +1060,7 @@ lldb::ProcessSP Platform::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, Target &target, Status &error) { Log *log = GetLog(LLDBLog::Platform); - LLDB_LOG(log, "target = {0})", &target); + LLDB_LOG(log, "target = {0}", &target); ProcessSP process_sp; // Make sure we stop at the entry point @@ -1633,7 +1630,7 @@ Status Platform::DownloadModuleSlice(const FileSpec &src_file_spec, return error; } - std::vector<char> buffer(1024); + std::vector<char> buffer(512 * 1024); auto offset = src_offset; uint64_t total_bytes_read = 0; while (total_bytes_read < src_size) { @@ -1815,8 +1812,9 @@ lldb::ProcessSP Platform::DoConnectProcess(llvm::StringRef connect_url, nullptr); process_sp->RestoreProcessEvents(); bool pop_process_io_handler = false; - Process::HandleProcessStateChangedEvent(event_sp, stream, - pop_process_io_handler); + // This is a user-level stop, so we allow recognizers to select frames. + Process::HandleProcessStateChangedEvent( + event_sp, stream, SelectMostRelevantFrame, pop_process_io_handler); } return process_sp; @@ -1895,6 +1893,12 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, trap_opcode_size = sizeof(g_hex_opcode); } break; + case llvm::Triple::msp430: { + static const uint8_t g_msp430_opcode[] = {0x43, 0x43}; + trap_opcode = g_msp430_opcode; + trap_opcode_size = sizeof(g_msp430_opcode); + } break; + case llvm::Triple::systemz: { static const uint8_t g_hex_opcode[] = {0x00, 0x01}; trap_opcode = g_hex_opcode; @@ -1967,6 +1971,14 @@ Args Platform::GetExtraStartupCommands() { return {}; } +void Platform::SetLocateModuleCallback(LocateModuleCallback callback) { + m_locate_module_callback = callback; +} + +Platform::LocateModuleCallback Platform::GetLocateModuleCallback() const { + return m_locate_module_callback; +} + PlatformSP PlatformList::GetOrCreate(llvm::StringRef name) { std::lock_guard<std::recursive_mutex> guard(m_mutex); for (const PlatformSP &platform_sp : m_platforms) { diff --git a/contrib/llvm-project/lldb/source/Target/Process.cpp b/contrib/llvm-project/lldb/source/Target/Process.cpp index e0cca0595ee3..05ddbbd146a2 100644 --- a/contrib/llvm-project/lldb/source/Target/Process.cpp +++ b/contrib/llvm-project/lldb/source/Target/Process.cpp @@ -92,9 +92,9 @@ class ProcessOptionValueProperties public: ProcessOptionValueProperties(ConstString name) : Cloneable(name) {} - const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx, - bool will_modify, - uint32_t idx) const override { + const Property * + GetPropertyAtIndex(size_t idx, + const ExecutionContext *exe_ctx) const override { // When getting the value for a key from the process options, we will // always try and grab the setting from the current process if there is // one. Else we just use the one from this instance. @@ -167,8 +167,8 @@ ProcessProperties::ProcessProperties(lldb_private::Process *process) std::make_shared<ProcessOptionValueProperties>(ConstString("process")); m_collection_sp->Initialize(g_process_properties); m_collection_sp->AppendProperty( - ConstString("thread"), ConstString("Settings specific to threads."), - true, Thread::GetGlobalProperties().GetValueProperties()); + "thread", "Settings specific to threads.", true, + Thread::GetGlobalProperties().GetValueProperties()); } else { m_collection_sp = OptionValueProperties::CreateLocalCopy(Process::GetGlobalProperties()); @@ -180,9 +180,9 @@ ProcessProperties::ProcessProperties(lldb_private::Process *process) m_experimental_properties_up = std::make_unique<ProcessExperimentalProperties>(); m_collection_sp->AppendProperty( - ConstString(Properties::GetExperimentalSettingsName()), - ConstString("Experimental settings - setting these won't produce " - "errors if the setting is not present."), + Properties::GetExperimentalSettingsName(), + "Experimental settings - setting these won't produce " + "errors if the setting is not present.", true, m_experimental_properties_up->GetValueProperties()); } @@ -190,169 +190,183 @@ ProcessProperties::~ProcessProperties() = default; bool ProcessProperties::GetDisableMemoryCache() const { const uint32_t idx = ePropertyDisableMemCache; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } uint64_t ProcessProperties::GetMemoryCacheLineSize() const { const uint32_t idx = ePropertyMemCacheLineSize; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_process_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_process_properties[idx].default_uint_value); } Args ProcessProperties::GetExtraStartupCommands() const { Args args; const uint32_t idx = ePropertyExtraStartCommand; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args); + m_collection_sp->GetPropertyAtIndexAsArgs(idx, args); return args; } void ProcessProperties::SetExtraStartupCommands(const Args &args) { const uint32_t idx = ePropertyExtraStartCommand; - m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args); + m_collection_sp->SetPropertyAtIndexFromArgs(idx, args); } FileSpec ProcessProperties::GetPythonOSPluginPath() const { const uint32_t idx = ePropertyPythonOSPluginPath; - return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } uint32_t ProcessProperties::GetVirtualAddressableBits() const { const uint32_t idx = ePropertyVirtualAddressableBits; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_process_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_process_properties[idx].default_uint_value); } void ProcessProperties::SetVirtualAddressableBits(uint32_t bits) { const uint32_t idx = ePropertyVirtualAddressableBits; - m_collection_sp->SetPropertyAtIndexAsUInt64(nullptr, idx, bits); + SetPropertyAtIndex(idx, static_cast<uint64_t>(bits)); } + +uint32_t ProcessProperties::GetHighmemVirtualAddressableBits() const { + const uint32_t idx = ePropertyHighmemVirtualAddressableBits; + return GetPropertyAtIndexAs<uint64_t>( + idx, g_process_properties[idx].default_uint_value); +} + +void ProcessProperties::SetHighmemVirtualAddressableBits(uint32_t bits) { + const uint32_t idx = ePropertyHighmemVirtualAddressableBits; + SetPropertyAtIndex(idx, static_cast<uint64_t>(bits)); +} + void ProcessProperties::SetPythonOSPluginPath(const FileSpec &file) { const uint32_t idx = ePropertyPythonOSPluginPath; - m_collection_sp->SetPropertyAtIndexAsFileSpec(nullptr, idx, file); + SetPropertyAtIndex(idx, file); } bool ProcessProperties::GetIgnoreBreakpointsInExpressions() const { const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } void ProcessProperties::SetIgnoreBreakpointsInExpressions(bool ignore) { const uint32_t idx = ePropertyIgnoreBreakpointsInExpressions; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore); + SetPropertyAtIndex(idx, ignore); } bool ProcessProperties::GetUnwindOnErrorInExpressions() const { const uint32_t idx = ePropertyUnwindOnErrorInExpressions; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } void ProcessProperties::SetUnwindOnErrorInExpressions(bool ignore) { const uint32_t idx = ePropertyUnwindOnErrorInExpressions; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, ignore); + SetPropertyAtIndex(idx, ignore); } bool ProcessProperties::GetStopOnSharedLibraryEvents() const { const uint32_t idx = ePropertyStopOnSharedLibraryEvents; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } void ProcessProperties::SetStopOnSharedLibraryEvents(bool stop) { const uint32_t idx = ePropertyStopOnSharedLibraryEvents; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop); + SetPropertyAtIndex(idx, stop); } bool ProcessProperties::GetDisableLangRuntimeUnwindPlans() const { const uint32_t idx = ePropertyDisableLangRuntimeUnwindPlans; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } void ProcessProperties::SetDisableLangRuntimeUnwindPlans(bool disable) { const uint32_t idx = ePropertyDisableLangRuntimeUnwindPlans; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, disable); + SetPropertyAtIndex(idx, disable); m_process->Flush(); } bool ProcessProperties::GetDetachKeepsStopped() const { const uint32_t idx = ePropertyDetachKeepsStopped; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } void ProcessProperties::SetDetachKeepsStopped(bool stop) { const uint32_t idx = ePropertyDetachKeepsStopped; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, stop); + SetPropertyAtIndex(idx, stop); } bool ProcessProperties::GetWarningsOptimization() const { const uint32_t idx = ePropertyWarningOptimization; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } bool ProcessProperties::GetWarningsUnsupportedLanguage() const { const uint32_t idx = ePropertyWarningUnsupportedLanguage; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } bool ProcessProperties::GetStopOnExec() const { const uint32_t idx = ePropertyStopOnExec; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } std::chrono::seconds ProcessProperties::GetUtilityExpressionTimeout() const { const uint32_t idx = ePropertyUtilityExpressionTimeout; - uint64_t value = m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_process_properties[idx].default_uint_value); + uint64_t value = GetPropertyAtIndexAs<uint64_t>( + idx, g_process_properties[idx].default_uint_value); return std::chrono::seconds(value); } std::chrono::seconds ProcessProperties::GetInterruptTimeout() const { const uint32_t idx = ePropertyInterruptTimeout; - uint64_t value = m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_process_properties[idx].default_uint_value); + uint64_t value = GetPropertyAtIndexAs<uint64_t>( + idx, g_process_properties[idx].default_uint_value); return std::chrono::seconds(value); } bool ProcessProperties::GetSteppingRunsAllThreads() const { const uint32_t idx = ePropertySteppingRunsAllThreads; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_process_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_process_properties[idx].default_uint_value != 0); } bool ProcessProperties::GetOSPluginReportsAllThreads() const { const bool fail_value = true; const Property *exp_property = - m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyExperimental); + m_collection_sp->GetPropertyAtIndex(ePropertyExperimental); OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties(); if (!exp_values) return fail_value; - return exp_values->GetPropertyAtIndexAsBoolean( - nullptr, ePropertyOSPluginReportsAllThreads, fail_value); + return exp_values + ->GetPropertyAtIndexAs<bool>(ePropertyOSPluginReportsAllThreads) + .value_or(fail_value); } void ProcessProperties::SetOSPluginReportsAllThreads(bool does_report) { const Property *exp_property = - m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertyExperimental); + m_collection_sp->GetPropertyAtIndex(ePropertyExperimental); OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties(); if (exp_values) - exp_values->SetPropertyAtIndexAsBoolean( - nullptr, ePropertyOSPluginReportsAllThreads, does_report); + exp_values->SetPropertyAtIndex(ePropertyOSPluginReportsAllThreads, + does_report); } FollowForkMode ProcessProperties::GetFollowForkMode() const { const uint32_t idx = ePropertyFollowForkMode; - return (FollowForkMode)m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_process_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<FollowForkMode>( + idx, static_cast<FollowForkMode>( + g_process_properties[idx].default_uint_value)); } ProcessSP Process::FindPlugin(lldb::TargetSP target_sp, @@ -402,8 +416,7 @@ ConstString &Process::GetStaticBroadcasterClass() { } Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp) - : Process(target_sp, listener_sp, - UnixSignals::Create(HostInfo::GetArchitecture())) { + : Process(target_sp, listener_sp, UnixSignals::CreateForHost()) { // This constructor just delegates to the full Process constructor, // defaulting to using the Host's UnixSignals. } @@ -480,13 +493,12 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp, // Allow the platform to override the default cache line size OptionValueSP value_sp = - m_collection_sp - ->GetPropertyAtIndex(nullptr, true, ePropertyMemCacheLineSize) + m_collection_sp->GetPropertyAtIndex(ePropertyMemCacheLineSize) ->GetValue(); - uint32_t platform_cache_line_size = + uint64_t platform_cache_line_size = target_sp->GetPlatform()->GetDefaultMemoryCacheLineSize(); if (!value_sp->OptionWasSet() && platform_cache_line_size != 0) - value_sp->SetUInt64Value(platform_cache_line_size); + value_sp->SetValueAs(platform_cache_line_size); RegisterAssertFrameRecognizer(this); } @@ -645,10 +657,10 @@ void Process::SyncIOHandler(uint32_t iohandler_id, } } -StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout, - EventSP *event_sp_ptr, bool wait_always, - ListenerSP hijack_listener_sp, - Stream *stream, bool use_run_lock) { +StateType Process::WaitForProcessToStop( + const Timeout<std::micro> &timeout, EventSP *event_sp_ptr, bool wait_always, + ListenerSP hijack_listener_sp, Stream *stream, bool use_run_lock, + SelectMostRelevant select_most_relevant) { // We can't just wait for a "stopped" event, because the stopped event may // have restarted the target. We have to actually check each event, and in // the case of a stopped event check the restarted flag on the event. @@ -683,8 +695,8 @@ StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout, *event_sp_ptr = event_sp; bool pop_process_io_handler = (hijack_listener_sp.get() != nullptr); - Process::HandleProcessStateChangedEvent(event_sp, stream, - pop_process_io_handler); + Process::HandleProcessStateChangedEvent( + event_sp, stream, select_most_relevant, pop_process_io_handler); switch (state) { case eStateCrashed: @@ -713,9 +725,10 @@ StateType Process::WaitForProcessToStop(const Timeout<std::micro> &timeout, return state; } -bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp, - Stream *stream, - bool &pop_process_io_handler) { +bool Process::HandleProcessStateChangedEvent( + const EventSP &event_sp, Stream *stream, + SelectMostRelevant select_most_relevant, + bool &pop_process_io_handler) { const bool handle_pop = pop_process_io_handler; pop_process_io_handler = false; @@ -897,7 +910,8 @@ bool Process::HandleProcessStateChangedEvent(const EventSP &event_sp, return false; const bool only_threads_with_stop_reason = true; - const uint32_t start_frame = thread_sp->GetSelectedFrameIndex(); + const uint32_t start_frame = + thread_sp->GetSelectedFrameIndex(select_most_relevant); const uint32_t num_frames = 1; const uint32_t num_frames_with_source = 1; const bool stop_format = true; @@ -1054,14 +1068,16 @@ bool Process::SetExitStatus(int status, const char *cstr) { std::lock_guard<std::mutex> guard(m_exit_status_mutex); 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 ? "\"" : ""); + LLDB_LOGF(log, "(plugin = %s status=%i (0x%8.8x), description=%s%s%s)", + GetPluginName().data(), status, status, cstr ? "\"" : "", + cstr ? cstr : "NULL", cstr ? "\"" : ""); // We were already in the exited state if (m_private_state.GetValue() == eStateExited) { - LLDB_LOGF(log, "Process::SetExitStatus () ignoring exit status because " - "state was already set to eStateExited"); + LLDB_LOGF(log, + "(plugin = %s) ignoring exit status because state was already set " + "to eStateExited", + GetPluginName().data()); return false; } @@ -1313,8 +1329,8 @@ void Process::SetPublicState(StateType new_state, bool restarted) { } Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); - LLDB_LOGF(log, "Process::SetPublicState (state = %s, restarted = %i)", - StateAsCString(new_state), restarted); + LLDB_LOGF(log, "(plugin = %s, state = %s, restarted = %i)", + GetPluginName().data(), StateAsCString(new_state), restarted); const StateType old_state = m_public_state.GetValue(); m_public_state.SetValue(new_state); @@ -1324,15 +1340,15 @@ void Process::SetPublicState(StateType new_state, bool restarted) { if (!StateChangedIsExternallyHijacked()) { if (new_state == eStateDetached) { LLDB_LOGF(log, - "Process::SetPublicState (%s) -- unlocking run lock for detach", - StateAsCString(new_state)); + "(plugin = %s, state = %s) -- unlocking run lock for detach", + GetPluginName().data(), StateAsCString(new_state)); m_public_run_lock.SetStopped(); } else { const bool old_state_is_stopped = StateIsStoppedState(old_state, false); if ((old_state_is_stopped != new_state_is_stopped)) { if (new_state_is_stopped && !restarted) { - LLDB_LOGF(log, "Process::SetPublicState (%s) -- unlocking run lock", - StateAsCString(new_state)); + LLDB_LOGF(log, "(plugin = %s, state = %s) -- unlocking run lock", + GetPluginName().data(), StateAsCString(new_state)); m_public_run_lock.SetStopped(); } } @@ -1342,10 +1358,11 @@ void Process::SetPublicState(StateType new_state, bool restarted) { Status Process::Resume() { Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); - LLDB_LOGF(log, "Process::Resume -- locking run lock"); + LLDB_LOGF(log, "(plugin = %s) -- locking run lock", GetPluginName().data()); if (!m_public_run_lock.TrySetRunning()) { Status error("Resume request failed - process still running."); - LLDB_LOGF(log, "Process::Resume: -- TrySetRunning failed, not resuming."); + LLDB_LOGF(log, "(plugin = %s) -- TrySetRunning failed, not resuming.", + GetPluginName().data()); return error; } Status error = PrivateResume(); @@ -1356,8 +1373,6 @@ Status Process::Resume() { return error; } -static const char *g_resume_sync_name = "lldb.Process.ResumeSynchronous.hijack"; - Status Process::ResumeSynchronous(Stream *stream) { Log *log(GetLog(LLDBLog::State | LLDBLog::Process)); LLDB_LOGF(log, "Process::ResumeSynchronous -- locking run lock"); @@ -1368,13 +1383,14 @@ Status Process::ResumeSynchronous(Stream *stream) { } ListenerSP listener_sp( - Listener::MakeListener(g_resume_sync_name)); + Listener::MakeListener(ResumeSynchronousHijackListenerName.data())); HijackProcessEvents(listener_sp); Status error = PrivateResume(); if (error.Success()) { StateType state = - WaitForProcessToStop(std::nullopt, nullptr, true, listener_sp, stream); + WaitForProcessToStop(std::nullopt, nullptr, true, listener_sp, stream, + true /* use_run_lock */, SelectMostRelevantFrame); const bool must_be_alive = false; // eStateExited is ok, so this must be false if (!StateIsStoppedState(state, must_be_alive)) @@ -1394,9 +1410,8 @@ Status Process::ResumeSynchronous(Stream *stream) { bool Process::StateChangedIsExternallyHijacked() { if (IsHijackedForEvent(eBroadcastBitStateChanged)) { - const char *hijacking_name = GetHijackingListenerName(); - if (hijacking_name && - strcmp(hijacking_name, g_resume_sync_name)) + llvm::StringRef hijacking_name = GetHijackingListenerName(); + if (!hijacking_name.starts_with("lldb.internal")) return true; } return false; @@ -1404,9 +1419,8 @@ bool Process::StateChangedIsExternallyHijacked() { bool Process::StateChangedIsHijackedForSynchronousResume() { if (IsHijackedForEvent(eBroadcastBitStateChanged)) { - const char *hijacking_name = GetHijackingListenerName(); - if (hijacking_name && - strcmp(hijacking_name, g_resume_sync_name) == 0) + llvm::StringRef hijacking_name = GetHijackingListenerName(); + if (hijacking_name == ResumeSynchronousHijackListenerName) return true; } return false; @@ -1421,7 +1435,8 @@ void Process::SetPrivateState(StateType new_state) { Log *log(GetLog(LLDBLog::State | LLDBLog::Process | LLDBLog::Unwind)); bool state_changed = false; - LLDB_LOGF(log, "Process::SetPrivateState (%s)", StateAsCString(new_state)); + LLDB_LOGF(log, "(plugin = %s, state = %s)", GetPluginName().data(), + StateAsCString(new_state)); std::lock_guard<std::recursive_mutex> thread_guard(m_thread_list.GetMutex()); std::lock_guard<std::recursive_mutex> guard(m_private_state.GetMutex()); @@ -1462,15 +1477,15 @@ void Process::SetPrivateState(StateType new_state) { if (!m_mod_id.IsLastResumeForUserExpression()) m_mod_id.SetStopEventForLastNaturalStopID(event_sp); m_memory_cache.Clear(); - LLDB_LOGF(log, "Process::SetPrivateState (%s) stop_id = %u", - StateAsCString(new_state), m_mod_id.GetStopID()); + LLDB_LOGF(log, "(plugin = %s, state = %s, stop_id = %u", + GetPluginName().data(), StateAsCString(new_state), + m_mod_id.GetStopID()); } m_private_state_broadcaster.BroadcastEvent(event_sp); } else { - LLDB_LOGF(log, - "Process::SetPrivateState (%s) state didn't change. Ignoring...", - StateAsCString(new_state)); + LLDB_LOGF(log, "(plugin = %s, state = %s) state didn't change. Ignoring...", + GetPluginName().data(), StateAsCString(new_state)); } } @@ -2355,6 +2370,23 @@ Status Process::DeallocateMemory(addr_t ptr) { return error; } +bool Process::GetWatchpointReportedAfter() { + if (std::optional<bool> subclass_override = DoGetWatchpointReportedAfter()) + return *subclass_override; + + bool reported_after = true; + const ArchSpec &arch = GetTarget().GetArchitecture(); + if (!arch.IsValid()) + return reported_after; + llvm::Triple triple = arch.GetTriple(); + + if (triple.isMIPS() || triple.isPPC64() || triple.isRISCV() || + triple.isAArch64() || triple.isArmMClass() || triple.isARM()) + reported_after = false; + + return reported_after; +} + ModuleSP Process::ReadModuleFromMemory(const FileSpec &file_spec, lldb::addr_t header_addr, size_t size_to_read) { @@ -2435,6 +2467,7 @@ Process::WaitForProcessStopPrivate(EventSP &event_sp, } void Process::LoadOperatingSystemPlugin(bool flush) { + std::lock_guard<std::recursive_mutex> guard(m_thread_mutex); if (flush) m_thread_list.Clear(); m_os_up.reset(OperatingSystem::FindPlugin(this, nullptr)); @@ -2495,7 +2528,7 @@ Status Process::LaunchPrivate(ProcessLaunchInfo &launch_info, StateType &state, FileSpec exe_spec_to_use; if (!exe_module) { - if (!launch_info.GetExecutableFile()) { + if (!launch_info.GetExecutableFile() && !launch_info.IsScriptedProcess()) { error.SetErrorString("executable module does not exist"); return error; } @@ -2637,7 +2670,8 @@ Status Process::LoadCore() { // Wait for a stopped event since we just posted one above... lldb::EventSP event_sp; StateType state = - WaitForProcessToStop(std::nullopt, &event_sp, true, listener_sp); + WaitForProcessToStop(std::nullopt, &event_sp, true, listener_sp, + nullptr, true, SelectMostRelevantFrame); if (!StateIsStoppedState(state, false)) { Log *log = GetLog(LLDBLog::Process); @@ -3142,9 +3176,13 @@ Status Process::Halt(bool clear_thread_plans, bool use_run_lock) { } // Wait for the process halt timeout seconds for the process to stop. - StateType state = - WaitForProcessToStop(GetInterruptTimeout(), &event_sp, true, - halt_listener_sp, nullptr, use_run_lock); + // If we are going to use the run lock, that means we're stopping out to the + // user, so we should also select the most relevant frame. + SelectMostRelevant select_most_relevant = + use_run_lock ? SelectMostRelevantFrame : DoNoSelectMostRelevantFrame; + StateType state = WaitForProcessToStop(GetInterruptTimeout(), &event_sp, true, + halt_listener_sp, nullptr, + use_run_lock, select_most_relevant); RestoreProcessEvents(); if (state == eStateInvalid || !event_sp) { @@ -3352,7 +3390,7 @@ Status Process::Signal(int signal) { void Process::SetUnixSignals(UnixSignalsSP &&signals_sp) { assert(signals_sp && "null signals_sp"); - m_unix_signals_sp = signals_sp; + m_unix_signals_sp = std::move(signals_sp); } const lldb::UnixSignalsSP &Process::GetUnixSignals() { @@ -3562,8 +3600,8 @@ bool Process::StartPrivateStateThread(bool is_secondary_thread) { }, 8 * 1024 * 1024); if (!private_state_thread) { - LLDB_LOG(GetLog(LLDBLog::Host), "failed to launch host thread: {}", - llvm::toString(private_state_thread.takeError())); + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), private_state_thread.takeError(), + "failed to launch host thread: {0}"); return false; } @@ -3913,12 +3951,11 @@ Process::ProcessEventData::ProcessEventData(const ProcessSP &process_sp, Process::ProcessEventData::~ProcessEventData() = default; -ConstString Process::ProcessEventData::GetFlavorString() { - static ConstString g_flavor("Process::ProcessEventData"); - return g_flavor; +llvm::StringRef Process::ProcessEventData::GetFlavorString() { + return "Process::ProcessEventData"; } -ConstString Process::ProcessEventData::GetFlavor() const { +llvm::StringRef Process::ProcessEventData::GetFlavor() const { return ProcessEventData::GetFlavorString(); } @@ -4265,7 +4302,7 @@ void Process::BroadcastStructuredData(const StructuredData::ObjectSP &object_sp, } StructuredDataPluginSP -Process::GetStructuredDataPlugin(ConstString type_name) const { +Process::GetStructuredDataPlugin(llvm::StringRef type_name) const { auto find_it = m_structured_data_plugin_map.find(type_name); if (find_it != m_structured_data_plugin_map.end()) return find_it->second; @@ -4745,10 +4782,11 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, // Save the thread & frame from the exe_ctx for restoration after we run const uint32_t thread_idx_id = thread->GetIndexID(); - StackFrameSP selected_frame_sp = thread->GetSelectedFrame(); + StackFrameSP selected_frame_sp = + thread->GetSelectedFrame(DoNoSelectMostRelevantFrame); if (!selected_frame_sp) { thread->SetSelectedFrame(nullptr); - selected_frame_sp = thread->GetSelectedFrame(); + selected_frame_sp = thread->GetSelectedFrame(DoNoSelectMostRelevantFrame); if (!selected_frame_sp) { diagnostic_manager.Printf( eDiagnosticSeverityError, @@ -4780,7 +4818,9 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, StackID selected_stack_id; if (selected_thread_sp) { selected_tid = selected_thread_sp->GetIndexID(); - selected_stack_id = selected_thread_sp->GetSelectedFrame()->GetStackID(); + selected_stack_id = + selected_thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame) + ->GetStackID(); } else { selected_tid = LLDB_INVALID_THREAD_ID; } @@ -5624,25 +5664,75 @@ void Process::Flush() { } lldb::addr_t Process::GetCodeAddressMask() { - if (m_code_address_mask == 0) { - if (uint32_t number_of_addressable_bits = GetVirtualAddressableBits()) { - lldb::addr_t address_mask = ~((1ULL << number_of_addressable_bits) - 1); - SetCodeAddressMask(address_mask); - } - } + if (uint32_t num_bits_setting = GetVirtualAddressableBits()) + return ~((1ULL << num_bits_setting) - 1); + return m_code_address_mask; } lldb::addr_t Process::GetDataAddressMask() { - if (m_data_address_mask == 0) { - if (uint32_t number_of_addressable_bits = GetVirtualAddressableBits()) { - lldb::addr_t address_mask = ~((1ULL << number_of_addressable_bits) - 1); - SetDataAddressMask(address_mask); - } - } + if (uint32_t num_bits_setting = GetVirtualAddressableBits()) + return ~((1ULL << num_bits_setting) - 1); + return m_data_address_mask; } +lldb::addr_t Process::GetHighmemCodeAddressMask() { + if (uint32_t num_bits_setting = GetHighmemVirtualAddressableBits()) + return ~((1ULL << num_bits_setting) - 1); + return GetCodeAddressMask(); +} + +lldb::addr_t Process::GetHighmemDataAddressMask() { + if (uint32_t num_bits_setting = GetHighmemVirtualAddressableBits()) + return ~((1ULL << num_bits_setting) - 1); + return GetDataAddressMask(); +} + +void Process::SetCodeAddressMask(lldb::addr_t code_address_mask) { + LLDB_LOG(GetLog(LLDBLog::Process), + "Setting Process code address mask to {0:x}", code_address_mask); + m_code_address_mask = code_address_mask; +} + +void Process::SetDataAddressMask(lldb::addr_t data_address_mask) { + LLDB_LOG(GetLog(LLDBLog::Process), + "Setting Process data address mask to {0:x}", data_address_mask); + m_data_address_mask = data_address_mask; +} + +void Process::SetHighmemCodeAddressMask(lldb::addr_t code_address_mask) { + LLDB_LOG(GetLog(LLDBLog::Process), + "Setting Process highmem code address mask to {0:x}", + code_address_mask); + m_highmem_code_address_mask = code_address_mask; +} + +void Process::SetHighmemDataAddressMask(lldb::addr_t data_address_mask) { + LLDB_LOG(GetLog(LLDBLog::Process), + "Setting Process highmem data address mask to {0:x}", + data_address_mask); + m_highmem_data_address_mask = data_address_mask; +} + +addr_t Process::FixCodeAddress(addr_t addr) { + if (ABISP abi_sp = GetABI()) + addr = abi_sp->FixCodeAddress(addr); + return addr; +} + +addr_t Process::FixDataAddress(addr_t addr) { + if (ABISP abi_sp = GetABI()) + addr = abi_sp->FixDataAddress(addr); + return addr; +} + +addr_t Process::FixAnyAddress(addr_t addr) { + if (ABISP abi_sp = GetABI()) + addr = abi_sp->FixAnyAddress(addr); + return addr; +} + void Process::DidExec() { Log *log = GetLog(LLDBLog::Process); LLDB_LOGF(log, "Process::%s()", __FUNCTION__); @@ -5737,7 +5827,7 @@ void Process::ModulesDidLoad(ModuleList &module_list) { LoadOperatingSystemPlugin(false); // Inform the structured-data plugins of the modified modules. - for (auto pair : m_structured_data_plugin_map) { + for (auto &pair : m_structured_data_plugin_map) { if (pair.second) pair.second->ModulesDidLoad(*this, module_list); } @@ -5918,7 +6008,7 @@ Status Process::GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) { } Status -Process::ConfigureStructuredData(ConstString type_name, +Process::ConfigureStructuredData(llvm::StringRef type_name, const StructuredData::ObjectSP &config_sp) { // If you get this, the Process-derived class needs to implement a method to // enable an already-reported asynchronous structured data feature. See @@ -5932,34 +6022,29 @@ void Process::MapSupportedStructuredDataPlugins( // Bail out early if there are no type names to map. if (supported_type_names.GetSize() == 0) { - LLDB_LOGF(log, "Process::%s(): no structured data types supported", - __FUNCTION__); + LLDB_LOG(log, "no structured data types supported"); return; } - // Convert StructuredData type names to ConstString instances. - std::set<ConstString> const_type_names; + // These StringRefs are backed by the input parameter. + std::set<llvm::StringRef> type_names; - LLDB_LOGF(log, - "Process::%s(): the process supports the following async " - "structured data types:", - __FUNCTION__); + LLDB_LOG(log, + "the process supports the following async structured data types:"); supported_type_names.ForEach( - [&const_type_names, &log](StructuredData::Object *object) { - if (!object) { - // Invalid - shouldn't be null objects in the array. + [&type_names, &log](StructuredData::Object *object) { + // There shouldn't be null objects in the array. + if (!object) return false; - } - auto type_name = object->GetAsString(); - if (!type_name) { - // Invalid format - all type names should be strings. + // All type names should be strings. + const llvm::StringRef type_name = object->GetStringValue(); + if (type_name.empty()) return false; - } - const_type_names.insert(ConstString(type_name->GetValue())); - LLDB_LOG(log, "- {0}", type_name->GetValue()); + type_names.insert(type_name); + LLDB_LOG(log, "- {0}", type_name); return true; }); @@ -5968,10 +6053,10 @@ void Process::MapSupportedStructuredDataPlugins( // we've consumed all the type names. // FIXME: should we return an error if there are type names nobody // supports? - for (uint32_t plugin_index = 0; !const_type_names.empty(); plugin_index++) { + for (uint32_t plugin_index = 0; !type_names.empty(); plugin_index++) { auto create_instance = - PluginManager::GetStructuredDataPluginCreateCallbackAtIndex( - plugin_index); + PluginManager::GetStructuredDataPluginCreateCallbackAtIndex( + plugin_index); if (!create_instance) break; @@ -5984,8 +6069,8 @@ void Process::MapSupportedStructuredDataPlugins( } // For any of the remaining type names, map any that this plugin supports. - std::vector<ConstString> names_to_remove; - for (auto &type_name : const_type_names) { + std::vector<llvm::StringRef> names_to_remove; + for (llvm::StringRef type_name : type_names) { if (plugin_sp->SupportsStructuredDataType(type_name)) { m_structured_data_plugin_map.insert( std::make_pair(type_name, plugin_sp)); @@ -5996,8 +6081,8 @@ void Process::MapSupportedStructuredDataPlugins( } // Remove the type names that were consumed by this plugin. - for (auto &type_name : names_to_remove) - const_type_names.erase(type_name); + for (llvm::StringRef type_name : names_to_remove) + type_names.erase(type_name); } } @@ -6014,7 +6099,7 @@ bool Process::RouteAsyncStructuredData( return false; // Grab the async structured type name (i.e. the feature/plugin name). - ConstString type_name; + llvm::StringRef type_name; if (!dictionary->GetValueForKeyAsString("type", type_name)) return false; diff --git a/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp b/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp index ee344b01c6b8..7236a45bff3b 100644 --- a/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp +++ b/contrib/llvm-project/lldb/source/Target/RegisterContext.cpp @@ -320,11 +320,6 @@ Status RegisterContext::ReadRegisterValueFromMemory( // |AABB| Address contents // |AABB0000| Register contents [on little-endian hardware] // |0000AABB| Register contents [on big-endian hardware] - if (src_len > RegisterValue::kMaxRegisterByteSize) { - error.SetErrorString("register too small to receive memory data"); - return error; - } - const uint32_t dst_len = reg_info->byte_size; if (src_len > dst_len) { @@ -336,11 +331,11 @@ Status RegisterContext::ReadRegisterValueFromMemory( ProcessSP process_sp(m_thread.GetProcess()); if (process_sp) { - uint8_t src[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer src(src_len); // Read the memory const uint32_t bytes_read = - process_sp->ReadMemory(src_addr, src, src_len, error); + process_sp->ReadMemory(src_addr, src.data(), src_len, error); // Make sure the memory read succeeded... if (bytes_read != src_len) { @@ -357,7 +352,7 @@ Status RegisterContext::ReadRegisterValueFromMemory( // TODO: we might need to add a parameter to this function in case the byte // order of the memory data doesn't match the process. For now we are // assuming they are the same. - reg_value.SetFromMemoryData(*reg_info, src, src_len, + reg_value.SetFromMemoryData(*reg_info, src.data(), src_len, process_sp->GetByteOrder(), error); } else error.SetErrorString("invalid process"); @@ -384,16 +379,16 @@ Status RegisterContext::WriteRegisterValueToMemory( // TODO: we might need to add a parameter to this function in case the byte // order of the memory data doesn't match the process. For now we are // assuming they are the same. - uint8_t dst[RegisterValue::kMaxRegisterByteSize]; + RegisterValue::BytesContainer dst(dst_len); const uint32_t bytes_copied = reg_value.GetAsMemoryData( - *reg_info, dst, dst_len, process_sp->GetByteOrder(), error); + *reg_info, dst.data(), dst_len, process_sp->GetByteOrder(), error); if (error.Success()) { if (bytes_copied == 0) { error.SetErrorString("byte copy failed."); } else { const uint32_t bytes_written = - process_sp->WriteMemory(dst_addr, dst, bytes_copied, error); + process_sp->WriteMemory(dst_addr, dst.data(), bytes_copied, error); if (bytes_written != bytes_copied) { if (error.Success()) { // This might happen if we read _some_ bytes but not all diff --git a/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp b/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp index 2da40ba2bf61..242c7d3f6b94 100644 --- a/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp +++ b/contrib/llvm-project/lldb/source/Target/RegisterContextUnwind.cpp @@ -37,6 +37,8 @@ #include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/VASPrintf.h" #include "lldb/lldb-private.h" + +#include <cassert> #include <memory> using namespace lldb; @@ -135,9 +137,8 @@ void RegisterContextUnwind::InitializeZerothFrame() { // (which would be a no-op in frame 0 where we get it from the register set, // but still a good idea to make the call here for other ABIs that may // exist.) - ABI *abi = process->GetABI().get(); - if (abi) - current_pc = abi->FixCodeAddress(current_pc); + if (ABISP abi_sp = process->GetABI()) + current_pc = abi_sp->FixCodeAddress(current_pc); UnwindPlanSP lang_runtime_plan_sp = LanguageRuntime::GetRuntimeUnwindPlan( m_thread, this, m_behaves_like_zeroth_frame); @@ -289,6 +290,13 @@ void RegisterContextUnwind::InitializeZerothFrame() { } else ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa); + if (m_cfa == LLDB_INVALID_ADDRESS && m_afa == LLDB_INVALID_ADDRESS) { + UnwindLogMsg( + "could not read CFA or AFA values for first frame, not valid."); + m_frame_type = eNotAValidFrame; + return; + } + UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64 " using %s UnwindPlan", (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), @@ -346,17 +354,23 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { // Let ABIs fixup code addresses to make sure they are valid. In ARM ABIs // this will strip bit zero in case we read a PC from memory or from the LR. - ABI *abi = process->GetABI().get(); - if (abi) - pc = abi->FixCodeAddress(pc); + ABISP abi_sp = process->GetABI(); + if (abi_sp) + pc = abi_sp->FixCodeAddress(pc); if (log) { UnwindLogMsg("pc = 0x%" PRIx64, pc); addr_t reg_val; - if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) + if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP, reg_val)) { + if (abi_sp) + reg_val = abi_sp->FixDataAddress(reg_val); UnwindLogMsg("fp = 0x%" PRIx64, reg_val); - if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) + } + if (ReadGPRValue(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP, reg_val)) { + if (abi_sp) + reg_val = abi_sp->FixDataAddress(reg_val); UnwindLogMsg("sp = 0x%" PRIx64, reg_val); + } } // A pc of 0x0 means it's the end of the stack crawl unless we're above a trap @@ -415,11 +429,11 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { } } - if (abi) { + if (abi_sp) { m_fast_unwind_plan_sp.reset(); m_full_unwind_plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindGeneric); - abi->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp); + abi_sp->CreateDefaultUnwindPlan(*m_full_unwind_plan_sp); if (m_frame_type != eSkipFrame) // don't override eSkipFrame { m_frame_type = eNormalFrame; @@ -1742,8 +1756,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { old_caller_pc_value = reg_value.GetAsUInt64(); if (ProcessSP process_sp = m_thread.GetProcess()) { - if (ABISP abi = process_sp->GetABI()) - old_caller_pc_value = abi->FixCodeAddress(old_caller_pc_value); + if (ABISP abi_sp = process_sp->GetABI()) + old_caller_pc_value = abi_sp->FixCodeAddress(old_caller_pc_value); } } } @@ -1802,8 +1816,8 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { reg_value)) { new_caller_pc_value = reg_value.GetAsUInt64(); if (ProcessSP process_sp = m_thread.GetProcess()) { - if (ABISP abi = process_sp->GetABI()) - new_caller_pc_value = abi->FixCodeAddress(new_caller_pc_value); + if (ABISP abi_sp = process_sp->GetABI()) + new_caller_pc_value = abi_sp->FixCodeAddress(new_caller_pc_value); } } } @@ -1944,6 +1958,7 @@ bool RegisterContextUnwind::ReadFrameAddress( address = LLDB_INVALID_ADDRESS; addr_t cfa_reg_contents; + ABISP abi_sp = m_thread.GetProcess()->GetABI(); switch (fa.GetValueType()) { case UnwindPlan::Row::FAValue::isRegisterDereferenced: { @@ -1954,11 +1969,13 @@ bool RegisterContextUnwind::ReadFrameAddress( GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB)); RegisterValue reg_value; if (reg_info) { + if (abi_sp) + cfa_reg_contents = abi_sp->FixDataAddress(cfa_reg_contents); Status error = ReadRegisterValueFromMemory( reg_info, cfa_reg_contents, reg_info->byte_size, reg_value); if (error.Success()) { address = reg_value.GetAsUInt64(); - if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) + if (abi_sp) address = abi_sp->FixCodeAddress(address); UnwindLogMsg( "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 @@ -1980,6 +1997,8 @@ bool RegisterContextUnwind::ReadFrameAddress( RegisterNumber cfa_reg(m_thread, row_register_kind, fa.GetRegisterNumber()); if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { + if (abi_sp) + cfa_reg_contents = abi_sp->FixDataAddress(cfa_reg_contents); if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1) { UnwindLogMsg( @@ -2067,6 +2086,8 @@ lldb::addr_t RegisterContextUnwind::GetReturnAddressHint(int32_t plan_offset) { return LLDB_INVALID_ADDRESS; if (!m_sym_ctx.module_sp || !m_sym_ctx.symbol) return LLDB_INVALID_ADDRESS; + if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) + hint = abi_sp->FixCodeAddress(hint); hint += plan_offset; @@ -2116,28 +2137,46 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind, } const RegisterInfo *reg_info = GetRegisterInfoAtIndex(lldb_regnum); + assert(reg_info); + if (!reg_info) { + UnwindLogMsg( + "Could not find RegisterInfo definition for lldb register number %d", + lldb_regnum); + return false; + } + + uint32_t generic_regnum = LLDB_INVALID_REGNUM; + if (register_kind == eRegisterKindGeneric) + generic_regnum = regnum; + else + m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds( + register_kind, regnum, eRegisterKindGeneric, generic_regnum); + ABISP abi_sp = m_thread.GetProcess()->GetABI(); + RegisterValue reg_value; // if this is frame 0 (currently executing frame), get the requested reg // contents from the actual thread registers if (IsFrameZero()) { if (m_thread.GetRegisterContext()->ReadRegister(reg_info, reg_value)) { value = reg_value.GetAsUInt64(); + if (abi_sp && generic_regnum != LLDB_INVALID_REGNUM) { + if (generic_regnum == LLDB_REGNUM_GENERIC_PC || + generic_regnum == LLDB_REGNUM_GENERIC_RA) + value = abi_sp->FixCodeAddress(value); + if (generic_regnum == LLDB_REGNUM_GENERIC_SP || + generic_regnum == LLDB_REGNUM_GENERIC_FP) + value = abi_sp->FixDataAddress(value); + } return true; } return false; } bool pc_register = false; - uint32_t generic_regnum; - if (register_kind == eRegisterKindGeneric && - (regnum == LLDB_REGNUM_GENERIC_PC || regnum == LLDB_REGNUM_GENERIC_RA)) { + if (generic_regnum != LLDB_INVALID_REGNUM && + (generic_regnum == LLDB_REGNUM_GENERIC_PC || + generic_regnum == LLDB_REGNUM_GENERIC_RA)) pc_register = true; - } else if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds( - register_kind, regnum, eRegisterKindGeneric, generic_regnum) && - (generic_regnum == LLDB_REGNUM_GENERIC_PC || - generic_regnum == LLDB_REGNUM_GENERIC_RA)) { - pc_register = true; - } lldb_private::UnwindLLDB::RegisterLocation regloc; if (!m_parent_unwind.SearchForSavedLocationForRegister( @@ -2147,9 +2186,8 @@ bool RegisterContextUnwind::ReadGPRValue(lldb::RegisterKind register_kind, if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { value = reg_value.GetAsUInt64(); if (pc_register) { - if (ProcessSP process_sp = m_thread.GetProcess()) { - if (ABISP abi = process_sp->GetABI()) - value = abi->FixCodeAddress(value); + if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) { + value = abi_sp->FixCodeAddress(value); } } return true; @@ -2198,10 +2236,8 @@ bool RegisterContextUnwind::ReadRegister(const RegisterInfo *reg_info, if (is_pc_regnum && value.GetType() == RegisterValue::eTypeUInt64) { addr_t reg_value = value.GetAsUInt64(LLDB_INVALID_ADDRESS); if (reg_value != LLDB_INVALID_ADDRESS) { - if(ProcessSP process_sp = m_thread.GetProcess()) { - if (ABISP abi = process_sp->GetABI()) - value = abi->FixCodeAddress(reg_value); - } + if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) + value = abi_sp->FixCodeAddress(reg_value); } } } @@ -2283,9 +2319,8 @@ bool RegisterContextUnwind::GetStartPC(addr_t &start_pc) { ProcessSP process_sp (m_thread.GetProcess()); if (process_sp) { - ABI *abi = process_sp->GetABI().get(); - if (abi) - start_pc = abi->FixCodeAddress(start_pc); + if (ABISP abi_sp = process_sp->GetABI()) + start_pc = abi_sp->FixCodeAddress(start_pc); } } return read_successfully; @@ -2313,13 +2348,8 @@ bool RegisterContextUnwind::ReadPC(addr_t &pc) { // through a NULL pointer -- we want to be able to unwind past that frame // to help find the bug. - ProcessSP process_sp (m_thread.GetProcess()); - if (process_sp) - { - ABI *abi = process_sp->GetABI().get(); - if (abi) - pc = abi->FixCodeAddress(pc); - } + if (ABISP abi_sp = m_thread.GetProcess()->GetABI()) + pc = abi_sp->FixCodeAddress(pc); return !(m_all_registers_available == false && above_trap_handler == false && (pc == 0 || pc == 1)); diff --git a/contrib/llvm-project/lldb/source/Target/RegisterFlags.cpp b/contrib/llvm-project/lldb/source/Target/RegisterFlags.cpp new file mode 100644 index 000000000000..06fb45d777ec --- /dev/null +++ b/contrib/llvm-project/lldb/source/Target/RegisterFlags.cpp @@ -0,0 +1,177 @@ +//===-- RegisterFlags.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/RegisterFlags.h" +#include "lldb/Utility/StreamString.h" + +#include <numeric> +#include <optional> + +using namespace lldb_private; + +void RegisterFlags::Field::log(Log *log) const { + LLDB_LOG(log, " Name: \"{0}\" Start: {1} End: {2}", m_name.c_str(), m_start, + m_end); +} + +bool RegisterFlags::Field::Overlaps(const Field &other) const { + unsigned overlap_start = std::max(GetStart(), other.GetStart()); + unsigned overlap_end = std::min(GetEnd(), other.GetEnd()); + return overlap_start <= overlap_end; +} + +unsigned RegisterFlags::Field::PaddingDistance(const Field &other) const { + assert(!Overlaps(other) && + "Cannot get padding distance for overlapping fields."); + assert((other < (*this)) && "Expected fields in MSB to LSB order."); + + // If they don't overlap they are either next to each other or separated + // by some number of bits. + + // Where left will be the MSB and right will be the LSB. + unsigned lhs_start = GetStart(); + unsigned rhs_end = other.GetStart() + other.GetSizeInBits() - 1; + + if (*this < other) { + lhs_start = other.GetStart(); + rhs_end = GetStart() + GetSizeInBits() - 1; + } + + return lhs_start - rhs_end - 1; +} + +RegisterFlags::RegisterFlags(std::string id, unsigned size, + const std::vector<Field> &fields) + : m_id(std::move(id)), m_size(size) { + // We expect that the XML processor will discard anything describing flags but + // with no fields. + assert(fields.size() && "Some fields must be provided."); + + // We expect that these are unsorted but do not overlap. + // They could fill the register but may have gaps. + std::vector<Field> provided_fields = fields; + m_fields.reserve(provided_fields.size()); + + // ProcessGDBRemote should have sorted these in descending order already. + assert(std::is_sorted(provided_fields.rbegin(), provided_fields.rend())); + + // Build a new list of fields that includes anonymous (empty name) fields + // wherever there is a gap. This will simplify processing later. + std::optional<Field> previous_field; + unsigned register_msb = (size * 8) - 1; + for (auto field : provided_fields) { + if (previous_field) { + unsigned padding = previous_field->PaddingDistance(field); + if (padding) { + // -1 to end just before the previous field. + unsigned end = previous_field->GetStart() - 1; + // +1 because if you want to pad 1 bit you want to start and end + // on the same bit. + m_fields.push_back(Field("", field.GetEnd() + 1, end)); + } + } else { + // This is the first field. Check that it starts at the register's MSB. + if (field.GetEnd() != register_msb) + m_fields.push_back(Field("", field.GetEnd() + 1, register_msb)); + } + m_fields.push_back(field); + previous_field = field; + } + + // The last field may not extend all the way to bit 0. + if (previous_field && previous_field->GetStart() != 0) + m_fields.push_back(Field("", 0, previous_field->GetStart() - 1)); +} + +void RegisterFlags::log(Log *log) const { + LLDB_LOG(log, "ID: \"{0}\" Size: {1}", m_id.c_str(), m_size); + for (const Field &field : m_fields) + field.log(log); +} + +static StreamString FormatCell(const StreamString &content, + unsigned column_width) { + unsigned pad = column_width - content.GetString().size(); + std::string pad_l; + std::string pad_r; + if (pad) { + pad_l = std::string(pad / 2, ' '); + pad_r = std::string((pad / 2) + (pad % 2), ' '); + } + + StreamString aligned; + aligned.Printf("|%s%s%s", pad_l.c_str(), content.GetString().data(), + pad_r.c_str()); + return aligned; +} + +static void EmitTable(std::string &out, std::array<std::string, 3> &table) { + // Close the table. + for (std::string &line : table) + line += '|'; + + out += std::accumulate(table.begin() + 1, table.end(), table.front(), + [](std::string lhs, const auto &rhs) { + return std::move(lhs) + "\n" + rhs; + }); +} + +std::string RegisterFlags::AsTable(uint32_t max_width) const { + std::string table; + // position / gridline / name + std::array<std::string, 3> lines; + uint32_t current_width = 0; + + for (const RegisterFlags::Field &field : m_fields) { + StreamString position; + if (field.GetEnd() == field.GetStart()) + position.Printf(" %d ", field.GetEnd()); + else + position.Printf(" %d-%d ", field.GetEnd(), field.GetStart()); + + StreamString name; + name.Printf(" %s ", field.GetName().c_str()); + + unsigned column_width = position.GetString().size(); + unsigned name_width = name.GetString().size(); + if (name_width > column_width) + column_width = name_width; + + // If the next column would overflow and we have already formatted at least + // one column, put out what we have and move to a new table on the next line + // (+1 here because we need to cap the ends with '|'). If this is the first + // column, just let it overflow and we'll wrap next time around. There's not + // much we can do with a very small terminal. + if (current_width && ((current_width + column_width + 1) >= max_width)) { + EmitTable(table, lines); + // Blank line between each. + table += "\n\n"; + + for (std::string &line : lines) + line.clear(); + current_width = 0; + } + + StreamString aligned_position = FormatCell(position, column_width); + lines[0] += aligned_position.GetString(); + StreamString grid; + grid << '|' << std::string(column_width, '-'); + lines[1] += grid.GetString(); + StreamString aligned_name = FormatCell(name, column_width); + lines[2] += aligned_name.GetString(); + + // +1 for the left side '|'. + current_width += column_width + 1; + } + + // If we didn't overflow and still have table to print out. + if (lines[0].size()) + EmitTable(table, lines); + + return table; +} diff --git a/contrib/llvm-project/lldb/source/Target/StackFrame.cpp b/contrib/llvm-project/lldb/source/Target/StackFrame.cpp index c04b58e80523..11ada92348ec 100644 --- a/contrib/llvm-project/lldb/source/Target/StackFrame.cpp +++ b/contrib/llvm-project/lldb/source/Target/StackFrame.cpp @@ -567,26 +567,21 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( // Check for direct ivars access which helps us with implicit access to // ivars using "this" or "self". GetSymbolContext(eSymbolContextFunction | eSymbolContextBlock); - lldb::LanguageType method_language = eLanguageTypeUnknown; - bool is_instance_method = false; - ConstString method_object_name; - if (m_sc.GetFunctionMethodInfo(method_language, is_instance_method, - method_object_name)) { - if (is_instance_method && method_object_name) { - var_sp = variable_list->FindVariable(method_object_name); - if (var_sp) { - separator_idx = 0; - 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; - } + llvm::StringRef instance_var_name = m_sc.GetInstanceVariableName(); + if (!instance_var_name.empty()) { + var_sp = variable_list->FindVariable(ConstString(instance_var_name)); + if (var_sp) { + separator_idx = 0; + 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; } } } @@ -609,7 +604,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( valobj_sp = GetValueObjectForFrameVariable(variable_sp, use_dynamic); if (!valobj_sp) return valobj_sp; - valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string, true); + valobj_sp = valobj_sp->GetChildMemberWithName(name_const_string); if (valobj_sp) break; } @@ -710,13 +705,13 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( return ValueObjectSP(); } } - child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp = valobj_sp->GetChildMemberWithName(child_name); if (!child_valobj_sp) { if (!no_synth_child) { child_valobj_sp = valobj_sp->GetSyntheticValue(); if (child_valobj_sp) child_valobj_sp = - child_valobj_sp->GetChildMemberWithName(child_name, true); + child_valobj_sp->GetChildMemberWithName(child_name); } if (no_synth_child || !child_valobj_sp) { @@ -819,7 +814,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( // extract bit low out of it. reading array item low would be done by // saying arr[low], without a deref * sign Status error; - ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true)); + ValueObjectSP temp(valobj_sp->GetChildAtIndex(0)); if (error.Fail()) { valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( @@ -873,7 +868,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( valobj_sp->GetTypeName().AsCString("<invalid type>"), var_expr_path_strm.GetData()); } else { - child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); + child_valobj_sp = synthetic->GetChildAtIndex(child_index); if (!child_valobj_sp) { valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( @@ -899,7 +894,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( nullptr, nullptr, &is_incomplete_array)) { // Pass false to dynamic_value here so we can tell the difference // between no dynamic value and no member of this type... - child_valobj_sp = valobj_sp->GetChildAtIndex(child_index, true); + child_valobj_sp = valobj_sp->GetChildAtIndex(child_index); if (!child_valobj_sp && (is_incomplete_array || !no_synth_child)) child_valobj_sp = valobj_sp->GetSyntheticArrayMember(child_index, true); @@ -945,7 +940,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( valobj_sp->GetTypeName().AsCString("<invalid type>"), var_expr_path_strm.GetData()); } else { - child_valobj_sp = synthetic->GetChildAtIndex(child_index, true); + child_valobj_sp = synthetic->GetChildAtIndex(child_index); if (!child_valobj_sp) { valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( @@ -1017,7 +1012,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( // extract bits low thru high out of it. reading array items low thru // high would be done by saying arr[low-high], without a deref * sign Status error; - ValueObjectSP temp(valobj_sp->GetChildAtIndex(0, true)); + ValueObjectSP temp(valobj_sp->GetChildAtIndex(0)); if (error.Fail()) { valobj_sp->GetExpressionPath(var_expr_path_strm); error.SetErrorStringWithFormat( @@ -1365,7 +1360,7 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) { target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC); if (auto err = c_type_system_or_err.takeError()) { LLDB_LOG_ERROR(GetLog(LLDBLog::Thread), std::move(err), - "Unable to guess value for given address"); + "Unable to guess value for given address: {0}"); return ValueObjectSP(); } else { auto ts = *c_type_system_or_err; @@ -1405,8 +1400,7 @@ ValueObjectSP GetValueForOffset(StackFrame &frame, ValueObjectSP &parent, } for (int ci = 0, ce = parent->GetNumChildren(); ci != ce; ++ci) { - const bool can_create = true; - ValueObjectSP child_sp = parent->GetChildAtIndex(ci, can_create); + ValueObjectSP child_sp = parent->GetChildAtIndex(ci); if (!child_sp) { return ValueObjectSP(); diff --git a/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp b/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp index c782b506a9cb..2841f512439a 100644 --- a/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp +++ b/contrib/llvm-project/lldb/source/Target/StackFrameList.cpp @@ -9,6 +9,7 @@ #include "lldb/Target/StackFrameList.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/StreamFile.h" #include "lldb/Symbol/Block.h" @@ -17,6 +18,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" @@ -37,7 +39,7 @@ StackFrameList::StackFrameList(Thread &thread, const lldb::StackFrameListSP &prev_frames_sp, bool show_inline_frames) : m_thread(thread), m_prev_frames_sp(prev_frames_sp), m_mutex(), m_frames(), - m_selected_frame_idx(0), m_concrete_frames_fetched(0), + m_selected_frame_idx(), m_concrete_frames_fetched(0), m_current_inlined_depth(UINT32_MAX), m_current_inlined_pc(LLDB_INVALID_ADDRESS), m_show_inlined_frames(show_inline_frames) { @@ -83,8 +85,8 @@ void StackFrameList::ResetCurrentInlinedDepth() { return; std::lock_guard<std::recursive_mutex> guard(m_mutex); - - GetFramesUpTo(0); + + GetFramesUpTo(0, DoNotAllowInterruption); if (m_frames.empty()) return; if (!m_frames[0]->IsInlined()) { @@ -251,7 +253,7 @@ struct CallDescriptor { using CallSequence = std::vector<CallDescriptor>; /// Find the unique path through the call graph from \p begin (with return PC -/// \p return_pc) to \p end. On success this path is stored into \p path, and +/// \p return_pc) to \p end. On success this path is stored into \p path, and /// on failure \p path is unchanged. static void FindInterveningFrames(Function &begin, Function &end, ExecutionContext &exe_ctx, Target &target, @@ -434,21 +436,23 @@ void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { next_frame.SetFrameIndex(m_frames.size()); } -void StackFrameList::GetFramesUpTo(uint32_t end_idx) { +bool StackFrameList::GetFramesUpTo(uint32_t end_idx, + InterruptionControl allow_interrupt) { // Do not fetch frames for an invalid thread. + bool was_interrupted = false; if (!m_thread.IsValid()) - return; + return false; // We've already gotten more frames than asked for, or we've already finished // unwinding, return. if (m_frames.size() > end_idx || GetAllFramesFetched()) - return; + return false; Unwind &unwinder = m_thread.GetUnwinder(); if (!m_show_inlined_frames) { GetOnlyConcreteFramesUpTo(end_idx, unwinder); - return; + return false; } #if defined(DEBUG_STACK_FRAMES) @@ -470,6 +474,7 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { } StackFrameSP unwind_frame_sp; + Debugger &dbg = m_thread.GetProcess()->GetTarget().GetDebugger(); do { uint32_t idx = m_concrete_frames_fetched++; lldb::addr_t pc = LLDB_INVALID_ADDRESS; @@ -502,6 +507,15 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); } } else { + // Check for interruption when building the frames. + // Do the check in idx > 0 so that we'll always create a 0th frame. + if (allow_interrupt + && INTERRUPT_REQUESTED(dbg, "Interrupted having fetched {0} frames", + m_frames.size())) { + was_interrupted = true; + break; + } + const bool success = unwinder.GetFrameInfoAtIndex(idx, cfa, pc, behaves_like_zeroth_frame); if (!success) { @@ -614,14 +628,19 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { Dump(&s); s.EOL(); #endif + // Don't report interrupted if we happen to have gotten all the frames: + if (!GetAllFramesFetched()) + return was_interrupted; + return false; } uint32_t StackFrameList::GetNumFrames(bool can_create) { std::lock_guard<std::recursive_mutex> guard(m_mutex); - if (can_create) - GetFramesUpTo(UINT32_MAX); - + if (can_create) { + // Don't allow interrupt or we might not return the correct count + GetFramesUpTo(UINT32_MAX, DoNotAllowInterruption); + } return GetVisibleStackFrameIndex(m_frames.size()); } @@ -662,7 +681,13 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) { // GetFramesUpTo will fill m_frames with as many frames as you asked for, if // there are that many. If there weren't then you asked for too many frames. - GetFramesUpTo(idx); + // GetFramesUpTo returns true if interrupted: + if (GetFramesUpTo(idx)) { + Log *log = GetLog(LLDBLog::Thread); + LLDB_LOG(log, "GetFrameAtIndex was interrupted"); + return {}; + } + if (idx < m_frames.size()) { if (m_show_inlined_frames) { // When inline frames are enabled we actually create all the frames in @@ -772,9 +797,52 @@ bool StackFrameList::SetFrameAtIndex(uint32_t idx, StackFrameSP &frame_sp) { return false; // resize failed, out of memory? } -uint32_t StackFrameList::GetSelectedFrameIndex() const { +void StackFrameList::SelectMostRelevantFrame() { + // Don't call into the frame recognizers on the private state thread as + // they can cause code to run in the target, and that can cause deadlocks + // when fetching stop events for the expression. + if (m_thread.GetProcess()->CurrentThreadIsPrivateStateThread()) + return; + + Log *log = GetLog(LLDBLog::Thread); + + // Only the top frame should be recognized. + StackFrameSP frame_sp = GetFrameAtIndex(0); + if (!frame_sp) { + LLDB_LOG(log, "Failed to construct Frame #0"); + return; + } + + RecognizedStackFrameSP recognized_frame_sp = frame_sp->GetRecognizedFrame(); + + if (!recognized_frame_sp) { + LLDB_LOG(log, "Frame #0 not recognized"); + return; + } + + if (StackFrameSP most_relevant_frame_sp = + recognized_frame_sp->GetMostRelevantFrame()) { + LLDB_LOG(log, "Found most relevant frame at index {0}", + most_relevant_frame_sp->GetFrameIndex()); + SetSelectedFrame(most_relevant_frame_sp.get()); + } else { + LLDB_LOG(log, "No relevant frame!"); + } +} + +uint32_t StackFrameList::GetSelectedFrameIndex( + SelectMostRelevant select_most_relevant) { std::lock_guard<std::recursive_mutex> guard(m_mutex); - return m_selected_frame_idx; + if (!m_selected_frame_idx && select_most_relevant) + SelectMostRelevantFrame(); + if (!m_selected_frame_idx) { + // If we aren't selecting the most relevant frame, and the selected frame + // isn't set, then don't force a selection here, just return 0. + if (!select_most_relevant) + return 0; + m_selected_frame_idx = 0; + } + return *m_selected_frame_idx; } uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) { @@ -783,17 +851,19 @@ uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) { const_iterator begin = m_frames.begin(); const_iterator end = m_frames.end(); m_selected_frame_idx = 0; + for (pos = begin; pos != end; ++pos) { if (pos->get() == frame) { m_selected_frame_idx = std::distance(begin, pos); uint32_t inlined_depth = GetCurrentInlinedDepth(); if (inlined_depth != UINT32_MAX) - m_selected_frame_idx -= inlined_depth; + m_selected_frame_idx = *m_selected_frame_idx - inlined_depth; break; } } + SetDefaultFileAndLineToSelectedFrame(); - return m_selected_frame_idx; + return *m_selected_frame_idx; } bool StackFrameList::SetSelectedFrameByIndex(uint32_t idx) { @@ -809,7 +879,8 @@ bool StackFrameList::SetSelectedFrameByIndex(uint32_t idx) { void StackFrameList::SetDefaultFileAndLineToSelectedFrame() { if (m_thread.GetID() == m_thread.GetProcess()->GetThreadList().GetSelectedThread()->GetID()) { - StackFrameSP frame_sp(GetFrameAtIndex(GetSelectedFrameIndex())); + StackFrameSP frame_sp( + GetFrameAtIndex(GetSelectedFrameIndex(DoNoSelectMostRelevantFrame))); if (frame_sp) { SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextLineEntry); if (sc.line_entry.file) @@ -821,10 +892,16 @@ void StackFrameList::SetDefaultFileAndLineToSelectedFrame() { // The thread has been run, reset the number stack frames to zero so we can // determine how many frames we have lazily. +// Note, we don't actually re-use StackFrameLists, we always make a new +// StackFrameList every time we stop, and then copy frame information frame +// by frame from the old to the new StackFrameList. So the comment above, +// does not describe how StackFrameLists are currently used. +// Clear is currently only used to clear the list in the destructor. void StackFrameList::Clear() { std::lock_guard<std::recursive_mutex> guard(m_mutex); m_frames.clear(); m_concrete_frames_fetched = 0; + m_selected_frame_idx.reset(); } lldb::StackFrameSP @@ -863,7 +940,8 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame, else last_frame = first_frame + num_frames; - StackFrameSP selected_frame_sp = m_thread.GetSelectedFrame(); + StackFrameSP selected_frame_sp = + m_thread.GetSelectedFrame(DoNoSelectMostRelevantFrame); const char *unselected_marker = nullptr; std::string buffer; if (selected_frame_marker) { @@ -884,6 +962,14 @@ size_t StackFrameList::GetStatus(Stream &strm, uint32_t first_frame, else marker = unselected_marker; } + // Check for interruption here. If we're fetching arguments, this loop + // can go slowly: + Debugger &dbg = m_thread.GetProcess()->GetTarget().GetDebugger(); + if (INTERRUPT_REQUESTED(dbg, + "Interrupted dumping stack for thread {0:hex} with {1} shown.", + m_thread.GetID(), num_frames_displayed)) + break; + if (!frame_sp->GetStatus(strm, show_frame_info, num_frames_with_source > (first_frame - frame_idx), diff --git a/contrib/llvm-project/lldb/source/Target/StopInfo.cpp b/contrib/llvm-project/lldb/source/Target/StopInfo.cpp index 225234c0ffba..efc8fd269ac2 100644 --- a/contrib/llvm-project/lldb/source/Target/StopInfo.cpp +++ b/contrib/llvm-project/lldb/source/Target/StopInfo.cpp @@ -256,7 +256,7 @@ protected: if (!m_should_perform_action) return; m_should_perform_action = false; - bool internal_breakpoint = true; + bool all_stopping_locs_internal = true; ThreadSP thread_sp(m_thread_wp.lock()); @@ -332,7 +332,7 @@ protected: ExecutionContext exe_ctx(thread_sp->GetStackFrameAtIndex(0)); Process *process = exe_ctx.GetProcessPtr(); - if (process->GetModIDRef().IsLastResumeForUserExpression()) { + if (process->GetModIDRef().IsRunningExpression()) { // If we are in the middle of evaluating an expression, don't run // asynchronous breakpoint commands or expressions. That could // lead to infinite recursion if the command or condition re-calls @@ -421,8 +421,6 @@ protected: continue; } - internal_breakpoint = bp_loc_sp->GetBreakpoint().IsInternal(); - // First run the precondition, but since the precondition is per // breakpoint, only run it once per breakpoint. std::pair<std::unordered_set<break_id_t>::iterator, bool> result = @@ -509,7 +507,7 @@ protected: loc_desc.GetData()); // We want this stop reported, so you will know we auto-continued // but only for external breakpoints: - if (!internal_breakpoint) + if (!bp_loc_sp->GetBreakpoint().IsInternal()) thread_sp->SetShouldReportStop(eVoteYes); auto_continue_says_stop = false; } @@ -539,6 +537,9 @@ protected: actually_said_continue = true; } + if (m_should_stop && !bp_loc_sp->GetBreakpoint().IsInternal()) + all_stopping_locs_internal = false; + // If we are going to stop for this breakpoint, then remove the // breakpoint. if (callback_says_stop && bp_loc_sp && @@ -576,7 +577,7 @@ protected: __FUNCTION__, m_value); } - if ((!m_should_stop || internal_breakpoint) && + if ((!m_should_stop || all_stopping_locs_internal) && thread_sp->CompletedPlanOverridesBreakpoint()) { // Override should_stop decision when we have completed step plan @@ -665,9 +666,8 @@ public: WatchpointSP watchpoint_sp; }; - StopInfoWatchpoint(Thread &thread, break_id_t watch_id, - lldb::addr_t watch_hit_addr) - : StopInfo(thread, watch_id), m_watch_hit_addr(watch_hit_addr) {} + StopInfoWatchpoint(Thread &thread, break_id_t watch_id, bool silently_skip_wp) + : StopInfo(thread, watch_id), m_silently_skip_wp(silently_skip_wp) {} ~StopInfoWatchpoint() override = default; @@ -822,22 +822,19 @@ protected: // stop ProcessSP process_sp = exe_ctx.GetProcessSP(); - uint32_t num; - bool wp_triggers_after; + bool wp_triggers_after = process_sp->GetWatchpointReportedAfter(); - if (!process_sp->GetWatchpointSupportInfo(num, wp_triggers_after) - .Success()) { - m_should_stop_is_valid = true; - m_should_stop = true; - return m_should_stop; - } - if (!wp_triggers_after) { // We have to step over the watchpoint before we know what to do: StopInfoWatchpointSP me_as_siwp_sp = std::static_pointer_cast<StopInfoWatchpoint>(shared_from_this()); ThreadPlanSP step_over_wp_sp(new ThreadPlanStepOverWatchpoint( *(thread_sp.get()), me_as_siwp_sp, wp_sp)); + // When this plan is done we want to stop, so set this as a Controlling + // plan. + step_over_wp_sp->SetIsControllingPlan(true); + step_over_wp_sp->SetOkayToDiscard(false); + Status error; error = thread_sp->QueueThreadPlan(step_over_wp_sp, false); // If we couldn't push the thread plan, just stop here: @@ -895,27 +892,9 @@ protected: WatchpointSentry sentry(process_sp, wp_sp); - /* - * MIPS: Last 3bits of the watchpoint address are masked by the kernel. - * For example: - * 'n' is at 0x120010d00 and 'm' is 0x120010d04. When a watchpoint is - * set at 'm', then - * watch exception is generated even when 'n' is read/written. To handle - * this case, - * server emulates the instruction at PC and finds the base address of - * the load/store - * instruction and appends it in the description of the stop-info - * packet. If watchpoint - * is not set on this address by user then this do not stop. - */ - if (m_watch_hit_addr != LLDB_INVALID_ADDRESS) { - WatchpointSP wp_hit_sp = - thread_sp->CalculateTarget()->GetWatchpointList().FindByAddress( - m_watch_hit_addr); - if (!wp_hit_sp) { - m_should_stop = false; - wp_sp->IncrementFalseAlarmsAndReviseHitCount(); - } + if (m_silently_skip_wp) { + m_should_stop = false; + wp_sp->UndoHitCount(); } if (wp_sp->GetHitCount() <= wp_sp->GetIgnoreCount()) { @@ -1037,7 +1016,17 @@ private: bool m_should_stop = false; bool m_should_stop_is_valid = false; - lldb::addr_t m_watch_hit_addr; + // A false watchpoint hit has happened - + // the thread stopped with a watchpoint + // hit notification, but the watched region + // was not actually accessed (as determined + // by the gdb stub we're talking to). + // Continue past this watchpoint without + // notifying the user; on some targets this + // may mean disable wp, instruction step, + // re-enable wp, continue. + // On others, just continue. + bool m_silently_skip_wp = false; bool m_step_over_plan_complete = false; bool m_using_step_over_plan = false; }; @@ -1046,8 +1035,9 @@ private: class StopInfoUnixSignal : public StopInfo { public: - StopInfoUnixSignal(Thread &thread, int signo, const char *description) - : StopInfo(thread, signo) { + StopInfoUnixSignal(Thread &thread, int signo, const char *description, + std::optional<int> code) + : StopInfo(thread, signo), m_code(code) { SetDescription(description); } @@ -1102,19 +1092,26 @@ public: if (m_description.empty()) { ThreadSP thread_sp(m_thread_wp.lock()); if (thread_sp) { + UnixSignalsSP unix_signals = thread_sp->GetProcess()->GetUnixSignals(); StreamString strm; - const char *signal_name = - thread_sp->GetProcess()->GetUnixSignals()->GetSignalAsCString( - m_value); - if (signal_name) - strm.Printf("signal %s", signal_name); + strm << "signal "; + + std::string signal_name = + unix_signals->GetSignalDescription(m_value, m_code); + if (signal_name.size()) + strm << signal_name; else - strm.Printf("signal %" PRIi64, m_value); + strm.Printf("%" PRIi64, m_value); + m_description = std::string(strm.GetString()); } } return m_description.c_str(); } + +private: + // In siginfo_t terms, if m_value is si_signo, m_code is si_code. + std::optional<int> m_code; }; // StopInfoTrace @@ -1366,16 +1363,18 @@ StopInfoSP StopInfo::CreateStopReasonWithBreakpointSiteID(Thread &thread, return StopInfoSP(new StopInfoBreakpoint(thread, break_id, should_stop)); } -StopInfoSP -StopInfo::CreateStopReasonWithWatchpointID(Thread &thread, break_id_t watch_id, - lldb::addr_t watch_hit_addr) { - return StopInfoSP(new StopInfoWatchpoint(thread, watch_id, watch_hit_addr)); +StopInfoSP StopInfo::CreateStopReasonWithWatchpointID(Thread &thread, + break_id_t watch_id, + bool silently_continue) { + return StopInfoSP( + new StopInfoWatchpoint(thread, watch_id, silently_continue)); } StopInfoSP StopInfo::CreateStopReasonWithSignal(Thread &thread, int signo, - const char *description) { + const char *description, + std::optional<int> code) { thread.GetProcess()->GetUnixSignals()->IncrementSignalHitCount(signo); - return StopInfoSP(new StopInfoUnixSignal(thread, signo, description)); + return StopInfoSP(new StopInfoUnixSignal(thread, signo, description, code)); } StopInfoSP StopInfo::CreateStopReasonToTrace(Thread &thread) { @@ -1457,7 +1456,8 @@ StopInfo::GetCrashingDereference(StopInfoSP &stop_info_sp, return ValueObjectSP(); } - StackFrameSP frame_sp = thread_sp->GetSelectedFrame(); + StackFrameSP frame_sp = + thread_sp->GetSelectedFrame(DoNoSelectMostRelevantFrame); if (!frame_sp) { return ValueObjectSP(); diff --git a/contrib/llvm-project/lldb/source/Target/StructuredDataPlugin.cpp b/contrib/llvm-project/lldb/source/Target/StructuredDataPlugin.cpp index 20ed26a1a99a..1b5894b5df4b 100644 --- a/contrib/llvm-project/lldb/source/Target/StructuredDataPlugin.cpp +++ b/contrib/llvm-project/lldb/source/Target/StructuredDataPlugin.cpp @@ -32,7 +32,7 @@ StructuredDataPlugin::StructuredDataPlugin(const ProcessWP &process_wp) StructuredDataPlugin::~StructuredDataPlugin() = default; -bool StructuredDataPlugin::GetEnabled(ConstString type_name) const { +bool StructuredDataPlugin::GetEnabled(llvm::StringRef type_name) const { // By default, plugins are always enabled. Plugin authors should override // this if there is an enabled/disabled state for their plugin. return true; diff --git a/contrib/llvm-project/lldb/source/Target/Target.cpp b/contrib/llvm-project/lldb/source/Target/Target.cpp index fd0cf0a5361d..f0c57ef83c4a 100644 --- a/contrib/llvm-project/lldb/source/Target/Target.cpp +++ b/contrib/llvm-project/lldb/source/Target/Target.cpp @@ -46,6 +46,7 @@ #include "lldb/Target/Language.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Process.h" +#include "lldb/Target/RegisterTypeBuilder.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/StackFrameRecognizer.h" @@ -68,6 +69,7 @@ #include <memory> #include <mutex> #include <optional> +#include <sstream> using namespace lldb; using namespace lldb_private; @@ -292,6 +294,7 @@ void Target::Destroy() { m_stop_hooks.clear(); m_stop_hook_next_id = 0; m_suppress_stop_hooks = false; + m_repl_map.clear(); Args signal_args; ClearDummySignals(signal_args); } @@ -790,19 +793,18 @@ bool Target::ProcessIsValid() { } static bool CheckIfWatchpointsSupported(Target *target, Status &error) { - uint32_t num_supported_hardware_watchpoints; - Status rc = target->GetProcessSP()->GetWatchpointSupportInfo( - num_supported_hardware_watchpoints); + std::optional<uint32_t> num_supported_hardware_watchpoints = + target->GetProcessSP()->GetWatchpointSlotCount(); // If unable to determine the # of watchpoints available, // assume they are supported. - if (rc.Fail()) + if (!num_supported_hardware_watchpoints) return true; if (num_supported_hardware_watchpoints == 0) { error.SetErrorStringWithFormat( "Target supports (%u) hardware watchpoint slots.\n", - num_supported_hardware_watchpoints); + *num_supported_hardware_watchpoints); return false; } return true; @@ -1391,8 +1393,8 @@ static void LoadScriptingResourceForModule(const ModuleSP &module_sp, Target *target) { Status error; StreamString feedback_stream; - if (module_sp && !module_sp->LoadScriptingResourceInTarget( - target, error, &feedback_stream)) { + if (module_sp && !module_sp->LoadScriptingResourceInTarget(target, error, + feedback_stream)) { if (error.AsCString()) target->GetDebugger().GetErrorStream().Printf( "unable to load scripting data for module %s - error reported was " @@ -2127,19 +2129,46 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, // of the library bool did_create_module = false; FileSpecList search_paths = GetExecutableSearchPaths(); - // If there are image search path entries, try to use them first to acquire - // a suitable image. - if (m_image_search_paths.GetSize()) { - ModuleSpec transformed_spec(module_spec); - ConstString transformed_dir; - if (m_image_search_paths.RemapPath( - module_spec.GetFileSpec().GetDirectory(), transformed_dir)) { - transformed_spec.GetFileSpec().SetDirectory(transformed_dir); - transformed_spec.GetFileSpec().SetFilename( - module_spec.GetFileSpec().GetFilename()); - error = ModuleList::GetSharedModule(transformed_spec, module_sp, - &search_paths, &old_modules, - &did_create_module); + FileSpec symbol_file_spec; + + // Call locate module callback if set. This allows users to implement their + // own module cache system. For example, to leverage build system artifacts, + // to bypass pulling files from remote platform, or to search symbol files + // from symbol servers. + CallLocateModuleCallbackIfSet(module_spec, module_sp, symbol_file_spec, + did_create_module); + + // The result of this CallLocateModuleCallbackIfSet is one of the following. + // 1. module_sp:loaded, symbol_file_spec:set + // The callback found a module file and a symbol file for the + // module_spec. We will call module_sp->SetSymbolFileFileSpec with + // the symbol_file_spec later. + // 2. module_sp:loaded, symbol_file_spec:empty + // The callback only found a module file for the module_spec. + // 3. module_sp:empty, symbol_file_spec:set + // The callback only found a symbol file for the module. We continue + // to find a module file for this module_spec and we will call + // module_sp->SetSymbolFileFileSpec with the symbol_file_spec later. + // 4. module_sp:empty, symbol_file_spec:empty + // The callback is not set. Or the callback did not find any module + // files nor any symbol files. Or the callback failed, or something + // went wrong. We continue to find a module file for this module_spec. + + if (!module_sp) { + // If there are image search path entries, try to use them to acquire a + // suitable image. + if (m_image_search_paths.GetSize()) { + ModuleSpec transformed_spec(module_spec); + ConstString transformed_dir; + if (m_image_search_paths.RemapPath( + module_spec.GetFileSpec().GetDirectory(), transformed_dir)) { + transformed_spec.GetFileSpec().SetDirectory(transformed_dir); + transformed_spec.GetFileSpec().SetFilename( + module_spec.GetFileSpec().GetFilename()); + error = ModuleList::GetSharedModule(transformed_spec, module_sp, + &search_paths, &old_modules, + &did_create_module); + } } } @@ -2230,11 +2259,15 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, }); } + // If the locate module callback had found a symbol file, set it to the + // module_sp before preloading symbols. + if (symbol_file_spec) + module_sp->SetSymbolFileFileSpec(symbol_file_spec); + // Preload symbols outside of any lock, so hopefully we can do this for // each library in parallel. if (GetPreloadSymbols()) module_sp->PreloadSymbols(); - llvm::SmallVector<ModuleSP, 1> replaced_modules; for (ModuleSP &old_module_sp : old_modules) { if (m_images.GetIndexForModule(old_module_sp.get()) != @@ -2269,7 +2302,7 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, message << " (uuid "; if (dump_uuid.IsValid()) - dump_uuid.Dump(&message); + dump_uuid.Dump(message); else message << "not specified"; @@ -2305,6 +2338,113 @@ ModuleSP Target::GetOrCreateModule(const ModuleSpec &module_spec, bool notify, return module_sp; } +void Target::CallLocateModuleCallbackIfSet(const ModuleSpec &module_spec, + lldb::ModuleSP &module_sp, + FileSpec &symbol_file_spec, + bool &did_create_module) { + if (!m_platform_sp) + return; + + Platform::LocateModuleCallback locate_module_callback = + m_platform_sp->GetLocateModuleCallback(); + if (!locate_module_callback) + return; + + FileSpec module_file_spec; + Status error = + locate_module_callback(module_spec, module_file_spec, symbol_file_spec); + + // Locate module callback is set and called. Check the error. + Log *log = GetLog(LLDBLog::Target); + if (error.Fail()) { + LLDB_LOGF(log, "%s: locate module callback failed: %s", + LLVM_PRETTY_FUNCTION, error.AsCString()); + return; + } + + // The locate module callback was succeeded. It should returned + // 1. a combination of a module file and a symbol file. + // 2. or only a module file. + // 3. or only a symbol file. For example, a breakpad symbol text file. + // + // Check the module_file_spec and symbol_file_spec values. + // 1. module:empty symbol:empty -> Invalid + // 2. module:exists symbol:exists -> Success + // 3. module:exists symbol:empty -> Success + // 4. module:empty symbol:exists -> Success + if (!module_file_spec && !symbol_file_spec) { + // This is '1. module:empty symbol:empty -> Invalid'. + LLDB_LOGF(log, + "%s: locate module callback did not set both " + "module_file_spec and symbol_file_spec", + LLVM_PRETTY_FUNCTION); + return; + } + + // The module file should exist. + if (module_file_spec && !FileSystem::Instance().Exists(module_file_spec)) { + LLDB_LOGF(log, + "%s: locate module callback set a non-existent file to " + "module_file_spec: %s", + LLVM_PRETTY_FUNCTION, module_file_spec.GetPath().c_str()); + // Clear symbol_file_spec for the error. + symbol_file_spec.Clear(); + return; + } + + // The symbol file should exist. + if (symbol_file_spec && !FileSystem::Instance().Exists(symbol_file_spec)) { + LLDB_LOGF(log, + "%s: locate module callback set a non-existent file to " + "symbol_file_spec: %s", + LLVM_PRETTY_FUNCTION, symbol_file_spec.GetPath().c_str()); + // Clear symbol_file_spec for the error. + symbol_file_spec.Clear(); + return; + } + + if (!module_file_spec && symbol_file_spec) { + // This is '4. module:empty symbol:exists -> Success'. + // The locate module callback returned only a symbol file. For example, + // a breakpad symbol text file. GetOrCreateModule will use this returned + // symbol_file_spec. + LLDB_LOGF(log, "%s: locate module callback succeeded: symbol=%s", + LLVM_PRETTY_FUNCTION, symbol_file_spec.GetPath().c_str()); + return; + } + + // The locate module callback returned + // - '2. module:exists symbol:exists -> Success' + // - a combination of a module file and a symbol file. + // - Or '3. module:exists symbol:empty -> Success' + // - only a module file. + // Load the module file. + auto cached_module_spec(module_spec); + cached_module_spec.GetUUID().Clear(); // Clear UUID since it may contain md5 + // content hash instead of real UUID. + cached_module_spec.GetFileSpec() = module_file_spec; + cached_module_spec.GetPlatformFileSpec() = module_spec.GetFileSpec(); + cached_module_spec.SetObjectOffset(0); + + error = ModuleList::GetSharedModule(cached_module_spec, module_sp, nullptr, + nullptr, &did_create_module, false); + if (error.Success() && module_sp) { + // Succeeded to load the module file. + LLDB_LOGF(log, "%s: locate module callback succeeded: module=%s symbol=%s", + LLVM_PRETTY_FUNCTION, module_file_spec.GetPath().c_str(), + symbol_file_spec.GetPath().c_str()); + } else { + LLDB_LOGF(log, + "%s: locate module callback succeeded but failed to load: " + "module=%s symbol=%s", + LLVM_PRETTY_FUNCTION, module_file_spec.GetPath().c_str(), + symbol_file_spec.GetPath().c_str()); + // Clear module_sp and symbol_file_spec for the error. + module_sp.reset(); + symbol_file_spec.Clear(); + } +} + TargetSP Target::CalculateTarget() { return shared_from_this(); } ProcessSP Target::CalculateProcess() { return m_process_sp; } @@ -2359,6 +2499,14 @@ Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language, create_on_demand); } +CompilerType Target::GetRegisterType(const std::string &name, + const lldb_private::RegisterFlags &flags, + uint32_t byte_size) { + RegisterTypeBuilderSP provider = PluginManager::GetRegisterTypeBuilder(*this); + assert(provider); + return provider->GetRegisterType(name, flags, byte_size); +} + std::vector<lldb::TypeSystemSP> Target::GetScratchTypeSystems(bool create_on_demand) { if (!m_valid) @@ -2377,18 +2525,17 @@ Target::GetScratchTypeSystems(bool create_on_demand) { auto type_system_or_err = GetScratchTypeSystemForLanguage(language, create_on_demand); if (!type_system_or_err) - LLDB_LOG_ERROR(GetLog(LLDBLog::Target), type_system_or_err.takeError(), - "Language '{}' has expression support but no scratch type " - "system available", - Language::GetNameForLanguageType(language)); + LLDB_LOG_ERROR( + GetLog(LLDBLog::Target), type_system_or_err.takeError(), + "Language '{1}' has expression support but no scratch type " + "system available: {0}", + Language::GetNameForLanguageType(language)); else if (auto ts = *type_system_or_err) scratch_type_systems.push_back(ts); } - std::sort(scratch_type_systems.begin(), scratch_type_systems.end(), - [](lldb::TypeSystemSP a, lldb::TypeSystemSP b) { - return a.get() <= b.get(); - }); + + std::sort(scratch_type_systems.begin(), scratch_type_systems.end()); scratch_type_systems.erase( std::unique(scratch_type_systems.begin(), scratch_type_systems.end()), scratch_type_systems.end()); @@ -2400,9 +2547,10 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) { auto type_system_or_err = GetScratchTypeSystemForLanguage(language, true); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err), - "Unable to get persistent expression state for language {}", - Language::GetNameForLanguageType(language)); + LLDB_LOG_ERROR( + GetLog(LLDBLog::Target), std::move(err), + "Unable to get persistent expression state for language {1}: {0}", + Language::GetNameForLanguageType(language)); return nullptr; } @@ -2410,7 +2558,7 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) { return ts->GetPersistentExpressionState(); LLDB_LOG(GetLog(LLDBLog::Target), - "Unable to get persistent expression state for language {}", + "Unable to get persistent expression state for language {1}: {0}", Language::GetNameForLanguageType(language)); return nullptr; } @@ -2529,6 +2677,27 @@ void Target::SetDefaultArchitecture(const ArchSpec &arch) { Target::GetGlobalProperties().SetDefaultArchitecture(arch); } +llvm::Error Target::SetLabel(llvm::StringRef label) { + size_t n = LLDB_INVALID_INDEX32; + if (llvm::to_integer(label, n)) + return llvm::make_error<llvm::StringError>( + "Cannot use integer as target label.", llvm::inconvertibleErrorCode()); + TargetList &targets = GetDebugger().GetTargetList(); + for (size_t i = 0; i < targets.GetNumTargets(); i++) { + TargetSP target_sp = targets.GetTargetAtIndex(i); + if (target_sp && target_sp->GetLabel() == label) { + return llvm::make_error<llvm::StringError>( + llvm::formatv( + "Cannot use label '{0}' since it's set in target #{1}.", label, + i), + llvm::inconvertibleErrorCode()); + } + } + + m_label = label.str(); + return llvm::Error::success(); +} + Target *Target::GetTargetFromContexts(const ExecutionContext *exe_ctx_ptr, const SymbolContext *sc_ptr) { // The target can either exist in the "process" of ExecutionContext, or in @@ -2588,7 +2757,7 @@ ExpressionResults Target::EvaluateExpression( auto ts = *type_system_or_err; if (!ts) LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err), - "Scratch type system is no longer live"); + "Scratch type system is no longer live: {0}"); else persistent_var_sp = ts->GetPersistentExpressionState()->GetVariable(expr); @@ -2863,7 +3032,7 @@ bool Target::RunStopHooks() { if (print_hook_header && !any_thread_matched) { StreamString s; - cur_hook_sp->GetDescription(&s, eDescriptionLevelBrief); + cur_hook_sp->GetDescription(s, eDescriptionLevelBrief); if (s.GetSize() != 0) output_sp->Printf("\n- Hook %" PRIu64 " (%s)\n", cur_hook_sp->GetID(), s.GetData()); @@ -3082,6 +3251,17 @@ bool Target::SetSectionUnloaded(const lldb::SectionSP §ion_sp, void Target::ClearAllLoadedSections() { m_section_load_history.Clear(); } +void Target::SaveScriptedLaunchInfo(lldb_private::ProcessInfo &process_info) { + if (process_info.IsScriptedProcess()) { + // Only copy scripted process launch options. + ProcessLaunchInfo &default_launch_info = const_cast<ProcessLaunchInfo &>( + GetGlobalProperties().GetProcessLaunchInfo()); + default_launch_info.SetProcessPluginName("ScriptedProcess"); + default_launch_info.SetScriptedMetadata(process_info.GetScriptedMetadata()); + SetProcessLaunchInfo(default_launch_info); + } +} + Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { m_stats.SetLaunchOrAttachTime(); Status error; @@ -3111,19 +3291,7 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { launch_info.GetFlags().Set(eLaunchFlagDebug); - if (launch_info.IsScriptedProcess()) { - // Only copy scripted process launch options. - ProcessLaunchInfo &default_launch_info = const_cast<ProcessLaunchInfo &>( - GetGlobalProperties().GetProcessLaunchInfo()); - - default_launch_info.SetProcessPluginName("ScriptedProcess"); - default_launch_info.SetScriptedProcessClassName( - launch_info.GetScriptedProcessClassName()); - default_launch_info.SetScriptedProcessDictionarySP( - launch_info.GetScriptedProcessDictionarySP()); - - SetProcessLaunchInfo(launch_info); - } + SaveScriptedLaunchInfo(launch_info); // Get the value of synchronous execution here. If you wait till after you // have started to run, then you could have hit a breakpoint, whose command @@ -3152,8 +3320,8 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { // 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")); + launch_info.SetHijackListener(Listener::MakeListener( + Process::LaunchSynchronousHijackListenerName.data())); // 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. @@ -3181,13 +3349,14 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { assert(m_process_sp); } else { // Use a Process plugin to construct the process. - const char *plugin_name = launch_info.GetProcessPluginName(); - CreateProcess(launch_info.GetListener(), plugin_name, nullptr, false); + CreateProcess(launch_info.GetListener(), + launch_info.GetProcessPluginName(), nullptr, false); } // Since we didn't have a platform launch the process, launch it here. if (m_process_sp) { m_process_sp->HijackProcessEvents(launch_info.GetHijackListener()); + m_process_sp->SetShadowListener(launch_info.GetShadowListener()); error = m_process_sp->Launch(launch_info); } } @@ -3226,7 +3395,7 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { // SyncResume hijacker. m_process_sp->ResumeSynchronous(stream); else - error = m_process_sp->PrivateResume(); + error = m_process_sp->Resume(); if (!error.Success()) { Status error2; error2.SetErrorStringWithFormat( @@ -3329,26 +3498,27 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { ListenerSP hijack_listener_sp; const bool async = attach_info.GetAsync(); if (!async) { - hijack_listener_sp = - Listener::MakeListener("lldb.Target.Attach.attach.hijack"); + hijack_listener_sp = Listener::MakeListener( + Process::AttachSynchronousHijackListenerName.data()); attach_info.SetHijackListener(hijack_listener_sp); } Status error; if (state != eStateConnected && platform_sp != nullptr && - platform_sp->CanDebugProcess()) { + platform_sp->CanDebugProcess() && !attach_info.IsScriptedProcess()) { SetPlatform(platform_sp); process_sp = platform_sp->Attach(attach_info, GetDebugger(), this, error); } else { if (state != eStateConnected) { - const char *plugin_name = attach_info.GetProcessPluginName(); + SaveScriptedLaunchInfo(attach_info); + llvm::StringRef plugin_name = attach_info.GetProcessPluginName(); process_sp = CreateProcess(attach_info.GetListenerForProcess(GetDebugger()), plugin_name, nullptr, false); - if (process_sp == nullptr) { - error.SetErrorStringWithFormat( - "failed to create process using plugin %s", - (plugin_name) ? plugin_name : "null"); + if (!process_sp) { + error.SetErrorStringWithFormatv( + "failed to create process using plugin '{0}'", + plugin_name.empty() ? "<empty>" : plugin_name); return error; } } @@ -3361,9 +3531,10 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { if (async) { process_sp->RestoreProcessEvents(); } else { - state = process_sp->WaitForProcessToStop(std::nullopt, nullptr, false, - attach_info.GetHijackListener(), - stream); + // We are stopping all the way out to the user, so update selected frames. + state = process_sp->WaitForProcessToStop( + std::nullopt, nullptr, false, attach_info.GetHijackListener(), stream, + true, SelectMostRelevantFrame); process_sp->RestoreProcessEvents(); if (state != eStateStopped) { @@ -3620,7 +3791,7 @@ bool Target::StopHook::ExecutionContextPasses(const ExecutionContext &exc_ctx) { return will_run; } -void Target::StopHook::GetDescription(Stream *s, +void Target::StopHook::GetDescription(Stream &s, lldb::DescriptionLevel level) const { // For brief descriptions, only print the subclass description: @@ -3629,55 +3800,55 @@ void Target::StopHook::GetDescription(Stream *s, return; } - unsigned indent_level = s->GetIndentLevel(); + unsigned indent_level = s.GetIndentLevel(); - s->SetIndentLevel(indent_level + 2); + s.SetIndentLevel(indent_level + 2); - s->Printf("Hook: %" PRIu64 "\n", GetID()); + s.Printf("Hook: %" PRIu64 "\n", GetID()); if (m_active) - s->Indent("State: enabled\n"); + s.Indent("State: enabled\n"); else - s->Indent("State: disabled\n"); + s.Indent("State: disabled\n"); if (m_auto_continue) - s->Indent("AutoContinue on\n"); + s.Indent("AutoContinue on\n"); if (m_specifier_sp) { - s->Indent(); - s->PutCString("Specifier:\n"); - s->SetIndentLevel(indent_level + 4); - m_specifier_sp->GetDescription(s, level); - s->SetIndentLevel(indent_level + 2); + s.Indent(); + s.PutCString("Specifier:\n"); + s.SetIndentLevel(indent_level + 4); + m_specifier_sp->GetDescription(&s, level); + s.SetIndentLevel(indent_level + 2); } if (m_thread_spec_up) { StreamString tmp; - s->Indent("Thread:\n"); + s.Indent("Thread:\n"); m_thread_spec_up->GetDescription(&tmp, level); - s->SetIndentLevel(indent_level + 4); - s->Indent(tmp.GetString()); - s->PutCString("\n"); - s->SetIndentLevel(indent_level + 2); + s.SetIndentLevel(indent_level + 4); + s.Indent(tmp.GetString()); + s.PutCString("\n"); + s.SetIndentLevel(indent_level + 2); } GetSubclassDescription(s, level); } void Target::StopHookCommandLine::GetSubclassDescription( - Stream *s, lldb::DescriptionLevel level) const { + Stream &s, lldb::DescriptionLevel level) const { // The brief description just prints the first command. if (level == eDescriptionLevelBrief) { if (m_commands.GetSize() == 1) - s->PutCString(m_commands.GetStringAtIndex(0)); + s.PutCString(m_commands.GetStringAtIndex(0)); return; } - s->Indent("Commands: \n"); - s->SetIndentLevel(s->GetIndentLevel() + 4); + s.Indent("Commands: \n"); + s.SetIndentLevel(s.GetIndentLevel() + 4); uint32_t num_commands = m_commands.GetSize(); for (uint32_t i = 0; i < num_commands; i++) { - s->Indent(m_commands.GetStringAtIndex(i)); - s->PutCString("\n"); + s.Indent(m_commands.GetStringAtIndex(i)); + s.PutCString("\n"); } - s->SetIndentLevel(s->GetIndentLevel() - 4); + s.SetIndentLevel(s.GetIndentLevel() - 4); } // Target::StopHookCommandLine @@ -3765,13 +3936,13 @@ Target::StopHookScripted::HandleStop(ExecutionContext &exc_ctx, } void Target::StopHookScripted::GetSubclassDescription( - Stream *s, lldb::DescriptionLevel level) const { + Stream &s, lldb::DescriptionLevel level) const { if (level == eDescriptionLevelBrief) { - s->PutCString(m_class_name); + s.PutCString(m_class_name); return; } - s->Indent("Class:"); - s->Printf("%s\n", m_class_name.c_str()); + s.Indent("Class:"); + s.Printf("%s\n", m_class_name.c_str()); // Now print the extra args: // FIXME: We should use StructuredData.GetDescription on the m_extra_args @@ -3790,20 +3961,20 @@ void Target::StopHookScripted::GetSubclassDescription( if (num_keys == 0) return; - s->Indent("Args:\n"); - s->SetIndentLevel(s->GetIndentLevel() + 4); + s.Indent("Args:\n"); + s.SetIndentLevel(s.GetIndentLevel() + 4); auto print_one_element = [&s](ConstString key, StructuredData::Object *object) { - s->Indent(); - s->Printf("%s : %s\n", key.GetCString(), + s.Indent(); + s.Printf("%s : %s\n", key.GetCString(), object->GetStringValue().str().c_str()); return true; }; as_dict->ForEach(print_one_element); - s->SetIndentLevel(s->GetIndentLevel() - 4); + s.SetIndentLevel(s.GetIndentLevel() - 4); } static constexpr OptionEnumValueElement g_dynamic_value_types[] = { @@ -3998,9 +4169,9 @@ class TargetOptionValueProperties public: TargetOptionValueProperties(ConstString name) : Cloneable(name) {} - const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx, - bool will_modify, - uint32_t idx) const override { + const Property * + GetPropertyAtIndex(size_t idx, + const ExecutionContext *exe_ctx = nullptr) const override { // When getting the value for a key from the target options, we will always // try and grab the setting from the current target if there is one. Else // we just use the one from this instance. @@ -4081,9 +4252,9 @@ TargetProperties::TargetProperties(Target *target) m_experimental_properties_up = std::make_unique<TargetExperimentalProperties>(); m_collection_sp->AppendProperty( - ConstString(Properties::GetExperimentalSettingsName()), - ConstString("Experimental settings - setting these won't produce " - "errors if the setting is not present."), + Properties::GetExperimentalSettingsName(), + "Experimental settings - setting these won't produce " + "errors if the setting is not present.", true, m_experimental_properties_up->GetValueProperties()); } else { m_collection_sp = @@ -4092,13 +4263,13 @@ TargetProperties::TargetProperties(Target *target) m_experimental_properties_up = std::make_unique<TargetExperimentalProperties>(); m_collection_sp->AppendProperty( - ConstString(Properties::GetExperimentalSettingsName()), - ConstString("Experimental settings - setting these won't produce " - "errors if the setting is not present."), + Properties::GetExperimentalSettingsName(), + "Experimental settings - setting these won't produce " + "errors if the setting is not present.", true, m_experimental_properties_up->GetValueProperties()); m_collection_sp->AppendProperty( - ConstString("process"), ConstString("Settings specific to processes."), - true, Process::GetGlobalProperties().GetValueProperties()); + "process", "Settings specific to processes.", true, + Process::GetGlobalProperties().GetValueProperties()); m_collection_sp->SetValueChangedCallback( ePropertySaveObjectsDir, [this] { CheckJITObjectsDir(); }); } @@ -4121,13 +4292,14 @@ void TargetProperties::UpdateLaunchInfoFromProperties() { bool TargetProperties::GetInjectLocalVariables( ExecutionContext *exe_ctx) const { - const Property *exp_property = m_collection_sp->GetPropertyAtIndex( - exe_ctx, false, ePropertyExperimental); + const Property *exp_property = + m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx); OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties(); if (exp_values) - return exp_values->GetPropertyAtIndexAsBoolean( - exe_ctx, ePropertyInjectLocalVars, true); + return exp_values + ->GetPropertyAtIndexAs<bool>(ePropertyInjectLocalVars, exe_ctx) + .value_or(true); else return true; } @@ -4135,100 +4307,98 @@ bool TargetProperties::GetInjectLocalVariables( void TargetProperties::SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b) { const Property *exp_property = - m_collection_sp->GetPropertyAtIndex(exe_ctx, true, ePropertyExperimental); + m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx); OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties(); if (exp_values) - exp_values->SetPropertyAtIndexAsBoolean(exe_ctx, ePropertyInjectLocalVars, - true); + exp_values->SetPropertyAtIndex(ePropertyInjectLocalVars, true, exe_ctx); } ArchSpec TargetProperties::GetDefaultArchitecture() const { - OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch( - nullptr, ePropertyDefaultArch); - if (value) - return value->GetCurrentValue(); - return ArchSpec(); + const uint32_t idx = ePropertyDefaultArch; + return GetPropertyAtIndexAs<ArchSpec>(idx, {}); } void TargetProperties::SetDefaultArchitecture(const ArchSpec &arch) { - OptionValueArch *value = m_collection_sp->GetPropertyAtIndexAsOptionValueArch( - nullptr, ePropertyDefaultArch); - if (value) - return value->SetCurrentValue(arch, true); + const uint32_t idx = ePropertyDefaultArch; + SetPropertyAtIndex(idx, arch); } bool TargetProperties::GetMoveToNearestCode() const { const uint32_t idx = ePropertyMoveToNearestCode; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } lldb::DynamicValueType TargetProperties::GetPreferDynamicValue() const { const uint32_t idx = ePropertyPreferDynamic; - return (lldb::DynamicValueType) - m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<lldb::DynamicValueType>( + idx, static_cast<lldb::DynamicValueType>( + g_target_properties[idx].default_uint_value)); } bool TargetProperties::SetPreferDynamicValue(lldb::DynamicValueType d) { const uint32_t idx = ePropertyPreferDynamic; - return m_collection_sp->SetPropertyAtIndexAsEnumeration(nullptr, idx, d); + return SetPropertyAtIndex(idx, d); } bool TargetProperties::GetPreloadSymbols() const { + if (INTERRUPT_REQUESTED(m_target->GetDebugger(), + "Interrupted checking preload symbols")) { + return false; + } const uint32_t idx = ePropertyPreloadSymbols; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetPreloadSymbols(bool b) { const uint32_t idx = ePropertyPreloadSymbols; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + SetPropertyAtIndex(idx, b); } bool TargetProperties::GetDisableASLR() const { const uint32_t idx = ePropertyDisableASLR; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetDisableASLR(bool b) { const uint32_t idx = ePropertyDisableASLR; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + SetPropertyAtIndex(idx, b); } bool TargetProperties::GetInheritTCC() const { const uint32_t idx = ePropertyInheritTCC; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetInheritTCC(bool b) { const uint32_t idx = ePropertyInheritTCC; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + SetPropertyAtIndex(idx, b); } bool TargetProperties::GetDetachOnError() const { const uint32_t idx = ePropertyDetachOnError; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetDetachOnError(bool b) { const uint32_t idx = ePropertyDetachOnError; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + SetPropertyAtIndex(idx, b); } bool TargetProperties::GetDisableSTDIO() const { const uint32_t idx = ePropertyDisableSTDIO; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetDisableSTDIO(bool b) { const uint32_t idx = ePropertyDisableSTDIO; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + SetPropertyAtIndex(idx, b); } const char *TargetProperties::GetDisassemblyFlavor() const { @@ -4236,38 +4406,41 @@ const char *TargetProperties::GetDisassemblyFlavor() const { const char *return_value; x86DisassemblyFlavor flavor_value = - (x86DisassemblyFlavor)m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_target_properties[idx].default_uint_value); + GetPropertyAtIndexAs<x86DisassemblyFlavor>( + idx, static_cast<x86DisassemblyFlavor>( + g_target_properties[idx].default_uint_value)); + return_value = g_x86_dis_flavor_value_types[flavor_value].string_value; return return_value; } InlineStrategy TargetProperties::GetInlineStrategy() const { const uint32_t idx = ePropertyInlineStrategy; - return (InlineStrategy)m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<InlineStrategy>( + idx, + static_cast<InlineStrategy>(g_target_properties[idx].default_uint_value)); } llvm::StringRef TargetProperties::GetArg0() const { const uint32_t idx = ePropertyArg0; - return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, - llvm::StringRef()); + return GetPropertyAtIndexAs<llvm::StringRef>( + idx, g_target_properties[idx].default_cstr_value); } void TargetProperties::SetArg0(llvm::StringRef arg) { const uint32_t idx = ePropertyArg0; - m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, arg); + SetPropertyAtIndex(idx, arg); m_launch_info.SetArg0(arg); } bool TargetProperties::GetRunArguments(Args &args) const { const uint32_t idx = ePropertyRunArgs; - return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args); + return m_collection_sp->GetPropertyAtIndexAsArgs(idx, args); } void TargetProperties::SetRunArguments(const Args &args) { const uint32_t idx = ePropertyRunArgs; - m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args); + m_collection_sp->SetPropertyAtIndexFromArgs(idx, args); m_launch_info.GetArguments() = args; } @@ -4275,8 +4448,8 @@ Environment TargetProperties::ComputeEnvironment() const { Environment env; if (m_target && - m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, ePropertyInheritEnv, + GetPropertyAtIndexAs<bool>( + ePropertyInheritEnv, g_target_properties[ePropertyInheritEnv].default_uint_value != 0)) { if (auto platform_sp = m_target->GetPlatform()) { Environment platform_env = platform_sp->GetEnvironment(); @@ -4286,14 +4459,13 @@ Environment TargetProperties::ComputeEnvironment() const { } Args property_unset_env; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyUnsetEnvVars, + m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyUnsetEnvVars, property_unset_env); for (const auto &var : property_unset_env) env.erase(var.ref()); Args property_env; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEnvVars, - property_env); + m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEnvVars, property_env); for (const auto &KV : Environment(property_env)) env[KV.first()] = KV.second; @@ -4310,8 +4482,8 @@ Environment TargetProperties::GetInheritedEnvironment() const { if (m_target == nullptr) return environment; - if (!m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, ePropertyInheritEnv, + if (!GetPropertyAtIndexAs<bool>( + ePropertyInheritEnv, g_target_properties[ePropertyInheritEnv].default_uint_value != 0)) return environment; @@ -4324,7 +4496,7 @@ Environment TargetProperties::GetInheritedEnvironment() const { environment[KV.first()] = KV.second; Args property_unset_environment; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyUnsetEnvVars, + m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyUnsetEnvVars, property_unset_environment); for (const auto &var : property_unset_environment) environment.erase(var.ref()); @@ -4334,7 +4506,7 @@ Environment TargetProperties::GetInheritedEnvironment() const { Environment TargetProperties::GetTargetEnvironment() const { Args property_environment; - m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, ePropertyEnvVars, + m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyEnvVars, property_environment); Environment environment; for (const auto &KV : Environment(property_environment)) @@ -4346,106 +4518,93 @@ Environment TargetProperties::GetTargetEnvironment() const { void TargetProperties::SetEnvironment(Environment env) { // TODO: Get rid of the Args intermediate step const uint32_t idx = ePropertyEnvVars; - m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, Args(env)); + m_collection_sp->SetPropertyAtIndexFromArgs(idx, Args(env)); } bool TargetProperties::GetSkipPrologue() const { const uint32_t idx = ePropertySkipPrologue; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } PathMappingList &TargetProperties::GetSourcePathMap() const { const uint32_t idx = ePropertySourceMap; OptionValuePathMappings *option_value = - m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(nullptr, - false, idx); + m_collection_sp->GetPropertyAtIndexAsOptionValuePathMappings(idx); assert(option_value); return option_value->GetCurrentValue(); } bool TargetProperties::GetAutoSourceMapRelative() const { const uint32_t idx = ePropertyAutoSourceMapRelative; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::AppendExecutableSearchPaths(const FileSpec &dir) { const uint32_t idx = ePropertyExecutableSearchPaths; OptionValueFileSpecList *option_value = - m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, - false, idx); + m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(idx); assert(option_value); option_value->AppendCurrentValue(dir); } FileSpecList TargetProperties::GetExecutableSearchPaths() { const uint32_t idx = ePropertyExecutableSearchPaths; - const OptionValueFileSpecList *option_value = - m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, - false, idx); - assert(option_value); - return option_value->GetCurrentValue(); + return GetPropertyAtIndexAs<FileSpecList>(idx, {}); } FileSpecList TargetProperties::GetDebugFileSearchPaths() { const uint32_t idx = ePropertyDebugFileSearchPaths; - const OptionValueFileSpecList *option_value = - m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, - false, idx); - assert(option_value); - return option_value->GetCurrentValue(); + return GetPropertyAtIndexAs<FileSpecList>(idx, {}); } FileSpecList TargetProperties::GetClangModuleSearchPaths() { const uint32_t idx = ePropertyClangModuleSearchPaths; - const OptionValueFileSpecList *option_value = - m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, - false, idx); - assert(option_value); - return option_value->GetCurrentValue(); + return GetPropertyAtIndexAs<FileSpecList>(idx, {}); } bool TargetProperties::GetEnableAutoImportClangModules() const { const uint32_t idx = ePropertyAutoImportClangModules; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } ImportStdModule TargetProperties::GetImportStdModule() const { const uint32_t idx = ePropertyImportStdModule; - return (ImportStdModule)m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<ImportStdModule>( + idx, static_cast<ImportStdModule>( + 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); + return GetPropertyAtIndexAs<DynamicClassInfoHelper>( + idx, static_cast<DynamicClassInfoHelper>( + g_target_properties[idx].default_uint_value)); } bool TargetProperties::GetEnableAutoApplyFixIts() const { const uint32_t idx = ePropertyAutoApplyFixIts; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } uint64_t TargetProperties::GetNumberOfRetriesWithFixits() const { const uint32_t idx = ePropertyRetriesWithFixIts; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_target_properties[idx].default_uint_value); } bool TargetProperties::GetEnableNotifyAboutFixIts() const { const uint32_t idx = ePropertyNotifyAboutFixIts; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + 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); + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } void TargetProperties::CheckJITObjectsDir() { @@ -4461,7 +4620,7 @@ void TargetProperties::CheckJITObjectsDir() { if (exists && is_directory && writable) return; - m_collection_sp->GetPropertyAtIndex(nullptr, true, ePropertySaveObjectsDir) + m_collection_sp->GetPropertyAtIndex(ePropertySaveObjectsDir) ->GetValue() ->Clear(); @@ -4483,87 +4642,82 @@ void TargetProperties::CheckJITObjectsDir() { bool TargetProperties::GetEnableSyntheticValue() const { const uint32_t idx = ePropertyEnableSynthetic; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } uint32_t TargetProperties::GetMaxZeroPaddingInFloatFormat() const { const uint32_t idx = ePropertyMaxZeroPaddingInFloatFormat; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_target_properties[idx].default_uint_value); } uint32_t TargetProperties::GetMaximumNumberOfChildrenToDisplay() const { const uint32_t idx = ePropertyMaxChildrenCount; - return m_collection_sp->GetPropertyAtIndexAsSInt64( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<int64_t>( + 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); + m_collection_sp->GetPropertyAtIndexAsOptionValueUInt64(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( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_target_properties[idx].default_uint_value); } uint32_t TargetProperties::GetMaximumMemReadSize() const { const uint32_t idx = ePropertyMaxMemReadSize; - return m_collection_sp->GetPropertyAtIndexAsSInt64( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_target_properties[idx].default_uint_value); } FileSpec TargetProperties::GetStandardInputPath() const { const uint32_t idx = ePropertyInputPath; - return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } void TargetProperties::SetStandardInputPath(llvm::StringRef path) { const uint32_t idx = ePropertyInputPath; - m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); + SetPropertyAtIndex(idx, path); } FileSpec TargetProperties::GetStandardOutputPath() const { const uint32_t idx = ePropertyOutputPath; - return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } void TargetProperties::SetStandardOutputPath(llvm::StringRef path) { const uint32_t idx = ePropertyOutputPath; - m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); + SetPropertyAtIndex(idx, path); } FileSpec TargetProperties::GetStandardErrorPath() const { const uint32_t idx = ePropertyErrorPath; - return m_collection_sp->GetPropertyAtIndexAsFileSpec(nullptr, idx); + return GetPropertyAtIndexAs<FileSpec>(idx, {}); } void TargetProperties::SetStandardErrorPath(llvm::StringRef path) { const uint32_t idx = ePropertyErrorPath; - m_collection_sp->SetPropertyAtIndexAsString(nullptr, idx, path); + SetPropertyAtIndex(idx, path); } LanguageType TargetProperties::GetLanguage() const { - OptionValueLanguage *value = - m_collection_sp->GetPropertyAtIndexAsOptionValueLanguage( - nullptr, ePropertyLanguage); - if (value) - return value->GetCurrentValue(); - return LanguageType(); + const uint32_t idx = ePropertyLanguage; + return GetPropertyAtIndexAs<LanguageType>(idx, {}); } llvm::StringRef TargetProperties::GetExpressionPrefixContents() { const uint32_t idx = ePropertyExprPrefix; OptionValueFileSpec *file = - m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(nullptr, false, - idx); + m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpec(idx); if (file) { DataBufferSP data_sp(file->GetFileContents()); if (data_sp) @@ -4576,89 +4730,110 @@ llvm::StringRef TargetProperties::GetExpressionPrefixContents() { uint64_t TargetProperties::GetExprErrorLimit() const { const uint32_t idx = ePropertyExprErrorLimit; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_target_properties[idx].default_uint_value); +} + +uint64_t TargetProperties::GetExprAllocAddress() const { + const uint32_t idx = ePropertyExprAllocAddress; + return GetPropertyAtIndexAs<uint64_t>( + idx, g_target_properties[idx].default_uint_value); +} + +uint64_t TargetProperties::GetExprAllocSize() const { + const uint32_t idx = ePropertyExprAllocSize; + return GetPropertyAtIndexAs<uint64_t>( + idx, g_target_properties[idx].default_uint_value); +} + +uint64_t TargetProperties::GetExprAllocAlign() const { + const uint32_t idx = ePropertyExprAllocAlign; + return GetPropertyAtIndexAs<uint64_t>( + idx, g_target_properties[idx].default_uint_value); } bool TargetProperties::GetBreakpointsConsultPlatformAvoidList() { const uint32_t idx = ePropertyBreakpointUseAvoidList; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } bool TargetProperties::GetUseHexImmediates() const { const uint32_t idx = ePropertyUseHexImmediates; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } bool TargetProperties::GetUseFastStepping() const { const uint32_t idx = ePropertyUseFastStepping; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } bool TargetProperties::GetDisplayExpressionsInCrashlogs() const { const uint32_t idx = ePropertyDisplayExpressionsInCrashlogs; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } LoadScriptFromSymFile TargetProperties::GetLoadScriptFromSymbolFile() const { const uint32_t idx = ePropertyLoadScriptFromSymbolFile; - return (LoadScriptFromSymFile) - m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<LoadScriptFromSymFile>( + idx, static_cast<LoadScriptFromSymFile>( + g_target_properties[idx].default_uint_value)); } LoadCWDlldbinitFile TargetProperties::GetLoadCWDlldbinitFile() const { const uint32_t idx = ePropertyLoadCWDlldbinitFile; - return (LoadCWDlldbinitFile)m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<LoadCWDlldbinitFile>( + idx, static_cast<LoadCWDlldbinitFile>( + g_target_properties[idx].default_uint_value)); } Disassembler::HexImmediateStyle TargetProperties::GetHexImmediateStyle() const { const uint32_t idx = ePropertyHexImmediateStyle; - return (Disassembler::HexImmediateStyle) - m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<Disassembler::HexImmediateStyle>( + idx, static_cast<Disassembler::HexImmediateStyle>( + g_target_properties[idx].default_uint_value)); } MemoryModuleLoadLevel TargetProperties::GetMemoryModuleLoadLevel() const { const uint32_t idx = ePropertyMemoryModuleLoadLevel; - return (MemoryModuleLoadLevel) - m_collection_sp->GetPropertyAtIndexAsEnumeration( - nullptr, idx, g_target_properties[idx].default_uint_value); + return GetPropertyAtIndexAs<MemoryModuleLoadLevel>( + idx, static_cast<MemoryModuleLoadLevel>( + g_target_properties[idx].default_uint_value)); } bool TargetProperties::GetUserSpecifiedTrapHandlerNames(Args &args) const { const uint32_t idx = ePropertyTrapHandlerNames; - return m_collection_sp->GetPropertyAtIndexAsArgs(nullptr, idx, args); + return m_collection_sp->GetPropertyAtIndexAsArgs(idx, args); } void TargetProperties::SetUserSpecifiedTrapHandlerNames(const Args &args) { const uint32_t idx = ePropertyTrapHandlerNames; - m_collection_sp->SetPropertyAtIndexFromArgs(nullptr, idx, args); + m_collection_sp->SetPropertyAtIndexFromArgs(idx, args); } bool TargetProperties::GetDisplayRuntimeSupportValues() const { const uint32_t idx = ePropertyDisplayRuntimeSupportValues; - return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetDisplayRuntimeSupportValues(bool b) { const uint32_t idx = ePropertyDisplayRuntimeSupportValues; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + SetPropertyAtIndex(idx, b); } bool TargetProperties::GetDisplayRecognizedArguments() const { const uint32_t idx = ePropertyDisplayRecognizedArguments; - return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetDisplayRecognizedArguments(bool b) { const uint32_t idx = ePropertyDisplayRecognizedArguments; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + SetPropertyAtIndex(idx, b); } const ProcessLaunchInfo &TargetProperties::GetProcessLaunchInfo() const { @@ -4695,19 +4870,19 @@ void TargetProperties::SetProcessLaunchInfo( bool TargetProperties::GetRequireHardwareBreakpoints() const { const uint32_t idx = ePropertyRequireHardwareBreakpoints; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetRequireHardwareBreakpoints(bool b) { const uint32_t idx = ePropertyRequireHardwareBreakpoints; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); + m_collection_sp->SetPropertyAtIndex(idx, b); } bool TargetProperties::GetAutoInstallMainExecutable() const { const uint32_t idx = ePropertyAutoInstallMainExecutable; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::Arg0ValueChangedCallback() { @@ -4769,13 +4944,13 @@ void TargetProperties::DisableSTDIOValueChangedCallback() { bool TargetProperties::GetDebugUtilityExpression() const { const uint32_t idx = ePropertyDebugUtilityExpression; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_target_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_target_properties[idx].default_uint_value != 0); } void TargetProperties::SetDebugUtilityExpression(bool debug) { const uint32_t idx = ePropertyDebugUtilityExpression; - m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, debug); + SetPropertyAtIndex(idx, debug); } // Target::TargetEventData @@ -4789,9 +4964,8 @@ Target::TargetEventData::TargetEventData(const lldb::TargetSP &target_sp, Target::TargetEventData::~TargetEventData() = default; -ConstString Target::TargetEventData::GetFlavorString() { - static ConstString g_flavor("Target::TargetEventData"); - return g_flavor; +llvm::StringRef Target::TargetEventData::GetFlavorString() { + return "Target::TargetEventData"; } void Target::TargetEventData::Dump(Stream *s) const { diff --git a/contrib/llvm-project/lldb/source/Target/TargetList.cpp b/contrib/llvm-project/lldb/source/Target/TargetList.cpp index 8ce2ae8c2898..cb198e388011 100644 --- a/contrib/llvm-project/lldb/source/Target/TargetList.cpp +++ b/contrib/llvm-project/lldb/source/Target/TargetList.cpp @@ -325,6 +325,7 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, return error; } target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); + debugger.GetTargetList().RegisterInProcessTarget(target_sp); target_sp->SetExecutableModule(exe_module_sp, load_dependent_files); if (user_exe_path_is_bundle) exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, @@ -336,6 +337,7 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, // No file was specified, just create an empty target with any arch if a // valid arch was specified target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); + debugger.GetTargetList().RegisterInProcessTarget(target_sp); } if (!target_sp) @@ -489,7 +491,7 @@ uint32_t TargetList::SignalIfRunning(lldb::pid_t pid, int signo) { return num_signals_sent; } -int TargetList::GetNumTargets() const { +size_t TargetList::GetNumTargets() const { std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); return m_target_list.size(); } @@ -513,6 +515,7 @@ uint32_t TargetList::GetIndexOfTarget(lldb::TargetSP target_sp) const { void TargetList::AddTargetInternal(TargetSP target_sp, bool do_select) { lldbassert(!llvm::is_contained(m_target_list, target_sp) && "target already exists it the list"); + UnregisterInProcessTarget(target_sp); m_target_list.push_back(std::move(target_sp)); if (do_select) SetSelectedTargetInternal(m_target_list.size() - 1); @@ -540,3 +543,36 @@ lldb::TargetSP TargetList::GetSelectedTarget() { m_selected_target_idx = 0; return GetTargetAtIndex(m_selected_target_idx); } + +bool TargetList::AnyTargetContainsModule(Module &module) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + for (const auto &target_sp : m_target_list) { + if (target_sp->GetImages().FindModule(&module)) + return true; + } + for (const auto &target_sp: m_in_process_target_list) { + if (target_sp->GetImages().FindModule(&module)) + return true; + } + return false; +} + + void TargetList::RegisterInProcessTarget(TargetSP target_sp) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + [[maybe_unused]] bool was_added; + std::tie(std::ignore, was_added) = + m_in_process_target_list.insert(target_sp); + assert(was_added && "Target pointer was left in the in-process map"); + } + + void TargetList::UnregisterInProcessTarget(TargetSP target_sp) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + [[maybe_unused]] bool was_present = + m_in_process_target_list.erase(target_sp); + assert(was_present && "Target pointer being removed was not registered"); + } + + bool TargetList::IsTargetInProcess(TargetSP target_sp) { + std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex); + return m_in_process_target_list.count(target_sp) == 1; + } diff --git a/contrib/llvm-project/lldb/source/Target/TargetProperties.td b/contrib/llvm-project/lldb/source/Target/TargetProperties.td index 202304174bc1..19ea505af656 100644 --- a/contrib/llvm-project/lldb/source/Target/TargetProperties.td +++ b/contrib/llvm-project/lldb/source/Target/TargetProperties.td @@ -24,6 +24,15 @@ let Definition = "target" in { DefaultUnsignedValue<5>, Desc<"The maximum amount of errors to emit while parsing an expression. " "A value of 0 means to always continue parsing if possible.">; + def ExprAllocAddress: Property<"expr-alloc-address", "UInt64">, + DefaultUnsignedValue<0>, + Desc<"Start address within the process address space of memory allocation for expression evaluation.">; + def ExprAllocSize: Property<"expr-alloc-size", "UInt64">, + DefaultUnsignedValue<0>, + Desc<"Amount of memory in bytes to allocate for expression evaluation.">; + def ExprAllocAlign: Property<"expr-alloc-align", "UInt64">, + DefaultUnsignedValue<0>, + Desc<"Alignment for each memory allocation for expression evaluation.">; def PreferDynamic: Property<"prefer-dynamic-value", "Enum">, DefaultEnumValue<"eDynamicDontRunTarget">, EnumValues<"OptionEnumValues(g_dynamic_value_types)">, @@ -216,7 +225,7 @@ let Definition = "process" in { def DisableLangRuntimeUnwindPlans: Property<"disable-language-runtime-unwindplans", "Boolean">, Global, DefaultFalse, - Desc<"If true, LanguageRuntime plugins' UnwindPlans will not be used when backtracing.">; + Desc<"If true, language runtime augmented/overidden backtraces will not be used when printing a stack trace.">; def DetachKeepsStopped: Property<"detach-keeps-stopped", "Boolean">, Global, DefaultFalse, @@ -246,6 +255,9 @@ let Definition = "process" in { def VirtualAddressableBits: Property<"virtual-addressable-bits", "UInt64">, DefaultUnsignedValue<0>, Desc<"The number of bits used for addressing. If the value is 39, then bits 0..38 are used for addressing. The default value of 0 means unspecified.">; + def HighmemVirtualAddressableBits: Property<"highmem-virtual-addressable-bits", "UInt64">, + DefaultUnsignedValue<0>, + Desc<"The number of bits used for addressing high memory, when it differs from low memory in the same Process. When this is non-zero, target.process.virtual-addressable-bits will be the value for low memory (0x000... addresses) and this setting will be the value for high memory (0xfff... addresses). When this is zero, target.process.virtual-addressable-bits applies to all addresses. It is very uncommon to use this setting.">; def FollowForkMode: Property<"follow-fork-mode", "Enum">, DefaultEnumValue<"eFollowParent">, EnumValues<"OptionEnumValues(g_follow_fork_mode_values)">, diff --git a/contrib/llvm-project/lldb/source/Target/Thread.cpp b/contrib/llvm-project/lldb/source/Target/Thread.cpp index d620f746339e..ec4ffcbd9205 100644 --- a/contrib/llvm-project/lldb/source/Target/Thread.cpp +++ b/contrib/llvm-project/lldb/source/Target/Thread.cpp @@ -78,9 +78,9 @@ class ThreadOptionValueProperties public: ThreadOptionValueProperties(ConstString name) : Cloneable(name) {} - const Property *GetPropertyAtIndex(const ExecutionContext *exe_ctx, - bool will_modify, - uint32_t idx) const override { + const Property * + GetPropertyAtIndex(size_t idx, + const ExecutionContext *exe_ctx) const override { // When getting the value for a key from the thread options, we will always // try and grab the setting from the current thread if there is one. Else // we just use the one from this instance. @@ -112,47 +112,42 @@ ThreadProperties::~ThreadProperties() = default; const RegularExpression *ThreadProperties::GetSymbolsToAvoidRegexp() { const uint32_t idx = ePropertyStepAvoidRegex; - return m_collection_sp->GetPropertyAtIndexAsOptionValueRegex(nullptr, idx); + return GetPropertyAtIndexAs<const RegularExpression *>(idx); } FileSpecList ThreadProperties::GetLibrariesToAvoid() const { const uint32_t idx = ePropertyStepAvoidLibraries; - const OptionValueFileSpecList *option_value = - m_collection_sp->GetPropertyAtIndexAsOptionValueFileSpecList(nullptr, - false, idx); - assert(option_value); - return option_value->GetCurrentValue(); + return GetPropertyAtIndexAs<FileSpecList>(idx, {}); } bool ThreadProperties::GetTraceEnabledState() const { const uint32_t idx = ePropertyEnableThreadTrace; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_thread_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_thread_properties[idx].default_uint_value != 0); } bool ThreadProperties::GetStepInAvoidsNoDebug() const { const uint32_t idx = ePropertyStepInAvoidsNoDebug; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_thread_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_thread_properties[idx].default_uint_value != 0); } bool ThreadProperties::GetStepOutAvoidsNoDebug() const { const uint32_t idx = ePropertyStepOutAvoidsNoDebug; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - nullptr, idx, g_thread_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<bool>( + idx, g_thread_properties[idx].default_uint_value != 0); } uint64_t ThreadProperties::GetMaxBacktraceDepth() const { const uint32_t idx = ePropertyMaxBacktraceDepth; - return m_collection_sp->GetPropertyAtIndexAsUInt64( - nullptr, idx, g_thread_properties[idx].default_uint_value != 0); + return GetPropertyAtIndexAs<uint64_t>( + idx, g_thread_properties[idx].default_uint_value); } // Thread Event Data -ConstString Thread::ThreadEventData::GetFlavorString() { - static ConstString g_flavor("Thread::ThreadEventData"); - return g_flavor; +llvm::StringRef Thread::ThreadEventData::GetFlavorString() { + return "Thread::ThreadEventData"; } Thread::ThreadEventData::ThreadEventData(const lldb::ThreadSP thread_sp) @@ -264,10 +259,11 @@ void Thread::BroadcastSelectedFrameChange(StackID &new_frame_id) { new ThreadEventData(this->shared_from_this(), new_frame_id)); } -lldb::StackFrameSP Thread::GetSelectedFrame() { +lldb::StackFrameSP +Thread::GetSelectedFrame(SelectMostRelevant select_most_relevant) { StackFrameListSP stack_frame_list_sp(GetStackFrameList()); StackFrameSP frame_sp = stack_frame_list_sp->GetFrameAtIndex( - stack_frame_list_sp->GetSelectedFrameIndex()); + stack_frame_list_sp->GetSelectedFrameIndex(select_most_relevant)); FrameSelectedCallback(frame_sp.get()); return frame_sp; } @@ -298,15 +294,22 @@ bool Thread::SetSelectedFrameByIndexNoisily(uint32_t frame_idx, const bool broadcast = true; bool success = SetSelectedFrameByIndex(frame_idx, broadcast); if (success) { - StackFrameSP frame_sp = GetSelectedFrame(); + StackFrameSP frame_sp = GetSelectedFrame(DoNoSelectMostRelevantFrame); if (frame_sp) { bool already_shown = false; SymbolContext frame_sc( frame_sp->GetSymbolContext(eSymbolContextLineEntry)); - if (GetProcess()->GetTarget().GetDebugger().GetUseExternalEditor() && - frame_sc.line_entry.file && frame_sc.line_entry.line != 0) { - already_shown = Host::OpenFileInExternalEditor( - frame_sc.line_entry.file, frame_sc.line_entry.line); + const Debugger &debugger = GetProcess()->GetTarget().GetDebugger(); + if (debugger.GetUseExternalEditor() && frame_sc.line_entry.file && + frame_sc.line_entry.line != 0) { + if (llvm::Error e = Host::OpenFileInExternalEditor( + debugger.GetExternalEditor(), frame_sc.line_entry.file, + frame_sc.line_entry.line)) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e), + "OpenFileInExternalEditor failed: {0}"); + } else { + already_shown = true; + } } bool show_frame_info = true; @@ -588,36 +591,9 @@ std::string Thread::GetStopDescriptionRaw() { return raw_stop_description; } -void Thread::SelectMostRelevantFrame() { - Log *log = GetLog(LLDBLog::Thread); - - auto frames_list_sp = GetStackFrameList(); - - // Only the top frame should be recognized. - auto frame_sp = frames_list_sp->GetFrameAtIndex(0); - - auto recognized_frame_sp = frame_sp->GetRecognizedFrame(); - - if (!recognized_frame_sp) { - LLDB_LOG(log, "Frame #0 not recognized"); - return; - } - - if (StackFrameSP most_relevant_frame_sp = - recognized_frame_sp->GetMostRelevantFrame()) { - LLDB_LOG(log, "Found most relevant frame at index {0}", - most_relevant_frame_sp->GetFrameIndex()); - SetSelectedFrame(most_relevant_frame_sp.get()); - } else { - LLDB_LOG(log, "No relevant frame!"); - } -} - void Thread::WillStop() { ThreadPlan *current_plan = GetCurrentPlan(); - SelectMostRelevantFrame(); - // FIXME: I may decide to disallow threads with no plans. In which // case this should go to an assert. @@ -734,7 +710,7 @@ bool Thread::ShouldResume(StateType resume_state) { return need_to_resume; } -void Thread::DidResume() { +void Thread::DidResume() { SetResumeSignal(LLDB_INVALID_SIGNAL_NUMBER); // This will get recomputed each time when we stop. SetShouldRunBeforePublicStop(false); @@ -778,7 +754,7 @@ bool Thread::ShouldStop(Event *event_ptr) { : LLDB_INVALID_ADDRESS); return false; } - + // Clear the "must run me before stop" if it was set: SetShouldRunBeforePublicStop(false); @@ -1008,7 +984,7 @@ Vote Thread::ShouldReportStop(Event *event_ptr) { } if (GetPlans().AnyCompletedPlans()) { - // Pass skip_private = false to GetCompletedPlan, since we want to ask + // Pass skip_private = false to GetCompletedPlan, since we want to ask // the last plan, regardless of whether it is private or not. LLDB_LOGF(log, "Thread::ShouldReportStop() tid = 0x%4.4" PRIx64 @@ -1046,7 +1022,7 @@ Vote Thread::ShouldReportRun(Event *event_ptr) { Log *log = GetLog(LLDBLog::Step); if (GetPlans().AnyCompletedPlans()) { - // Pass skip_private = false to GetCompletedPlan, since we want to ask + // Pass skip_private = false to GetCompletedPlan, since we want to ask // the last plan, regardless of whether it is private or not. LLDB_LOGF(log, "Current Plan for thread %d(%p) (0x%4.4" PRIx64 @@ -1099,7 +1075,7 @@ void Thread::PushPlan(ThreadPlanSP thread_plan_sp) { static_cast<void *>(this), s.GetData(), thread_plan_sp->GetThread().GetID()); } - + GetPlans().PushPlan(std::move(thread_plan_sp)); } @@ -1117,7 +1093,7 @@ void Thread::DiscardPlan() { ThreadPlanSP discarded_plan_sp = GetPlans().DiscardPlan(); LLDB_LOGF(log, "Discarding plan: \"%s\", tid = 0x%4.4" PRIx64 ".", - discarded_plan_sp->GetName(), + discarded_plan_sp->GetName(), discarded_plan_sp->GetThread().GetID()); } @@ -1246,7 +1222,7 @@ Status Thread::UnwindInnermostExpression() { if (!innermost_expr_plan) { error.SetErrorString("No expressions currently active on this thread"); return error; - } + } DiscardThreadPlansUpToPlan(innermost_expr_plan); return error; } @@ -1390,8 +1366,8 @@ ThreadPlanSP Thread::QueueThreadPlanForStepUntil( } lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted( - bool abort_other_plans, const char *class_name, - StructuredData::ObjectSP extra_args_sp, bool stop_other_threads, + bool abort_other_plans, const char *class_name, + StructuredData::ObjectSP extra_args_sp, bool stop_other_threads, Status &status) { ThreadPlanSP thread_plan_sp(new ThreadPlanPython( @@ -1752,8 +1728,12 @@ size_t Thread::GetStatus(Stream &strm, uint32_t start_frame, SymbolContext frame_sc( frame_sp->GetSymbolContext(eSymbolContextLineEntry)); if (frame_sc.line_entry.line != 0 && frame_sc.line_entry.file) { - Host::OpenFileInExternalEditor(frame_sc.line_entry.file, - frame_sc.line_entry.line); + if (llvm::Error e = Host::OpenFileInExternalEditor( + target->GetDebugger().GetExternalEditor(), + frame_sc.line_entry.file, frame_sc.line_entry.line)) { + LLDB_LOG_ERROR(GetLog(LLDBLog::Host), std::move(e), + "OpenFileInExternalEditor failed: {0}"); + } } } } @@ -1826,7 +1806,7 @@ bool Thread::GetDescription(Stream &strm, lldb::DescriptionLevel level, id->GetType() == eStructuredDataTypeInteger) { strm.Format(" Activity '{0}', {1:x}\n", name->GetAsString()->GetValue(), - id->GetAsInteger()->GetValue()); + id->GetUnsignedIntegerValue()); } printed_activity = true; } diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp index 9913ecb591fa..7927fc314014 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlan.cpp @@ -171,6 +171,9 @@ bool ThreadPlan::IsUsuallyUnexplainedStopReason(lldb::StopReason reason) { case eStopReasonExec: case eStopReasonThreadExiting: case eStopReasonInstrumentation: + case eStopReasonFork: + case eStopReasonVFork: + case eStopReasonVForkDone: return true; default: return false; diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp index 7e9bb963bb5d..31027cd9e011 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -163,7 +163,7 @@ void ThreadPlanCallFunction::ReportRegisterState(const char *message) { reg_idx < num_registers; ++reg_idx) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg_idx); if (reg_ctx->ReadRegister(reg_info, reg_value)) { - DumpRegisterValue(reg_value, &strm, reg_info, true, false, + DumpRegisterValue(reg_value, strm, *reg_info, true, false, eFormatDefault); strm.EOL(); } diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp index bc2a7a02e99c..d6de6b3c3cf0 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanPython.cpp @@ -136,8 +136,11 @@ bool ThreadPlanPython::MischiefManaged() { // I don't really need mischief_managed, since it's simpler to just call // SetPlanComplete in should_stop. mischief_managed = IsPlanComplete(); - if (mischief_managed) + if (mischief_managed) { + // We need to cache the stop reason here we'll need it in GetDescription. + GetDescription(&m_stop_description, eDescriptionLevelBrief); m_implementation_sp.reset(); + } } return mischief_managed; } @@ -158,15 +161,40 @@ lldb::StateType ThreadPlanPython::GetPlanRunState() { return run_state; } -// The ones below are not currently exported to Python. void ThreadPlanPython::GetDescription(Stream *s, lldb::DescriptionLevel level) { - s->Printf("Python thread plan implemented by class %s.", + Log *log = GetLog(LLDBLog::Thread); + LLDB_LOGF(log, "%s called on Python Thread Plan: %s )", LLVM_PRETTY_FUNCTION, + m_class_name.c_str()); + if (m_implementation_sp) { + ScriptInterpreter *script_interp = GetScriptInterpreter(); + if (script_interp) { + bool script_error; + bool added_desc = script_interp->ScriptedThreadPlanGetStopDescription( + m_implementation_sp, s, script_error); + if (script_error || !added_desc) + s->Printf("Python thread plan implemented by class %s.", m_class_name.c_str()); + } + return; + } + // It's an error not to have a description, so if we get here, we should + // add something. + if (m_stop_description.Empty()) + s->Printf("Python thread plan implemented by class %s.", + m_class_name.c_str()); + s->PutCString(m_stop_description.GetData()); } +// The ones below are not currently exported to Python. bool ThreadPlanPython::WillStop() { 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; } + +bool ThreadPlanPython::DoWillResume(lldb::StateType resume_state, + bool current_plan) { + m_stop_description.Clear(); + return true; +} diff --git a/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp b/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp index 82927ef64877..f4d80ba89071 100644 --- a/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp +++ b/contrib/llvm-project/lldb/source/Target/ThreadPlanTracer.cpp @@ -56,7 +56,7 @@ Stream *ThreadPlanTracer::GetLogStream() { Thread &ThreadPlanTracer::GetThread() { if (m_thread) return *m_thread; - + ThreadSP thread_sp = m_process.GetThreadList().FindThreadByID(m_tid); m_thread = thread_sp.get(); return *m_thread; @@ -107,8 +107,9 @@ TypeFromUser ThreadPlanAssemblyTracer::GetIntPointerType() { auto type_system_or_err = target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(GetLog(LLDBLog::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: {0}"); } else { if (auto ts = *type_system_or_err) m_intptr_type = TypeFromUser(ts->GetBuiltinTypeForEncodingAndBitSize( @@ -223,7 +224,7 @@ void ThreadPlanAssemblyTracer::Log() { reg_value != m_register_values[reg_num]) { if (reg_value.GetType() != RegisterValue::eTypeInvalid) { stream->PutCString("\n\t"); - DumpRegisterValue(reg_value, stream, reg_info, true, false, + DumpRegisterValue(reg_value, *stream, *reg_info, true, false, eFormatDefault); } } diff --git a/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp b/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp index 858b1691f318..0e738241b1c5 100644 --- a/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp +++ b/contrib/llvm-project/lldb/source/Target/UnixSignals.cpp @@ -9,11 +9,11 @@ #include "lldb/Target/UnixSignals.h" #include "Plugins/Process/Utility/FreeBSDSignals.h" #include "Plugins/Process/Utility/LinuxSignals.h" -#include "Plugins/Process/Utility/MipsLinuxSignals.h" #include "Plugins/Process/Utility/NetBSDSignals.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/ArchSpec.h" #include <optional> +#include <sstream> using namespace lldb_private; using namespace llvm; @@ -33,17 +33,8 @@ UnixSignals::Signal::Signal(const char *name, bool default_suppress, lldb::UnixSignalsSP UnixSignals::Create(const ArchSpec &arch) { const auto &triple = arch.GetTriple(); switch (triple.getOS()) { - case llvm::Triple::Linux: { - switch (triple.getArch()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - return std::make_shared<MipsLinuxSignals>(); - default: - return std::make_shared<LinuxSignals>(); - } - } + case llvm::Triple::Linux: + return std::make_shared<LinuxSignals>(); case llvm::Triple::FreeBSD: case llvm::Triple::OpenBSD: return std::make_shared<FreeBSDSignals>(); @@ -122,6 +113,17 @@ void UnixSignals::AddSignal(int signo, const char *name, bool default_suppress, ++m_version; } +void UnixSignals::AddSignalCode(int signo, int code, + const llvm::StringLiteral description, + SignalCodePrintOption print_option) { + collection::iterator signal = m_signals.find(signo); + assert(signal != m_signals.end() && + "Tried to add code to signal that does not exist."); + signal->second.m_codes.insert( + std::pair{code, SignalCode{description, print_option}}); + ++m_version; +} + void UnixSignals::RemoveSignal(int signo) { collection::iterator pos = m_signals.find(signo); if (pos != m_signals.end()) @@ -137,14 +139,64 @@ const char *UnixSignals::GetSignalAsCString(int signo) const { return pos->second.m_name.GetCString(); } +std::string +UnixSignals::GetSignalDescription(int32_t signo, std::optional<int32_t> code, + std::optional<lldb::addr_t> addr, + std::optional<lldb::addr_t> lower, + std::optional<lldb::addr_t> upper) const { + std::string str; + + collection::const_iterator pos = m_signals.find(signo); + if (pos != m_signals.end()) { + str = pos->second.m_name.GetCString(); + + if (code) { + std::map<int32_t, SignalCode>::const_iterator cpos = + pos->second.m_codes.find(*code); + if (cpos != pos->second.m_codes.end()) { + const SignalCode &sc = cpos->second; + str += ": "; + if (sc.m_print_option != SignalCodePrintOption::Bounds) + str += sc.m_description.str(); + + std::stringstream strm; + switch (sc.m_print_option) { + case SignalCodePrintOption::None: + break; + case SignalCodePrintOption::Address: + if (addr) + strm << " (fault address: 0x" << std::hex << *addr << ")"; + break; + case SignalCodePrintOption::Bounds: + if (lower && upper && addr) { + if ((unsigned long)(*addr) < *lower) + strm << "lower bound violation "; + else + strm << "upper bound violation "; + + strm << "(fault address: 0x" << std::hex << *addr; + strm << ", lower bound: 0x" << std::hex << *lower; + strm << ", upper bound: 0x" << std::hex << *upper; + strm << ")"; + } else + strm << sc.m_description.str(); + + break; + } + str += strm.str(); + } + } + } + + return str; +} + bool UnixSignals::SignalIsValid(int32_t signo) const { return m_signals.find(signo) != m_signals.end(); } -ConstString UnixSignals::GetShortName(ConstString name) const { - if (name) - return ConstString(name.GetStringRef().substr(3)); // Remove "SIG" from name - return name; +llvm::StringRef UnixSignals::GetShortName(llvm::StringRef name) const { + return name.substr(3); // Remove "SIG" from name } int32_t UnixSignals::GetSignalNumberFromName(const char *name) const { diff --git a/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp b/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp index e1d7ee3ee276..fb0e985a0d56 100644 --- a/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ArchSpec.cpp @@ -16,8 +16,8 @@ #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/BinaryFormat/MachO.h" -#include "llvm/Support/ARMTargetParser.h" #include "llvm/Support/Compiler.h" +#include "llvm/TargetParser/ARMTargetParser.h" using namespace lldb; using namespace lldb_private; @@ -154,6 +154,10 @@ static const CoreDefinition g_core_definitions[] = { {eByteOrderLittle, 8, 2, 4, llvm::Triple::mips64el, ArchSpec::eCore_mips64r6el, "mips64r6el"}, + // MSP430 + {eByteOrderLittle, 2, 2, 4, llvm::Triple::msp430, ArchSpec::eCore_msp430, + "msp430"}, + {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_generic, "powerpc"}, {eByteOrderBig, 4, 4, 4, llvm::Triple::ppc, ArchSpec::eCore_ppc_ppc601, @@ -402,6 +406,8 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { ArchSpec::eMIPSSubType_mips64r2el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r2el {ArchSpec::eCore_mips64r6el, llvm::ELF::EM_MIPS, ArchSpec::eMIPSSubType_mips64r6el, 0xFFFFFFFFu, 0xFFFFFFFFu}, // mips64r6el + {ArchSpec::eCore_msp430, llvm::ELF::EM_MSP430, LLDB_INVALID_CPUTYPE, + 0xFFFFFFFFu, 0xFFFFFFFFu}, // MSP430 {ArchSpec::eCore_hexagon_generic, llvm::ELF::EM_HEXAGON, LLDB_INVALID_CPUTYPE, 0xFFFFFFFFu, 0xFFFFFFFFu}, // HEXAGON {ArchSpec::eCore_arc, llvm::ELF::EM_ARC_COMPACT2, LLDB_INVALID_CPUTYPE, @@ -537,7 +543,6 @@ void ArchSpec::Clear() { m_triple = llvm::Triple(); m_core = kCore_invalid; m_byte_order = eByteOrderInvalid; - m_distribution_id.Clear(); m_flags = 0; } @@ -683,14 +688,6 @@ llvm::Triple::ArchType ArchSpec::GetMachine() const { return llvm::Triple::UnknownArch; } -ConstString ArchSpec::GetDistributionId() const { - return m_distribution_id; -} - -void ArchSpec::SetDistributionId(const char *distribution_id) { - m_distribution_id.SetCString(distribution_id); -} - uint32_t ArchSpec::GetAddressByteSize() const { const CoreDefinition *core_def = FindCoreDefinition(m_core); if (core_def) { @@ -899,6 +896,9 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu, case llvm::ELF::ELFOSABI_SOLARIS: m_triple.setOS(llvm::Triple::OSType::Solaris); break; + case llvm::ELF::ELFOSABI_STANDALONE: + m_triple.setOS(llvm::Triple::OSType::UnknownOS); + break; } } else if (arch_type == eArchTypeCOFF && os == llvm::Triple::Win32) { m_triple.setVendor(llvm::Triple::PC); @@ -970,8 +970,6 @@ static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, } bool ArchSpec::IsMatch(const ArchSpec &rhs, MatchType match) const { - // explicitly ignoring m_distribution_id in this method. - if (GetByteOrder() != rhs.GetByteOrder() || !cores_match(GetCore(), rhs.GetCore(), true, match == ExactMatch)) return false; diff --git a/contrib/llvm-project/lldb/source/Utility/Args.cpp b/contrib/llvm-project/lldb/source/Utility/Args.cpp index 2d50b43bc241..d34433996021 100644 --- a/contrib/llvm-project/lldb/source/Utility/Args.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Args.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Utility/Args.h" -#include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StringList.h" @@ -385,20 +384,21 @@ void Args::Clear() { std::string Args::GetShellSafeArgument(const FileSpec &shell, llvm::StringRef unsafe_arg) { struct ShellDescriptor { - ConstString m_basename; + llvm::StringRef m_basename; llvm::StringRef m_escapables; }; - static ShellDescriptor g_Shells[] = {{ConstString("bash"), " '\"<>()&;"}, - {ConstString("fish"), " '\"<>()&\\|;"}, - {ConstString("tcsh"), " '\"<>()&;"}, - {ConstString("zsh"), " '\"<>()&;\\|"}, - {ConstString("sh"), " '\"<>()&;"}}; + static ShellDescriptor g_Shells[] = {{"bash", " '\"<>()&;"}, + {"fish", " '\"<>()&\\|;"}, + {"tcsh", " '\"<>()&;"}, + {"zsh", " '\"<>()&;\\|"}, + {"sh", " '\"<>()&;"}}; // safe minimal set llvm::StringRef escapables = " '\""; - if (auto basename = shell.GetFilename()) { + auto basename = shell.GetFilename().GetStringRef(); + if (!basename.empty()) { for (const auto &Shell : g_Shells) { if (Shell.m_basename == basename) { escapables = Shell.m_escapables; diff --git a/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp b/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp index 31530f8a6443..c9ecd4a7d2a9 100644 --- a/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Broadcaster.cpp @@ -23,9 +23,9 @@ using namespace lldb; using namespace lldb_private; -Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, const char *name) +Broadcaster::Broadcaster(BroadcasterManagerSP manager_sp, std::string name) : m_broadcaster_sp(std::make_shared<BroadcasterImpl>(*this)), - m_manager_sp(std::move(manager_sp)), m_broadcaster_name(name) { + m_manager_sp(std::move(manager_sp)), m_broadcaster_name(std::move(name)) { Log *log = GetLog(LLDBLog::Object); LLDB_LOG(log, "{0} Broadcaster::Broadcaster(\"{1}\")", static_cast<void *>(this), GetBroadcasterName()); @@ -215,12 +215,12 @@ void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp, if (log) { StreamString event_description; event_sp->Dump(&event_description); - LLDB_LOGF(log, - "%p Broadcaster(\"%s\")::BroadcastEvent (event_sp = {%s}, " - "unique =%i) hijack = %p", - static_cast<void *>(this), GetBroadcasterName(), - event_description.GetData(), unique, - static_cast<void *>(hijacking_listener_sp.get())); + LLDB_LOG(log, + "{0:x} Broadcaster(\"{1}\")::BroadcastEvent (event_sp = {2}, " + "unique={3}) hijack = {4:x}", + static_cast<void *>(this), GetBroadcasterName(), + event_description.GetData(), unique, + static_cast<void *>(hijacking_listener_sp.get())); } if (hijacking_listener_sp) { @@ -228,6 +228,8 @@ void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp, &m_broadcaster, event_type)) return; hijacking_listener_sp->AddEvent(event_sp); + if (m_shadow_listener) + m_shadow_listener->AddEvent(event_sp); } else { for (auto &pair : GetListeners()) { if (!(pair.second & event_type)) @@ -237,6 +239,8 @@ void Broadcaster::BroadcasterImpl::PrivateBroadcastEvent(EventSP &event_sp, continue; pair.first->AddEvent(event_sp); + if (m_shadow_listener) + m_shadow_listener->AddEvent(event_sp); } } } @@ -332,10 +336,13 @@ uint32_t BroadcasterManager::RegisterListenerForEvents( collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end(); uint32_t available_bits = event_spec.GetEventBits(); + auto class_matches = [&event_spec](const event_listener_key &input) -> bool { + return input.first.GetBroadcasterClass() == + event_spec.GetBroadcasterClass(); + }; + while (iter != end_iter && - (iter = find_if(iter, end_iter, - BroadcasterClassMatches( - event_spec.GetBroadcasterClass()))) != end_iter) { + (iter = find_if(iter, end_iter, class_matches)) != end_iter) { available_bits &= ~((*iter).first.GetEventBits()); iter++; } @@ -358,18 +365,22 @@ bool BroadcasterManager::UnregisterListenerForEvents( if (m_listeners.erase(listener_sp) == 0) return false; - ListenerMatchesAndSharedBits predicate(event_spec, listener_sp); + auto listener_matches_and_shared_bits = + [&listener_sp, &event_spec](const event_listener_key &input) -> bool { + return input.first.GetBroadcasterClass() == + event_spec.GetBroadcasterClass() && + (input.first.GetEventBits() & event_spec.GetEventBits()) != 0 && + input.second == listener_sp; + }; std::vector<BroadcastEventSpec> to_be_readded; uint32_t event_bits_to_remove = event_spec.GetEventBits(); // Go through the map and delete the exact matches, and build a list of // matches that weren't exact to re-add: - while (true) { - collection::iterator iter, end_iter = m_event_map.end(); - iter = find_if(m_event_map.begin(), end_iter, predicate); - if (iter == end_iter) { + for (auto iter = m_event_map.begin(), end = m_event_map.end();;) { + iter = find_if(iter, end, listener_matches_and_shared_bits); + if (iter == end) break; - } uint32_t iter_event_bits = (*iter).first.GetEventBits(); removed_some = true; @@ -378,12 +389,12 @@ bool BroadcasterManager::UnregisterListenerForEvents( to_be_readded.emplace_back(event_spec.GetBroadcasterClass(), new_event_bits); } - m_event_map.erase(iter); + iter = m_event_map.erase(iter); } // Okay now add back the bits that weren't completely removed: - for (size_t i = 0; i < to_be_readded.size(); i++) { - m_event_map.insert(event_listener_key(to_be_readded[i], listener_sp)); + for (const auto &event : to_be_readded) { + m_event_map.insert(event_listener_key(event, listener_sp)); } return removed_some; @@ -393,10 +404,13 @@ ListenerSP BroadcasterManager::GetListenerForEventSpec( const BroadcastEventSpec &event_spec) const { std::lock_guard<std::recursive_mutex> guard(m_manager_mutex); - collection::const_iterator iter, end_iter = m_event_map.end(); - iter = find_if(m_event_map.begin(), end_iter, - BroadcastEventSpecMatches(event_spec)); - if (iter != end_iter) + auto event_spec_matches = + [&event_spec](const event_listener_key &input) -> bool { + return input.first.IsContainedIn(event_spec); + }; + + auto iter = llvm::find_if(m_event_map, event_spec_matches); + if (iter != m_event_map.end()) return (*iter).second; return nullptr; @@ -404,38 +418,47 @@ ListenerSP BroadcasterManager::GetListenerForEventSpec( void BroadcasterManager::RemoveListener(Listener *listener) { std::lock_guard<std::recursive_mutex> guard(m_manager_mutex); - ListenerMatchesPointer predicate(listener); - listener_collection::iterator iter = m_listeners.begin(), - end_iter = m_listeners.end(); + auto listeners_predicate = + [&listener](const lldb::ListenerSP &input) -> bool { + return input.get() == listener; + }; - iter = std::find_if(iter, end_iter, predicate); - if (iter != end_iter) + if (auto iter = llvm::find_if(m_listeners, listeners_predicate); + iter != m_listeners.end()) m_listeners.erase(iter); - while (true) { - collection::iterator iter, end_iter = m_event_map.end(); - iter = find_if(m_event_map.begin(), end_iter, predicate); - if (iter == end_iter) + auto events_predicate = [listener](const event_listener_key &input) -> bool { + return input.second.get() == listener; + }; + + // TODO: use 'std::map::erase_if' when moving to c++20. + for (auto iter = m_event_map.begin(), end = m_event_map.end();;) { + iter = find_if(iter, end, events_predicate); + if (iter == end) break; - m_event_map.erase(iter); + iter = m_event_map.erase(iter); } } void BroadcasterManager::RemoveListener(const lldb::ListenerSP &listener_sp) { std::lock_guard<std::recursive_mutex> guard(m_manager_mutex); - ListenerMatches predicate(listener_sp); + + auto listener_matches = + [&listener_sp](const event_listener_key &input) -> bool { + return input.second == listener_sp; + }; if (m_listeners.erase(listener_sp) == 0) return; - while (true) { - collection::iterator iter, end_iter = m_event_map.end(); - iter = find_if(m_event_map.begin(), end_iter, predicate); + // TODO: use 'std::map::erase_if' when moving to c++20. + for (auto iter = m_event_map.begin(), end_iter = m_event_map.end();;) { + iter = find_if(iter, end_iter, listener_matches); if (iter == end_iter) break; - m_event_map.erase(iter); + iter = m_event_map.erase(iter); } } @@ -445,10 +468,13 @@ void BroadcasterManager::SignUpListenersForBroadcaster( collection::iterator iter = m_event_map.begin(), end_iter = m_event_map.end(); + auto class_matches = [&broadcaster](const event_listener_key &input) -> bool { + return input.first.GetBroadcasterClass() == + broadcaster.GetBroadcasterClass(); + }; + while (iter != end_iter && - (iter = find_if(iter, end_iter, - BroadcasterClassMatches( - broadcaster.GetBroadcasterClass()))) != end_iter) { + (iter = find_if(iter, end_iter, class_matches)) != end_iter) { (*iter).second->StartListeningForEvents(&broadcaster, (*iter).first.GetEventBits()); iter++; @@ -457,11 +483,9 @@ void BroadcasterManager::SignUpListenersForBroadcaster( void BroadcasterManager::Clear() { std::lock_guard<std::recursive_mutex> guard(m_manager_mutex); - listener_collection::iterator end_iter = m_listeners.end(); - for (listener_collection::iterator iter = m_listeners.begin(); - iter != end_iter; iter++) - (*iter)->BroadcasterManagerWillDestruct(this->shared_from_this()); + for (auto &listener : m_listeners) + listener->BroadcasterManagerWillDestruct(this->shared_from_this()); m_listeners.clear(); m_event_map.clear(); } diff --git a/contrib/llvm-project/lldb/source/Utility/ConstString.cpp b/contrib/llvm-project/lldb/source/Utility/ConstString.cpp index 7b084769e1ff..4535771adfb7 100644 --- a/contrib/llvm-project/lldb/source/Utility/ConstString.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ConstString.cpp @@ -98,7 +98,7 @@ public: return nullptr; } - const char *GetConstCStringWithStringRef(const llvm::StringRef &string_ref) { + const char *GetConstCStringWithStringRef(llvm::StringRef string_ref) { if (string_ref.data()) { const uint8_t h = hash(string_ref); @@ -171,7 +171,7 @@ public: } protected: - uint8_t hash(const llvm::StringRef &s) const { + uint8_t hash(llvm::StringRef s) const { uint32_t h = llvm::djbHash(s); return ((h >> 24) ^ (h >> 16) ^ (h >> 8) ^ h) & 0xff; } @@ -208,7 +208,7 @@ ConstString::ConstString(const char *cstr) ConstString::ConstString(const char *cstr, size_t cstr_len) : m_string(StringPool().GetConstCStringWithLength(cstr, cstr_len)) {} -ConstString::ConstString(const llvm::StringRef &s) +ConstString::ConstString(llvm::StringRef s) : m_string(StringPool().GetConstCStringWithStringRef(s)) {} bool ConstString::operator<(ConstString rhs) const { @@ -302,8 +302,8 @@ void ConstString::SetCString(const char *cstr) { m_string = StringPool().GetConstCString(cstr); } -void ConstString::SetString(const llvm::StringRef &s) { - m_string = StringPool().GetConstCStringWithLength(s.data(), s.size()); +void ConstString::SetString(llvm::StringRef s) { + m_string = StringPool().GetConstCStringWithStringRef(s); } void ConstString::SetStringWithMangledCounterpart(llvm::StringRef demangled, diff --git a/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp b/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp index a0cd945b7445..e9be0cba81f0 100644 --- a/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp +++ b/contrib/llvm-project/lldb/source/Utility/DataExtractor.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" @@ -70,39 +71,39 @@ static inline uint16_t ReadSwapInt16(const unsigned char *ptr, offset_t offset) { uint16_t value; memcpy(&value, ptr + offset, 2); - return llvm::ByteSwap_16(value); + return llvm::byteswap<uint16_t>(value); } static inline uint32_t ReadSwapInt32(const unsigned char *ptr, offset_t offset) { uint32_t value; memcpy(&value, ptr + offset, 4); - return llvm::ByteSwap_32(value); + return llvm::byteswap<uint32_t>(value); } static inline uint64_t ReadSwapInt64(const unsigned char *ptr, offset_t offset) { uint64_t value; memcpy(&value, ptr + offset, 8); - return llvm::ByteSwap_64(value); + return llvm::byteswap<uint64_t>(value); } static inline uint16_t ReadSwapInt16(const void *ptr) { uint16_t value; memcpy(&value, ptr, 2); - return llvm::ByteSwap_16(value); + return llvm::byteswap<uint16_t>(value); } static inline uint32_t ReadSwapInt32(const void *ptr) { uint32_t value; memcpy(&value, ptr, 4); - return llvm::ByteSwap_32(value); + return llvm::byteswap<uint32_t>(value); } static inline uint64_t ReadSwapInt64(const void *ptr) { uint64_t value; memcpy(&value, ptr, 8); - return llvm::ByteSwap_64(value); + return llvm::byteswap<uint64_t>(value); } static inline uint64_t ReadMaxInt64(const uint8_t *data, size_t byte_size, diff --git a/contrib/llvm-project/lldb/source/Utility/Diagnostics.cpp b/contrib/llvm-project/lldb/source/Utility/Diagnostics.cpp index a59750167cf7..1632ae0f9dfd 100644 --- a/contrib/llvm-project/lldb/source/Utility/Diagnostics.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Diagnostics.cpp @@ -43,9 +43,19 @@ Diagnostics::Diagnostics() : m_log_handler(g_num_log_messages) {} Diagnostics::~Diagnostics() {} -void Diagnostics::AddCallback(Callback callback) { +Diagnostics::CallbackID Diagnostics::AddCallback(Callback callback) { std::lock_guard<std::mutex> guard(m_callbacks_mutex); - m_callbacks.push_back(callback); + CallbackID id = m_callback_id++; + m_callbacks.emplace_back(id, callback); + return id; +} + +void Diagnostics::RemoveCallback(CallbackID id) { + std::lock_guard<std::mutex> guard(m_callbacks_mutex); + m_callbacks.erase( + std::remove_if(m_callbacks.begin(), m_callbacks.end(), + [id](const CallbackEntry &e) { return e.id == id; }), + m_callbacks.end()); } bool Diagnostics::Dump(raw_ostream &stream) { @@ -84,8 +94,8 @@ Error Diagnostics::Create(const FileSpec &dir) { if (Error err = DumpDiangosticsLog(dir)) return err; - for (Callback c : m_callbacks) { - if (Error err = c(dir)) + for (CallbackEntry e : m_callbacks) { + if (Error err = e.callback(dir)) return err; } diff --git a/contrib/llvm-project/lldb/source/Utility/Event.cpp b/contrib/llvm-project/lldb/source/Utility/Event.cpp index 5fca61b16df8..fcc367f43f93 100644 --- a/contrib/llvm-project/lldb/source/Utility/Event.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Event.cpp @@ -15,6 +15,8 @@ #include "lldb/Utility/StreamString.h" #include "lldb/lldb-enumerations.h" +#include "llvm/ADT/StringExtras.h" + #include <algorithm> #include <cctype> @@ -58,13 +60,13 @@ void Event::Dump(Stream *s) const { s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x (%s), data = ", static_cast<const void *>(this), static_cast<void *>(broadcaster), - broadcaster->GetBroadcasterName().GetCString(), m_type, + broadcaster->GetBroadcasterName().c_str(), m_type, event_name.GetData()); else s->Printf("%p Event: broadcaster = %p (%s), type = 0x%8.8x, data = ", static_cast<const void *>(this), static_cast<void *>(broadcaster), - broadcaster->GetBroadcasterName().GetCString(), m_type); + broadcaster->GetBroadcasterName().c_str(), m_type); } else s->Printf("%p Event: broadcaster = NULL, type = 0x%8.8x, data = ", static_cast<const void *>(this), m_type); @@ -114,12 +116,9 @@ EventDataBytes::EventDataBytes(const void *src, size_t src_len) : m_bytes() { EventDataBytes::~EventDataBytes() = default; -ConstString EventDataBytes::GetFlavorString() { - static ConstString g_flavor("EventDataBytes"); - return g_flavor; -} +llvm::StringRef EventDataBytes::GetFlavorString() { return "EventDataBytes"; } -ConstString EventDataBytes::GetFlavor() const { +llvm::StringRef EventDataBytes::GetFlavor() const { return EventDataBytes::GetFlavorString(); } @@ -182,6 +181,10 @@ void EventDataBytes::SwapBytes(std::string &new_bytes) { m_bytes.swap(new_bytes); } +llvm::StringRef EventDataReceipt::GetFlavorString() { + return "Process::ProcessEventData"; +} + #pragma mark - #pragma mark EventStructuredData @@ -200,7 +203,7 @@ EventDataStructuredData::~EventDataStructuredData() = default; // EventDataStructuredData member functions -ConstString EventDataStructuredData::GetFlavor() const { +llvm::StringRef EventDataStructuredData::GetFlavor() const { return EventDataStructuredData::GetFlavorString(); } @@ -280,7 +283,6 @@ EventDataStructuredData::GetPluginFromEvent(const Event *event_ptr) { return StructuredDataPluginSP(); } -ConstString EventDataStructuredData::GetFlavorString() { - static ConstString s_flavor("EventDataStructuredData"); - return s_flavor; +llvm::StringRef EventDataStructuredData::GetFlavorString() { + return "EventDataStructuredData"; } diff --git a/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp b/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp index 7ff57307dec5..eb34ef97cea0 100644 --- a/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp +++ b/contrib/llvm-project/lldb/source/Utility/FileSpec.cpp @@ -12,13 +12,14 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Program.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/TargetParser/Triple.h" #include <algorithm> #include <optional> @@ -399,9 +400,8 @@ void FileSpec::GetPath(llvm::SmallVectorImpl<char> &path, Denormalize(path, m_style); } -ConstString FileSpec::GetFileNameExtension() const { - return ConstString( - llvm::sys::path::extension(m_filename.GetStringRef(), m_style)); +llvm::StringRef FileSpec::GetFileNameExtension() const { + return llvm::sys::path::extension(m_filename.GetStringRef(), m_style); } ConstString FileSpec::GetFileNameStrippingExtension() const { @@ -430,12 +430,6 @@ FileSpec FileSpec::CopyByRemovingLastPathComponent() const { return *this; } -ConstString FileSpec::GetLastPathComponent() const { - llvm::SmallString<64> current_path; - GetPath(current_path, false); - return ConstString(llvm::sys::path::filename(current_path, m_style)); -} - void FileSpec::PrependPathComponent(llvm::StringRef component) { llvm::SmallString<64> new_path(component); llvm::SmallString<64> current_path; @@ -470,6 +464,26 @@ bool FileSpec::RemoveLastPathComponent() { } return false; } + +std::vector<llvm::StringRef> FileSpec::GetComponents() const { + std::vector<llvm::StringRef> components; + + auto dir_begin = llvm::sys::path::begin(m_directory.GetStringRef(), m_style); + auto dir_end = llvm::sys::path::end(m_directory.GetStringRef()); + + for (auto iter = dir_begin; iter != dir_end; ++iter) { + if (*iter == "/" || *iter == ".") + continue; + + components.push_back(*iter); + } + + if (!m_filename.IsEmpty() && m_filename != "/" && m_filename != ".") + components.push_back(m_filename.GetStringRef()); + + return components; +} + /// Returns true if the filespec represents an implementation source /// file (files with a ".c", ".cpp", ".m", ".mm" (many more) /// extension). @@ -478,8 +492,8 @@ bool FileSpec::RemoveLastPathComponent() { /// \b true if the filespec represents an implementation source /// file, \b false otherwise. bool FileSpec::IsSourceImplementationFile() const { - ConstString extension(GetFileNameExtension()); - if (!extension) + llvm::StringRef extension = GetFileNameExtension(); + if (extension.empty()) return false; static RegularExpression g_source_file_regex(llvm::StringRef( @@ -487,7 +501,7 @@ bool FileSpec::IsSourceImplementationFile() const { "cC][pP]|[sS]|[aA][sS][mM]|[fF]|[fF]77|[fF]90|[fF]95|[fF]03|[fF][oO][" "rR]|[fF][tT][nN]|[fF][pP][pP]|[aA][dD][aA]|[aA][dD][bB]|[aA][dD][sS])" "$")); - return g_source_file_regex.Execute(extension.GetStringRef()); + return g_source_file_regex.Execute(extension); } bool FileSpec::IsRelative() const { diff --git a/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp b/contrib/llvm-project/lldb/source/Utility/FileSpecList.cpp index 7fa511176e46..e5e0ac3e5981 100644 --- a/contrib/llvm-project/lldb/source/Core/FileSpecList.cpp +++ b/contrib/llvm-project/lldb/source/Utility/FileSpecList.cpp @@ -6,14 +6,12 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/FileSpecList.h" - +#include "lldb/Utility/FileSpecList.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Stream.h" -#include <utility> - #include <cstdint> +#include <utility> using namespace lldb_private; diff --git a/contrib/llvm-project/lldb/source/Utility/LLDBAssert.cpp b/contrib/llvm-project/lldb/source/Utility/LLDBAssert.cpp index a8d8ef65a945..4ecd6043e8ea 100644 --- a/contrib/llvm-project/lldb/source/Utility/LLDBAssert.cpp +++ b/contrib/llvm-project/lldb/source/Utility/LLDBAssert.cpp @@ -8,7 +8,7 @@ #include "lldb/Utility/LLDBAssert.h" #include "llvm/Config/llvm-config.h" -#include "llvm/Support/Format.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" @@ -16,18 +16,26 @@ #include <os/log.h> #endif -using namespace llvm; -using namespace lldb_private; +#include <atomic> -void lldb_private::lldb_assert(bool expression, const char *expr_text, - const char *func, const char *file, - unsigned int line) { +namespace lldb_private { + +static void DefaultAssertCallback(llvm::StringRef message, + llvm::StringRef backtrace, + llvm::StringRef prompt) { + llvm::errs() << message << '\n'; + llvm::errs() << backtrace; // Backtrace includes a newline. + llvm::errs() << prompt << '\n'; +} + +static std::atomic<LLDBAssertCallback> g_lldb_assert_callback = + &DefaultAssertCallback; + +void lldb_assert(bool expression, const char *expr_text, const char *func, + const char *file, unsigned int line) { if (LLVM_LIKELY(expression)) return; - // If asserts are enabled abort here. - assert(false && "lldb_assert failed"); - #if LLVM_SUPPORT_XCODE_SIGNPOSTS if (__builtin_available(macos 10.12, iOS 10, tvOS 10, watchOS 3, *)) { os_log_fault(OS_LOG_DEFAULT, @@ -36,13 +44,23 @@ void lldb_private::lldb_assert(bool expression, const char *expr_text, } #endif - // In a release configuration it will print a warning and encourage the user - // to file a bug report, similar to LLVM’s crash handler, and then return - // execution. - errs() << format("Assertion failed: (%s), function %s, file %s, line %u\n", - expr_text, func, file, line); - errs() << "backtrace leading to the failure:\n"; - llvm::sys::PrintStackTrace(errs()); - errs() << "please file a bug report against lldb reporting this failure " - "log, and as many details as possible\n"; + // Print a warning and encourage the user to file a bug report, similar to + // LLVM’s crash handler, and then return execution. + std::string buffer; + llvm::raw_string_ostream backtrace(buffer); + llvm::sys::PrintStackTrace(backtrace); + + (*g_lldb_assert_callback.load())( + llvm::formatv("Assertion failed: ({0}), function {1}, file {2}, line {3}", + expr_text, func, file, line) + .str(), + backtrace.str(), + "Please file a bug report against lldb reporting this failure log, and " + "as many details as possible"); +} + +void SetLLDBAssertCallback(LLDBAssertCallback callback) { + g_lldb_assert_callback.exchange(callback); } + +} // namespace lldb_private diff --git a/contrib/llvm-project/lldb/source/Utility/LLDBLog.cpp b/contrib/llvm-project/lldb/source/Utility/LLDBLog.cpp index 71c534a9cfc1..b193bd4eb07d 100644 --- a/contrib/llvm-project/lldb/source/Utility/LLDBLog.cpp +++ b/contrib/llvm-project/lldb/source/Utility/LLDBLog.cpp @@ -63,6 +63,7 @@ static constexpr Log::Category g_categories[] = { {{"on-demand"}, {"log symbol on-demand related activities"}, LLDBLog::OnDemand}, + {{"source"}, {"log source related activities"}, LLDBLog::Source}, }; static Log::Channel g_log_channel(g_categories, diff --git a/contrib/llvm-project/lldb/source/Utility/Listener.cpp b/contrib/llvm-project/lldb/source/Utility/Listener.cpp index 8bb55f93bbf8..48ea5fca899e 100644 --- a/contrib/llvm-project/lldb/source/Utility/Listener.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Listener.cpp @@ -8,7 +8,6 @@ #include "lldb/Utility/Listener.h" #include "lldb/Utility/Broadcaster.h" -#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Event.h" #include "lldb/Utility/LLDBLog.h" @@ -19,23 +18,9 @@ using namespace lldb; using namespace lldb_private; -namespace { -class BroadcasterManagerWPMatcher { -public: - BroadcasterManagerWPMatcher(BroadcasterManagerSP manager_sp) - : m_manager_sp(std::move(manager_sp)) {} - bool operator()(const BroadcasterManagerWP &input_wp) const { - BroadcasterManagerSP input_sp = input_wp.lock(); - return (input_sp && input_sp == m_manager_sp); - } - - BroadcasterManagerSP m_manager_sp; -}; -} // anonymous namespace - Listener::Listener(const char *name) : m_name(name), m_broadcasters(), m_broadcasters_mutex(), m_events(), - m_events_mutex() { + m_events_mutex(), m_is_shadow() { Log *log = GetLog(LLDBLog::Object); if (log != nullptr) LLDB_LOGF(log, "%p Listener::Listener('%s')", static_cast<void *>(this), @@ -182,17 +167,12 @@ void Listener::BroadcasterWillDestruct(Broadcaster *broadcaster) { } void Listener::BroadcasterManagerWillDestruct(BroadcasterManagerSP manager_sp) { - // Just need to remove this broadcast manager from the list of managers: - broadcaster_manager_collection::iterator iter, - end_iter = m_broadcaster_managers.end(); - BroadcasterManagerWP manager_wp; - - BroadcasterManagerWPMatcher matcher(std::move(manager_sp)); - iter = std::find_if<broadcaster_manager_collection::iterator, - BroadcasterManagerWPMatcher>( - m_broadcaster_managers.begin(), end_iter, matcher); - if (iter != end_iter) - m_broadcaster_managers.erase(iter); + const auto manager_matcher = + [&manager_sp](const BroadcasterManagerWP &input_wp) -> bool { + BroadcasterManagerSP input_sp = input_wp.lock(); + return (input_sp && input_sp == manager_sp); + }; + llvm::erase_if(m_broadcaster_managers, manager_matcher); } void Listener::AddEvent(EventSP &event_sp) { @@ -207,61 +187,10 @@ void Listener::AddEvent(EventSP &event_sp) { m_events_condition.notify_all(); } -class EventBroadcasterMatches { -public: - EventBroadcasterMatches(Broadcaster *broadcaster) - : m_broadcaster(broadcaster) {} - - bool operator()(const EventSP &event_sp) const { - return event_sp->BroadcasterIs(m_broadcaster); - } - -private: - Broadcaster *m_broadcaster; -}; - -class EventMatcher { -public: - EventMatcher(Broadcaster *broadcaster, const ConstString *broadcaster_names, - uint32_t num_broadcaster_names, uint32_t event_type_mask) - : m_broadcaster(broadcaster), m_broadcaster_names(broadcaster_names), - m_num_broadcaster_names(num_broadcaster_names), - m_event_type_mask(event_type_mask) {} - - bool operator()(const EventSP &event_sp) const { - if (m_broadcaster && !event_sp->BroadcasterIs(m_broadcaster)) - return false; - - if (m_broadcaster_names) { - bool found_source = false; - ConstString event_broadcaster_name = - event_sp->GetBroadcaster()->GetBroadcasterName(); - for (uint32_t i = 0; i < m_num_broadcaster_names; ++i) { - if (m_broadcaster_names[i] == event_broadcaster_name) { - found_source = true; - break; - } - } - if (!found_source) - return false; - } - - return m_event_type_mask == 0 || m_event_type_mask & event_sp->GetType(); - } - -private: - Broadcaster *m_broadcaster; - const ConstString *m_broadcaster_names; - const uint32_t m_num_broadcaster_names; - const uint32_t m_event_type_mask; -}; - bool Listener::FindNextEventInternal( std::unique_lock<std::mutex> &lock, - Broadcaster *broadcaster, // nullptr for any broadcaster - const ConstString *broadcaster_names, // nullptr for any event - uint32_t num_broadcaster_names, uint32_t event_type_mask, EventSP &event_sp, - bool remove) { + Broadcaster *broadcaster, // nullptr for any broadcaster + uint32_t event_type_mask, EventSP &event_sp, bool remove) { // NOTE: callers of this function must lock m_events_mutex using a // Mutex::Locker // and pass the locker as the first argument. m_events_mutex is no longer @@ -271,16 +200,18 @@ bool Listener::FindNextEventInternal( if (m_events.empty()) return false; + const auto event_matcher = + [broadcaster, event_type_mask](const EventSP &event_sp) -> bool { + if (broadcaster && !event_sp->BroadcasterIs(broadcaster)) + return false; + return event_type_mask == 0 || event_type_mask & event_sp->GetType(); + }; Listener::event_collection::iterator pos = m_events.end(); - if (broadcaster == nullptr && broadcaster_names == nullptr && - event_type_mask == 0) { + if (broadcaster == nullptr && event_type_mask == 0) pos = m_events.begin(); - } else { - pos = std::find_if(m_events.begin(), m_events.end(), - EventMatcher(broadcaster, broadcaster_names, - num_broadcaster_names, event_type_mask)); - } + else + pos = llvm::find_if(m_events, event_matcher); if (pos != m_events.end()) { event_sp = *pos; @@ -288,12 +219,10 @@ bool Listener::FindNextEventInternal( if (log != nullptr) LLDB_LOGF(log, "%p '%s' Listener::FindNextEventInternal(broadcaster=%p, " - "broadcaster_names=%p[%u], event_type_mask=0x%8.8x, " + "event_type_mask=0x%8.8x, " "remove=%i) event %p", static_cast<void *>(this), GetName(), - static_cast<void *>(broadcaster), - static_cast<const void *>(broadcaster_names), - num_broadcaster_names, event_type_mask, remove, + static_cast<void *>(broadcaster), event_type_mask, remove, static_cast<void *>(event_sp.get())); if (remove) { @@ -302,7 +231,8 @@ bool Listener::FindNextEventInternal( // to return it so it should be okay to get the next event off the queue // here - and it might be useful to do that in the "DoOnRemoval". lock.unlock(); - event_sp->DoOnRemoval(); + if (!m_is_shadow) + event_sp->DoOnRemoval(); } return true; } @@ -314,7 +244,7 @@ bool Listener::FindNextEventInternal( Event *Listener::PeekAtNextEvent() { std::unique_lock<std::mutex> guard(m_events_mutex); EventSP event_sp; - if (FindNextEventInternal(guard, nullptr, nullptr, 0, 0, event_sp, false)) + if (FindNextEventInternal(guard, nullptr, 0, event_sp, false)) return event_sp.get(); return nullptr; } @@ -322,7 +252,7 @@ Event *Listener::PeekAtNextEvent() { Event *Listener::PeekAtNextEventForBroadcaster(Broadcaster *broadcaster) { std::unique_lock<std::mutex> guard(m_events_mutex); EventSP event_sp; - if (FindNextEventInternal(guard, broadcaster, nullptr, 0, 0, event_sp, false)) + if (FindNextEventInternal(guard, broadcaster, 0, event_sp, false)) return event_sp.get(); return nullptr; } @@ -332,26 +262,23 @@ Listener::PeekAtNextEventForBroadcasterWithType(Broadcaster *broadcaster, uint32_t event_type_mask) { std::unique_lock<std::mutex> guard(m_events_mutex); EventSP event_sp; - if (FindNextEventInternal(guard, broadcaster, nullptr, 0, event_type_mask, - event_sp, false)) + if (FindNextEventInternal(guard, broadcaster, event_type_mask, event_sp, + false)) return event_sp.get(); return nullptr; } bool Listener::GetEventInternal( const Timeout<std::micro> &timeout, - Broadcaster *broadcaster, // nullptr for any broadcaster - const ConstString *broadcaster_names, // nullptr for any event - uint32_t num_broadcaster_names, uint32_t event_type_mask, - EventSP &event_sp) { + Broadcaster *broadcaster, // nullptr for any broadcaster + uint32_t event_type_mask, EventSP &event_sp) { 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); while (true) { - if (FindNextEventInternal(lock, broadcaster, broadcaster_names, - num_broadcaster_names, event_type_mask, event_sp, + if (FindNextEventInternal(lock, broadcaster, event_type_mask, event_sp, true)) { return true; } else { @@ -381,18 +308,17 @@ bool Listener::GetEventInternal( bool Listener::GetEventForBroadcasterWithType( Broadcaster *broadcaster, uint32_t event_type_mask, EventSP &event_sp, const Timeout<std::micro> &timeout) { - return GetEventInternal(timeout, broadcaster, nullptr, 0, event_type_mask, - event_sp); + return GetEventInternal(timeout, broadcaster, event_type_mask, event_sp); } bool Listener::GetEventForBroadcaster(Broadcaster *broadcaster, EventSP &event_sp, const Timeout<std::micro> &timeout) { - return GetEventInternal(timeout, broadcaster, nullptr, 0, 0, event_sp); + return GetEventInternal(timeout, broadcaster, 0, event_sp); } bool Listener::GetEvent(EventSP &event_sp, const Timeout<std::micro> &timeout) { - return GetEventInternal(timeout, nullptr, nullptr, 0, 0, event_sp); + return GetEventInternal(timeout, nullptr, 0, event_sp); } size_t Listener::HandleBroadcastEvent(EventSP &event_sp) { @@ -424,6 +350,11 @@ Listener::StartListeningForEventSpec(const BroadcasterManagerSP &manager_sp, if (!manager_sp) return 0; + const auto manager_matcher = + [&manager_sp](const BroadcasterManagerWP &input_wp) -> bool { + BroadcasterManagerSP input_sp = input_wp.lock(); + return (input_sp && input_sp == manager_sp); + }; // The BroadcasterManager mutex must be locked before m_broadcasters_mutex to // avoid violating the lock hierarchy (manager before broadcasters). std::lock_guard<std::recursive_mutex> manager_guard( @@ -433,14 +364,9 @@ Listener::StartListeningForEventSpec(const BroadcasterManagerSP &manager_sp, uint32_t bits_acquired = manager_sp->RegisterListenerForEvents( this->shared_from_this(), event_spec); if (bits_acquired) { - broadcaster_manager_collection::iterator iter, - end_iter = m_broadcaster_managers.end(); BroadcasterManagerWP manager_wp(manager_sp); - BroadcasterManagerWPMatcher matcher(manager_sp); - iter = std::find_if<broadcaster_manager_collection::iterator, - BroadcasterManagerWPMatcher>( - m_broadcaster_managers.begin(), end_iter, matcher); - if (iter == end_iter) + auto iter = llvm::find_if(m_broadcaster_managers, manager_matcher); + if (iter == m_broadcaster_managers.end()) m_broadcaster_managers.push_back(manager_wp); } diff --git a/contrib/llvm-project/lldb/source/Utility/Log.cpp b/contrib/llvm-project/lldb/source/Utility/Log.cpp index 045e0f2cb68a..75912683e233 100644 --- a/contrib/llvm-project/lldb/source/Utility/Log.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Log.cpp @@ -131,8 +131,15 @@ Log::MaskType Log::GetMask() const { return m_mask.load(std::memory_order_relaxed); } -void Log::PutCString(const char *cstr) { Printf("%s", cstr); } -void Log::PutString(llvm::StringRef str) { PutCString(str.str().c_str()); } +void Log::PutCString(const char *cstr) { PutString(cstr); } + +void Log::PutString(llvm::StringRef str) { + std::string FinalMessage; + llvm::raw_string_ostream Stream(FinalMessage); + WriteHeader(Stream, "", ""); + Stream << str << "\n"; + WriteMessage(FinalMessage); +} // Simple variable argument logging with flags. void Log::Printf(const char *format, ...) { @@ -142,20 +149,25 @@ void Log::Printf(const char *format, ...) { va_end(args); } -// All logging eventually boils down to this function call. If we have a -// callback registered, then we call the logging callback. If we have a valid -// file handle, we also log to the file. void Log::VAPrintf(const char *format, va_list args) { - llvm::SmallString<64> FinalMessage; - llvm::raw_svector_ostream Stream(FinalMessage); - WriteHeader(Stream, "", ""); - llvm::SmallString<64> Content; lldb_private::VASprintf(Content, format, args); + PutString(Content); +} - Stream << Content << "\n"; +void Log::Formatf(llvm::StringRef file, llvm::StringRef function, + const char *format, ...) { + va_list args; + va_start(args, format); + VAFormatf(file, function, format, args); + va_end(args); +} - WriteMessage(std::string(FinalMessage.str())); +void Log::VAFormatf(llvm::StringRef file, llvm::StringRef function, + const char *format, va_list args) { + llvm::SmallString<64> Content; + lldb_private::VASprintf(Content, format, args); + Format(file, function, llvm::formatv("{0}", Content)); } // Printing of errors that are not fatal. @@ -344,7 +356,9 @@ void Log::WriteHeader(llvm::raw_ostream &OS, llvm::StringRef file, } } -void Log::WriteMessage(const std::string &message) { +// If we have a callback registered, then we call the logging callback. If we +// have a valid file handle, we also log to the file. +void Log::WriteMessage(llvm::StringRef message) { // Make a copy of our stream shared pointer in case someone disables our log // while we are logging and releases the stream auto handler_sp = GetHandler(); diff --git a/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp b/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp index 8e27a17d8337..6b2a7114dfb4 100644 --- a/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp +++ b/contrib/llvm-project/lldb/source/Utility/ProcessInfo.cpp @@ -9,6 +9,7 @@ #include "lldb/Utility/ProcessInfo.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/ScriptedMetadata.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UserIDResolver.h" @@ -21,12 +22,14 @@ using namespace lldb; using namespace lldb_private; ProcessInfo::ProcessInfo() - : m_executable(), m_arguments(), m_environment(), m_arch() {} + : m_executable(), m_arguments(), m_environment(), m_arch(), m_listener_sp(), + m_hijack_listener_sp(), m_shadow_listener_sp() {} ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) : m_executable(name), m_arguments(), m_environment(), m_arch(arch), - m_pid(pid) {} + m_pid(pid), m_listener_sp(), m_hijack_listener_sp(), + m_shadow_listener_sp() {} void ProcessInfo::Clear() { m_executable.Clear(); @@ -36,6 +39,7 @@ void ProcessInfo::Clear() { m_gid = UINT32_MAX; m_arch.Clear(); m_pid = LLDB_INVALID_PROCESS_ID; + m_scripted_metadata_sp.reset(); } const char *ProcessInfo::GetName() const { @@ -109,6 +113,10 @@ void ProcessInfo::SetArguments(const Args &args, bool first_arg_is_executable) { } } +bool ProcessInfo::IsScriptedProcess() const { + return m_scripted_metadata_sp && *m_scripted_metadata_sp; +} + void ProcessInstanceInfo::Dump(Stream &s, UserIDResolver &resolver) const { if (m_pid != LLDB_INVALID_PROCESS_ID) s.Printf(" pid = %" PRIu64 "\n", m_pid); diff --git a/contrib/llvm-project/lldb/source/Utility/RISCV_DWARF_Registers.h b/contrib/llvm-project/lldb/source/Utility/RISCV_DWARF_Registers.h index b7fc9d913e33..8aed3d13f935 100644 --- a/contrib/llvm-project/lldb/source/Utility/RISCV_DWARF_Registers.h +++ b/contrib/llvm-project/lldb/source/Utility/RISCV_DWARF_Registers.h @@ -83,40 +83,50 @@ enum { // alternate frame return column dwarf_alt_fr_col = 64, - dwarf_v0 = 96, - dwarf_v1, - dwarf_v2, - dwarf_v3, - dwarf_v4, - dwarf_v5, - dwarf_v6, - dwarf_v7, - dwarf_v8, - dwarf_v9, - dwarf_v10, - dwarf_v11, - dwarf_v12, - dwarf_v13, - dwarf_v14, - dwarf_v15, - dwarf_v16, - dwarf_v17, - dwarf_v18, - dwarf_v19, - dwarf_v20, - dwarf_v21, - dwarf_v22, - dwarf_v23, - dwarf_v24, - dwarf_v25, - dwarf_v26, - dwarf_v27, - dwarf_v28, - dwarf_v29, - dwarf_v30, - dwarf_v31 = 127, + dwarf_vpr_v0 = 96, + dwarf_vpr_v1, + dwarf_vpr_v2, + dwarf_vpr_v3, + dwarf_vpr_v4, + dwarf_vpr_v5, + dwarf_vpr_v6, + dwarf_vpr_v7, + dwarf_vpr_v8, + dwarf_vpr_v9, + dwarf_vpr_v10, + dwarf_vpr_v11, + dwarf_vpr_v12, + dwarf_vpr_v13, + dwarf_vpr_v14, + dwarf_vpr_v15, + dwarf_vpr_v16, + dwarf_vpr_v17, + dwarf_vpr_v18, + dwarf_vpr_v19, + dwarf_vpr_v20, + dwarf_vpr_v21, + dwarf_vpr_v22, + dwarf_vpr_v23, + dwarf_vpr_v24, + dwarf_vpr_v25, + dwarf_vpr_v26, + dwarf_vpr_v27, + dwarf_vpr_v28, + dwarf_vpr_v29, + dwarf_vpr_v30, + dwarf_vpr_v31 = 127, dwarf_first_csr = 4096, dwarf_fpr_fcsr = dwarf_first_csr + 0x003, + // The vector extension adds seven unprivileged CSRs + // (vstart, vxsat, vxrm, vcsr, vtype, vl, vlenb) + // to a base scalar RISC-V ISA. + dwarf_vpr_vstart = dwarf_first_csr + 0x008, + dwarf_vpr_vxsat = dwarf_first_csr + 0x009, + dwarf_vpr_vxrm = dwarf_first_csr + 0x00A, + dwarf_vpr_vcsr = dwarf_first_csr + 0x00F, + dwarf_vpr_vl = dwarf_first_csr + 0xC20, + dwarf_vpr_vtype = dwarf_first_csr + 0xC21, + dwarf_vpr_vlenb = dwarf_first_csr + 0xC22, dwarf_last_csr = 8191, // register ABI name diff --git a/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp b/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp index b9ce9fd18ac4..fa92ba8a8f92 100644 --- a/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp +++ b/contrib/llvm-project/lldb/source/Utility/RegisterValue.cpp @@ -48,11 +48,6 @@ uint32_t RegisterValue::GetAsMemoryData(const RegisterInfo ®_info, void *dst, return 0; } - if (dst_len > kMaxRegisterByteSize) { - error.SetErrorString("destination is too big"); - return 0; - } - const uint32_t src_len = reg_info.byte_size; // Extract the register data into a data extractor @@ -96,12 +91,6 @@ uint32_t RegisterValue::SetFromMemoryData(const RegisterInfo ®_info, // |AABB| Address contents // |AABB0000| Register contents [on little-endian hardware] // |0000AABB| Register contents [on big-endian hardware] - if (src_len > kMaxRegisterByteSize) { - error.SetErrorStringWithFormat( - "register buffer is too small to receive %u bytes of data.", src_len); - return 0; - } - const uint32_t dst_len = reg_info.byte_size; if (src_len > dst_len) { @@ -128,9 +117,10 @@ bool RegisterValue::GetScalarValue(Scalar &scalar) const { case eTypeInvalid: break; case eTypeBytes: { - DataExtractor data(buffer.bytes, buffer.length, buffer.byte_order, 1); - if (scalar.SetValueFromData(data, lldb::eEncodingUint, - buffer.length).Success()) + DataExtractor data(buffer.bytes.data(), buffer.bytes.size(), + buffer.byte_order, 1); + if (scalar.SetValueFromData(data, lldb::eEncodingUint, buffer.bytes.size()) + .Success()) return true; } break; case eTypeUInt8: @@ -190,9 +180,6 @@ Status RegisterValue::SetValueFromData(const RegisterInfo ®_info, if (src_len > reg_info.byte_size) src_len = reg_info.byte_size; - // Zero out the value in case we get partial data... - memset(buffer.bytes, 0, sizeof(buffer.bytes)); - type128 int128; m_type = eTypeInvalid; @@ -232,16 +219,14 @@ Status RegisterValue::SetValueFromData(const RegisterInfo ®_info, break; case eEncodingVector: { m_type = eTypeBytes; - buffer.length = reg_info.byte_size; + assert(reg_info.byte_size <= kMaxRegisterByteSize); + buffer.bytes.resize(reg_info.byte_size); buffer.byte_order = src.GetByteOrder(); - assert(buffer.length <= kMaxRegisterByteSize); - if (buffer.length > kMaxRegisterByteSize) - buffer.length = kMaxRegisterByteSize; if (src.CopyByteOrderedData( - src_offset, // offset within "src" to start extracting data - src_len, // src length - buffer.bytes, // dst buffer - buffer.length, // dst length + src_offset, // offset within "src" to start extracting data + src_len, // src length + buffer.bytes.data(), // dst buffer + buffer.bytes.size(), // dst length buffer.byte_order) == 0) // dst byte order { error.SetErrorStringWithFormat( @@ -357,9 +342,8 @@ Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info, break; } if (value_str.getAsInteger(0, uval64)) { - error.SetErrorStringWithFormat( - "'%s' is not a valid unsigned integer string value", - value_str.str().c_str()); + error.SetErrorStringWithFormatv( + "'{0}' is not a valid unsigned integer string value", value_str); break; } @@ -386,9 +370,8 @@ Status RegisterValue::SetValueFromString(const RegisterInfo *reg_info, } if (value_str.getAsInteger(0, ival64)) { - error.SetErrorStringWithFormat( - "'%s' is not a valid signed integer string value", - value_str.str().c_str()); + error.SetErrorStringWithFormatv( + "'{0}' is not a valid signed integer string value", value_str); break; } @@ -488,9 +471,7 @@ bool RegisterValue::CopyValue(const RegisterValue &rhs) { m_scalar = rhs.m_scalar; break; case eTypeBytes: - assert(rhs.buffer.length <= kMaxRegisterByteSize); - ::memcpy(buffer.bytes, rhs.buffer.bytes, kMaxRegisterByteSize); - buffer.length = rhs.buffer.length; + buffer.bytes = rhs.buffer.bytes; buffer.byte_order = rhs.buffer.byte_order; break; } @@ -509,12 +490,12 @@ uint16_t RegisterValue::GetAsUInt16(uint16_t fail_value, case eTypeUInt16: return m_scalar.UShort(fail_value); case eTypeBytes: { - switch (buffer.length) { + switch (buffer.bytes.size()) { default: break; case 1: case 2: - return *reinterpret_cast<const uint16_t *>(buffer.bytes); + return *reinterpret_cast<const uint16_t *>(buffer.bytes.data()); } } break; } @@ -538,13 +519,13 @@ uint32_t RegisterValue::GetAsUInt32(uint32_t fail_value, case eTypeLongDouble: return m_scalar.UInt(fail_value); case eTypeBytes: { - switch (buffer.length) { + switch (buffer.bytes.size()) { default: break; case 1: case 2: case 4: - return *reinterpret_cast<const uint32_t *>(buffer.bytes); + return *reinterpret_cast<const uint32_t *>(buffer.bytes.data()); } } break; } @@ -569,17 +550,17 @@ uint64_t RegisterValue::GetAsUInt64(uint64_t fail_value, case eTypeLongDouble: return m_scalar.ULongLong(fail_value); case eTypeBytes: { - switch (buffer.length) { + switch (buffer.bytes.size()) { default: break; case 1: - return *(const uint8_t *)buffer.bytes; + return *(const uint8_t *)buffer.bytes.data(); case 2: - return *reinterpret_cast<const uint16_t *>(buffer.bytes); + return *reinterpret_cast<const uint16_t *>(buffer.bytes.data()); case 4: - return *reinterpret_cast<const uint32_t *>(buffer.bytes); + return *reinterpret_cast<const uint32_t *>(buffer.bytes.data()); case 8: - return *reinterpret_cast<const uint64_t *>(buffer.bytes); + return *reinterpret_cast<const uint64_t *>(buffer.bytes.data()); } } break; } @@ -605,7 +586,7 @@ llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value, case eTypeLongDouble: return m_scalar.UInt128(fail_value); case eTypeBytes: { - switch (buffer.length) { + switch (buffer.bytes.size()) { default: break; case 1: @@ -613,8 +594,9 @@ llvm::APInt RegisterValue::GetAsUInt128(const llvm::APInt &fail_value, case 4: case 8: case 16: - return llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, - (reinterpret_cast<const type128 *>(buffer.bytes))->x); + return llvm::APInt( + BITWIDTH_INT128, NUM_OF_WORDS_INT128, + (reinterpret_cast<const type128 *>(buffer.bytes.data()))->x); } } break; } @@ -696,9 +678,9 @@ const void *RegisterValue::GetBytes() const { case eTypeDouble: case eTypeLongDouble: m_scalar.GetBytes(buffer.bytes); - return buffer.bytes; + return buffer.bytes.data(); case eTypeBytes: - return buffer.bytes; + return buffer.bytes.data(); } return nullptr; } @@ -719,7 +701,7 @@ uint32_t RegisterValue::GetByteSize() const { case eTypeLongDouble: return m_scalar.GetByteSize(); case eTypeBytes: - return buffer.length; + return buffer.bytes.size(); } return 0; } @@ -744,19 +726,14 @@ bool RegisterValue::SetUInt(uint64_t uint, uint32_t byte_size) { void RegisterValue::SetBytes(const void *bytes, size_t length, lldb::ByteOrder byte_order) { - // If this assertion fires off we need to increase the size of buffer.bytes, - // or make it something that is allocated on the heap. Since the data buffer - // is in a union, we can't make it a collection class like SmallVector... if (bytes && length > 0) { - assert(length <= sizeof(buffer.bytes) && - "Storing too many bytes in a RegisterValue."); m_type = eTypeBytes; - buffer.length = length; - memcpy(buffer.bytes, bytes, length); + buffer.bytes.resize(length); + memcpy(buffer.bytes.data(), bytes, length); buffer.byte_order = byte_order; } else { m_type = eTypeInvalid; - buffer.length = 0; + buffer.bytes.resize(0); } } @@ -775,15 +752,7 @@ bool RegisterValue::operator==(const RegisterValue &rhs) const { case eTypeLongDouble: return m_scalar == rhs.m_scalar; case eTypeBytes: - if (buffer.length != rhs.buffer.length) - return false; - else { - uint16_t length = buffer.length; - if (length > kMaxRegisterByteSize) - length = kMaxRegisterByteSize; - return memcmp(buffer.bytes, rhs.buffer.bytes, length) == 0; - } - break; + return buffer.bytes == rhs.buffer.bytes; } } return false; @@ -818,12 +787,12 @@ bool RegisterValue::ClearBit(uint32_t bit) { buffer.byte_order == eByteOrderLittle) { uint32_t byte_idx; if (buffer.byte_order == eByteOrderBig) - byte_idx = buffer.length - (bit / 8) - 1; + byte_idx = buffer.bytes.size() - (bit / 8) - 1; else byte_idx = bit / 8; const uint32_t byte_bit = bit % 8; - if (byte_idx < buffer.length) { + if (byte_idx < buffer.bytes.size()) { buffer.bytes[byte_idx] &= ~(1u << byte_bit); return true; } @@ -858,12 +827,12 @@ bool RegisterValue::SetBit(uint32_t bit) { buffer.byte_order == eByteOrderLittle) { uint32_t byte_idx; if (buffer.byte_order == eByteOrderBig) - byte_idx = buffer.length - (bit / 8) - 1; + byte_idx = buffer.bytes.size() - (bit / 8) - 1; else byte_idx = bit / 8; const uint32_t byte_bit = bit % 8; - if (byte_idx < buffer.length) { + if (byte_idx < buffer.bytes.size()) { buffer.bytes[byte_idx] |= (1u << byte_bit); return true; } diff --git a/contrib/llvm-project/lldb/source/Utility/Scalar.cpp b/contrib/llvm-project/lldb/source/Utility/Scalar.cpp index 19e00e111be5..791c0fb74352 100644 --- a/contrib/llvm-project/lldb/source/Utility/Scalar.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Scalar.cpp @@ -16,6 +16,7 @@ #include "lldb/lldb-types.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include <cinttypes> #include <cstdio> @@ -145,7 +146,7 @@ bool Scalar::IsZero() const { case e_void: break; case e_int: - return m_integer.isNullValue(); + return m_integer.isZero(); case e_float: return m_float.isZero(); } diff --git a/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp b/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp index acc09289e6b9..c0ed1e5a5c73 100644 --- a/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp +++ b/contrib/llvm-project/lldb/source/Utility/StructuredData.cpp @@ -9,6 +9,7 @@ #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/MemoryBuffer.h" #include <cerrno> #include <cinttypes> @@ -21,8 +22,7 @@ static StructuredData::ObjectSP ParseJSONValue(json::Value &value); static StructuredData::ObjectSP ParseJSONObject(json::Object *object); static StructuredData::ObjectSP ParseJSONArray(json::Array *array); -StructuredData::ObjectSP -StructuredData::ParseJSON(const std::string &json_text) { +StructuredData::ObjectSP StructuredData::ParseJSON(llvm::StringRef json_text) { llvm::Expected<json::Value> value = json::parse(json_text); if (!value) { llvm::consumeError(value.takeError()); @@ -68,8 +68,11 @@ static StructuredData::ObjectSP ParseJSONValue(json::Value &value) { if (auto b = value.getAsBoolean()) return std::make_shared<StructuredData::Boolean>(*b); + if (auto u = value.getAsUINT64()) + return std::make_shared<StructuredData::UnsignedInteger>(*u); + if (auto i = value.getAsInteger()) - return std::make_shared<StructuredData::Integer>(*i); + return std::make_shared<StructuredData::SignedInteger>(*i); if (auto d = value.getAsNumber()) return std::make_shared<StructuredData::Float>(*d); @@ -102,36 +105,34 @@ static StructuredData::ObjectSP ParseJSONArray(json::Array *array) { StructuredData::ObjectSP StructuredData::Object::GetObjectForDotSeparatedPath(llvm::StringRef path) { - if (this->GetType() == lldb::eStructuredDataTypeDictionary) { + if (GetType() == lldb::eStructuredDataTypeDictionary) { std::pair<llvm::StringRef, llvm::StringRef> match = path.split('.'); - std::string key = match.first.str(); - ObjectSP value = this->GetAsDictionary()->GetValueForKey(key); - if (value.get()) { - // Do we have additional words to descend? If not, return the value - // we're at right now. - if (match.second.empty()) { - return value; - } else { - return value->GetObjectForDotSeparatedPath(match.second); - } - } - return ObjectSP(); + llvm::StringRef key = match.first; + ObjectSP value = GetAsDictionary()->GetValueForKey(key); + if (!value) + return {}; + + // Do we have additional words to descend? If not, return the value + // we're at right now. + if (match.second.empty()) + return value; + + return value->GetObjectForDotSeparatedPath(match.second); } - if (this->GetType() == lldb::eStructuredDataTypeArray) { + if (GetType() == lldb::eStructuredDataTypeArray) { std::pair<llvm::StringRef, llvm::StringRef> match = path.split('['); - if (match.second.empty()) { - return this->shared_from_this(); - } - errno = 0; - uint64_t val = strtoul(match.second.str().c_str(), nullptr, 10); - if (errno == 0) { - return this->GetAsArray()->GetItemAtIndex(val); - } - return ObjectSP(); + if (match.second.empty()) + return shared_from_this(); + + uint64_t val = 0; + if (!llvm::to_integer(match.second, val, /* Base = */ 10)) + return {}; + + return GetAsArray()->GetItemAtIndex(val); } - return this->shared_from_this(); + return shared_from_this(); } void StructuredData::Object::DumpToStdout(bool pretty_print) const { @@ -147,10 +148,6 @@ void StructuredData::Array::Serialize(json::OStream &s) const { s.arrayEnd(); } -void StructuredData::Integer::Serialize(json::OStream &s) const { - s.value(static_cast<int64_t>(m_value)); -} - void StructuredData::Float::Serialize(json::OStream &s) const { s.value(m_value); } @@ -181,10 +178,6 @@ void StructuredData::Generic::Serialize(json::OStream &s) const { s.value(llvm::formatv("{0:X}", m_object)); } -void StructuredData::Integer::GetDescription(lldb_private::Stream &s) const { - s.Printf("%" PRId64, static_cast<int64_t>(m_value)); -} - void StructuredData::Float::GetDescription(lldb_private::Stream &s) const { s.Printf("%f", m_value); } diff --git a/contrib/llvm-project/lldb/source/Utility/Timer.cpp b/contrib/llvm-project/lldb/source/Utility/Timer.cpp index 477541d7bb3d..a059f877e023 100644 --- a/contrib/llvm-project/lldb/source/Utility/Timer.cpp +++ b/contrib/llvm-project/lldb/source/Utility/Timer.cpp @@ -135,7 +135,7 @@ void Timer::ResetCategoryTimes() { } } -void Timer::DumpCategoryTimes(Stream *s) { +void Timer::DumpCategoryTimes(Stream &s) { std::vector<Stats> sorted; for (Category *i = g_categories; i; i = i->m_next) { uint64_t nanos = i->m_nanos.load(std::memory_order_acquire); @@ -153,9 +153,9 @@ void Timer::DumpCategoryTimes(Stream *s) { llvm::sort(sorted, CategoryMapIteratorSortCriterion); for (const auto &stats : sorted) - s->Printf("%.9f sec (total: %.3fs; child: %.3fs; count: %" PRIu64 - ") for %s\n", - stats.nanos / 1000000000., stats.nanos_total / 1000000000., - (stats.nanos_total - stats.nanos) / 1000000000., stats.count, - stats.name); + s.Printf("%.9f sec (total: %.3fs; child: %.3fs; count: %" PRIu64 + ") for %s\n", + stats.nanos / 1000000000., stats.nanos_total / 1000000000., + (stats.nanos_total - stats.nanos) / 1000000000., stats.count, + stats.name); } diff --git a/contrib/llvm-project/lldb/source/Utility/UUID.cpp b/contrib/llvm-project/lldb/source/Utility/UUID.cpp index 62a75ecf47c2..57e3a39d1f8e 100644 --- a/contrib/llvm-project/lldb/source/Utility/UUID.cpp +++ b/contrib/llvm-project/lldb/source/Utility/UUID.cpp @@ -61,7 +61,7 @@ std::string UUID::GetAsString(llvm::StringRef separator) const { return result; } -void UUID::Dump(Stream *s) const { s->PutCString(GetAsString()); } +void UUID::Dump(Stream &s) const { s.PutCString(GetAsString()); } static inline int xdigit_to_int(char ch) { ch = tolower(ch); diff --git a/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp b/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp index 371b86437fa2..84f3ccbd01e2 100644 --- a/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp +++ b/contrib/llvm-project/lldb/source/Utility/XcodeSDK.cpp @@ -11,7 +11,7 @@ #include "lldb/lldb-types.h" -#include "llvm/ADT/Triple.h" +#include "llvm/TargetParser/Triple.h" #include <string> @@ -242,7 +242,7 @@ bool XcodeSDK::SupportsSwift() const { bool XcodeSDK::SDKSupportsModules(XcodeSDK::Type desired_type, const FileSpec &sdk_path) { - ConstString last_path_component = sdk_path.GetLastPathComponent(); + ConstString last_path_component = sdk_path.GetFilename(); if (!last_path_component) return false; diff --git a/contrib/llvm-project/lldb/source/Utility/ZipFile.cpp b/contrib/llvm-project/lldb/source/Utility/ZipFile.cpp new file mode 100644 index 000000000000..b8ed956cbfcb --- /dev/null +++ b/contrib/llvm-project/lldb/source/Utility/ZipFile.cpp @@ -0,0 +1,180 @@ +//===-- ZipFile.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/ZipFile.h" +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/FileSpec.h" +#include "llvm/Support/Endian.h" + +using namespace lldb_private; +using namespace llvm::support; + +namespace { + +// Zip headers. +// https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT + +// The end of central directory record. +struct EocdRecord { + static constexpr char kSignature[] = {0x50, 0x4b, 0x05, 0x06}; + char signature[sizeof(kSignature)]; + unaligned_uint16_t disks; + unaligned_uint16_t cd_start_disk; + unaligned_uint16_t cds_on_this_disk; + unaligned_uint16_t cd_records; + unaligned_uint32_t cd_size; + unaligned_uint32_t cd_offset; + unaligned_uint16_t comment_length; +}; + +// Logical find limit for the end of central directory record. +const size_t kEocdRecordFindLimit = + sizeof(EocdRecord) + + std::numeric_limits<decltype(EocdRecord::comment_length)>::max(); + +// Central directory record. +struct CdRecord { + static constexpr char kSignature[] = {0x50, 0x4b, 0x01, 0x02}; + char signature[sizeof(kSignature)]; + unaligned_uint16_t version_made_by; + unaligned_uint16_t version_needed_to_extract; + unaligned_uint16_t general_purpose_bit_flag; + unaligned_uint16_t compression_method; + unaligned_uint16_t last_modification_time; + unaligned_uint16_t last_modification_date; + unaligned_uint32_t crc32; + unaligned_uint32_t compressed_size; + unaligned_uint32_t uncompressed_size; + unaligned_uint16_t file_name_length; + unaligned_uint16_t extra_field_length; + unaligned_uint16_t comment_length; + unaligned_uint16_t file_start_disk; + unaligned_uint16_t internal_file_attributes; + unaligned_uint32_t external_file_attributes; + unaligned_uint32_t local_file_header_offset; +}; +// Immediately after CdRecord, +// - file name (file_name_length) +// - extra field (extra_field_length) +// - comment (comment_length) + +// Local file header. +struct LocalFileHeader { + static constexpr char kSignature[] = {0x50, 0x4b, 0x03, 0x04}; + char signature[sizeof(kSignature)]; + unaligned_uint16_t version_needed_to_extract; + unaligned_uint16_t general_purpose_bit_flag; + unaligned_uint16_t compression_method; + unaligned_uint16_t last_modification_time; + unaligned_uint16_t last_modification_date; + unaligned_uint32_t crc32; + unaligned_uint32_t compressed_size; + unaligned_uint32_t uncompressed_size; + unaligned_uint16_t file_name_length; + unaligned_uint16_t extra_field_length; +}; +// Immediately after LocalFileHeader, +// - file name (file_name_length) +// - extra field (extra_field_length) +// - file data (should be compressed_size == uncompressed_size, page aligned) + +const EocdRecord *FindEocdRecord(lldb::DataBufferSP zip_data) { + // Find backward the end of central directory record from the end of the zip + // file to the find limit. + const uint8_t *zip_data_end = zip_data->GetBytes() + zip_data->GetByteSize(); + const uint8_t *find_limit = zip_data_end - kEocdRecordFindLimit; + const uint8_t *p = zip_data_end - sizeof(EocdRecord); + for (; p >= zip_data->GetBytes() && p >= find_limit; p--) { + auto eocd = reinterpret_cast<const EocdRecord *>(p); + if (::memcmp(eocd->signature, EocdRecord::kSignature, + sizeof(EocdRecord::kSignature)) == 0) { + // Found the end of central directory. Sanity check the values. + if (eocd->cd_records * sizeof(CdRecord) > eocd->cd_size || + zip_data->GetBytes() + eocd->cd_offset + eocd->cd_size > p) + return nullptr; + + // This is a valid end of central directory record. + return eocd; + } + } + return nullptr; +} + +bool GetFile(lldb::DataBufferSP zip_data, uint32_t local_file_header_offset, + lldb::offset_t &file_offset, lldb::offset_t &file_size) { + auto local_file_header = reinterpret_cast<const LocalFileHeader *>( + zip_data->GetBytes() + local_file_header_offset); + // The signature should match. + if (::memcmp(local_file_header->signature, LocalFileHeader::kSignature, + sizeof(LocalFileHeader::kSignature)) != 0) + return false; + + auto file_data = reinterpret_cast<const uint8_t *>(local_file_header + 1) + + local_file_header->file_name_length + + local_file_header->extra_field_length; + // File should be uncompressed. + if (local_file_header->compressed_size != + local_file_header->uncompressed_size) + return false; + + // This file is valid. Return the file offset and size. + file_offset = file_data - zip_data->GetBytes(); + file_size = local_file_header->uncompressed_size; + return true; +} + +bool FindFile(lldb::DataBufferSP zip_data, const EocdRecord *eocd, + const llvm::StringRef file_path, lldb::offset_t &file_offset, + lldb::offset_t &file_size) { + // Find the file from the central directory records. + auto cd = reinterpret_cast<const CdRecord *>(zip_data->GetBytes() + + eocd->cd_offset); + size_t cd_records = eocd->cd_records; + for (size_t i = 0; i < cd_records; i++) { + // The signature should match. + if (::memcmp(cd->signature, CdRecord::kSignature, + sizeof(CdRecord::kSignature)) != 0) + return false; + + // Sanity check the file name values. + auto file_name = reinterpret_cast<const char *>(cd + 1); + size_t file_name_length = cd->file_name_length; + if (file_name + file_name_length >= reinterpret_cast<const char *>(eocd) || + file_name_length == 0) + return false; + + // Compare the file name. + if (file_path == llvm::StringRef(file_name, file_name_length)) { + // Found the file. + return GetFile(zip_data, cd->local_file_header_offset, file_offset, + file_size); + } else { + // Skip to the next central directory record. + cd = reinterpret_cast<const CdRecord *>( + reinterpret_cast<const char *>(cd) + sizeof(CdRecord) + + cd->file_name_length + cd->extra_field_length + cd->comment_length); + // Sanity check the pointer. + if (reinterpret_cast<const char *>(cd) >= + reinterpret_cast<const char *>(eocd)) + return false; + } + } + + return false; +} + +} // end anonymous namespace + +bool ZipFile::Find(lldb::DataBufferSP zip_data, const llvm::StringRef file_path, + lldb::offset_t &file_offset, lldb::offset_t &file_size) { + const EocdRecord *eocd = FindEocdRecord(zip_data); + if (!eocd) + return false; + + return FindFile(zip_data, eocd, file_path, file_offset, file_size); +} |