diff options
Diffstat (limited to 'lldb/source')
20 files changed, 207 insertions, 92 deletions
diff --git a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp index 21d94d6..8ae20bd 100644 --- a/lldb/source/Commands/CommandOptionsProcessLaunch.cpp +++ b/lldb/source/Commands/CommandOptionsProcessLaunch.cpp @@ -127,6 +127,10 @@ Status CommandOptionsProcessLaunch::SetOptionValue( break; } + case 'M': + launch_info.GetFlags().Set(eLaunchFlagMemoryTagging); + break; + case 'c': if (!option_arg.empty()) launch_info.SetShell(FileSpec(option_arg)); diff --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td index 595b3d0..a9f054e 100644 --- a/lldb/source/Commands/Options.td +++ b/lldb/source/Commands/Options.td @@ -1173,6 +1173,11 @@ let Command = "process launch" in { Arg<"Boolean">, Desc<"Set whether to shell expand arguments to the process when " "launching.">; + def process_launch_memory_tagging + : Option<"memory-tagging", "M">, + Desc<"Set whether to explicitly enable memory tagging when launching " + "the process. Requires hardware support. " + "(Only supported on Darwin.)">; } let Command = "process attach" in { diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index fda34a8..1be911c 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -162,10 +162,12 @@ let Definition = "debugger" in { Global, DefaultTrue, Desc<"Whether to use Ansi color codes or not.">; - def ShowProgress: Property<"show-progress", "Boolean">, - Global, - DefaultTrue, - Desc<"Whether to show progress or not if the debugger's output is an interactive color-enabled terminal.">; + def ShowProgress + : Property<"show-progress", "Boolean">, + Global, + DefaultFalse, + Desc<"Whether to show progress using Operating System Command (OSC) " + "Sequences in supporting terminal emulators.">; def ShowProgressAnsiPrefix: Property<"show-progress-ansi-prefix", "String">, Global, DefaultStringValue<"${ansi.faint}">, diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 568cd9d..b37d9d3 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -2066,19 +2066,23 @@ void Debugger::CancelForwardEvents(const ListenerSP &listener_sp) { m_forward_listener_sp.reset(); } +bool Debugger::IsEscapeCodeCapableTTY() { + if (lldb::LockableStreamFileSP stream_sp = GetOutputStreamSP()) { + File &file = stream_sp->GetUnlockedFile(); + return file.GetIsInteractive() && file.GetIsRealTerminal() && + file.GetIsTerminalWithColors(); + } + return false; +} + bool Debugger::StatuslineSupported() { // We have trouble with the contol codes on Windows, see // https://github.com/llvm/llvm-project/issues/134846. #ifndef _WIN32 - if (GetShowStatusline()) { - if (lldb::LockableStreamFileSP stream_sp = GetOutputStreamSP()) { - File &file = stream_sp->GetUnlockedFile(); - return file.GetIsInteractive() && file.GetIsRealTerminal() && - file.GetIsTerminalWithColors(); - } - } -#endif + return GetShowStatusline() && IsEscapeCodeCapableTTY(); +#else return false; +#endif } static bool RequiresFollowChildWorkaround(const Process &process) { @@ -2271,10 +2275,11 @@ void Debugger::HandleProgressEvent(const lldb::EventSP &event_sp) { ProgressReport progress_report{data->GetID(), data->GetCompleted(), data->GetTotal(), data->GetMessage()}; - // Do some bookkeeping regardless of whether we're going to display - // progress reports. { std::lock_guard<std::mutex> guard(m_progress_reports_mutex); + + // Do some bookkeeping regardless of whether we're going to display + // progress reports. auto it = llvm::find_if(m_progress_reports, [&](const auto &report) { return report.id == progress_report.id; }); @@ -2287,6 +2292,30 @@ void Debugger::HandleProgressEvent(const lldb::EventSP &event_sp) { } else { m_progress_reports.push_back(progress_report); } + + // Show progress using Operating System Command (OSC) sequences. + if (GetShowProgress() && IsEscapeCodeCapableTTY()) { + if (lldb::LockableStreamFileSP stream_sp = GetOutputStreamSP()) { + + // Clear progress if this was the last progress event. + if (m_progress_reports.empty()) { + stream_sp->Lock() << OSC_PROGRESS_REMOVE; + return; + } + + const ProgressReport &report = m_progress_reports.back(); + + // Show indeterminate progress. + if (report.total == UINT64_MAX) { + stream_sp->Lock() << OSC_PROGRESS_INDETERMINATE; + return; + } + + // Compute and show the progress value (0-100). + const unsigned value = (report.completed / report.total) * 100; + stream_sp->Lock().Printf(OSC_PROGRESS_SHOW, value); + } + } } } diff --git a/lldb/source/Host/freebsd/Host.cpp b/lldb/source/Host/freebsd/Host.cpp index fa7efad..dfdbfea 100644 --- a/lldb/source/Host/freebsd/Host.cpp +++ b/lldb/source/Host/freebsd/Host.cpp @@ -18,8 +18,6 @@ #include <dlfcn.h> #include <execinfo.h> -#include "llvm/Object/ELF.h" - #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" @@ -32,6 +30,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" +#include "llvm/Object/ELF.h" #include "llvm/TargetParser/Host.h" namespace lldb_private { diff --git a/lldb/source/Host/macosx/objcxx/Host.mm b/lldb/source/Host/macosx/objcxx/Host.mm index 3c1d117..7120892 100644 --- a/lldb/source/Host/macosx/objcxx/Host.mm +++ b/lldb/source/Host/macosx/objcxx/Host.mm @@ -1210,6 +1210,39 @@ static Status LaunchProcessPosixSpawn(const char *exe_path, } } + if (launch_info.GetFlags().Test(eLaunchFlagMemoryTagging)) { + // The following function configures the spawn attributes to launch the + // process with memory tagging explicitly enabled. We look it up + // dynamically since it is only available on newer OS. Does nothing on + // hardware which does not support MTE. + // + // int posix_spawnattr_set_use_sec_transition_shims_np( + // posix_spawnattr_t *attr, uint32_t flags); + // + using posix_spawnattr_set_use_sec_transition_shims_np_t = + int (*)(posix_spawnattr_t *attr, uint32_t flags); + auto posix_spawnattr_set_use_sec_transition_shims_np_fn = + (posix_spawnattr_set_use_sec_transition_shims_np_t)dlsym( + RTLD_DEFAULT, "posix_spawnattr_set_use_sec_transition_shims_np"); + if (posix_spawnattr_set_use_sec_transition_shims_np_fn) { + error = + Status(posix_spawnattr_set_use_sec_transition_shims_np_fn(&attr, 0), + eErrorTypePOSIX); + if (error.Fail()) { + LLDB_LOG(log, + "error: {0}, " + "posix_spawnattr_set_use_sec_transition_shims_np(&attr, 0)", + error); + return error; + } + } else { + LLDB_LOG(log, + "error: posix_spawnattr_set_use_sec_transition_shims_np not " + "available", + error); + } + } + // Don't set the binpref if a shell was provided. After all, that's only // going to affect what version of the shell is launched, not what fork of // the binary is launched. We insert "arch --arch <ARCH> as part of the diff --git a/lldb/source/Host/windows/MainLoopWindows.cpp b/lldb/source/Host/windows/MainLoopWindows.cpp index c0b1079..9b7df10 100644 --- a/lldb/source/Host/windows/MainLoopWindows.cpp +++ b/lldb/source/Host/windows/MainLoopWindows.cpp @@ -55,11 +55,7 @@ public: if (m_monitor_thread.joinable()) { m_stopped = true; SetEvent(m_ready); - // Keep trying to cancel ReadFile() until the thread exits. - do { - CancelIoEx(m_handle, /*lpOverlapped=*/NULL); - } while (WaitForSingleObject(m_monitor_thread.native_handle(), 1) == - WAIT_TIMEOUT); + CancelIoEx(m_handle, /*lpOverlapped=*/NULL); m_monitor_thread.join(); } CloseHandle(m_event); diff --git a/lldb/source/Interpreter/CommandInterpreter.cpp b/lldb/source/Interpreter/CommandInterpreter.cpp index d909c56..ffcc9ce 100644 --- a/lldb/source/Interpreter/CommandInterpreter.cpp +++ b/lldb/source/Interpreter/CommandInterpreter.cpp @@ -2591,7 +2591,7 @@ void CommandInterpreter::SourceInitFileCwd(CommandReturnObject &result) { llvm::sys::path::parent_path(home_init_file.GetPath())) { result.SetStatus(eReturnStatusSuccessFinishNoResult); } else { - result.AppendError(InitFileWarning); + result.AppendWarning(InitFileWarning); } } } diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp index 606f951..e20dd31 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.cpp @@ -142,7 +142,13 @@ lldb_private::formatters::LibcxxStdAtomicSyntheticFrontEnd:: SyntheticChildrenFrontEnd * lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator( CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - if (valobj_sp) + if (valobj_sp && IsLibCxxAtomic(*valobj_sp)) return new LibcxxStdAtomicSyntheticFrontEnd(valobj_sp); return nullptr; } + +bool lldb_private::formatters::IsLibCxxAtomic(ValueObject &valobj) { + if (auto valobj_sp = valobj.GetNonSyntheticValue()) + return valobj_sp->GetChildMemberWithName("__a_") != nullptr; + return false; +} diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h index 9327446..7005950 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxAtomic.h @@ -18,6 +18,8 @@ namespace lldb_private { namespace formatters { +bool IsLibCxxAtomic(ValueObject &valobj); + lldb::ValueObjectSP GetLibCxxAtomicValue(ValueObject &valobj); bool LibCxxAtomicSummaryProvider(ValueObject &valobj, Stream &stream, diff --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index 4b183a8..5588208 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -52,7 +52,7 @@ private: ValueObject *m_tree = nullptr; size_t m_num_elements = 0; ValueObject *m_next_element = nullptr; - std::vector<std::pair<ValueObject *, uint64_t>> m_elements_cache; + std::vector<ValueObject *> m_elements_cache; }; class LibCxxUnorderedMapIteratorSyntheticFrontEnd @@ -192,26 +192,25 @@ lldb::ValueObjectSP lldb_private::formatters:: return nullptr; } } - m_elements_cache.push_back( - {value_sp.get(), hash_sp->GetValueAsUnsigned(0)}); + m_elements_cache.push_back(value_sp.get()); m_next_element = node_sp->GetChildMemberWithName("__next_").get(); if (!m_next_element || m_next_element->GetValueAsUnsigned(0) == 0) m_next_element = nullptr; } - std::pair<ValueObject *, uint64_t> val_hash = m_elements_cache[idx]; - if (!val_hash.first) + ValueObject *val_hash = m_elements_cache[idx]; + if (!val_hash) return lldb::ValueObjectSP(); StreamString stream; stream.Printf("[%" PRIu64 "]", (uint64_t)idx); DataExtractor data; Status error; - val_hash.first->GetData(data, error); + val_hash->GetData(data, error); if (error.Fail()) return lldb::ValueObjectSP(); const bool thread_and_frame_only_if_stopped = true; - ExecutionContext exe_ctx = val_hash.first->GetExecutionContextRef().Lock( - thread_and_frame_only_if_stopped); + ExecutionContext exe_ctx = + val_hash->GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped); return CreateValueObjectFromData(stream.GetString(), data, exe_ctx, m_element_type); } diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h index 8a49181..e818b88 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h +++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStl.h @@ -89,6 +89,7 @@ MsvcStlVariantSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp); // MSVC STL std::atomic<> +bool IsMsvcStlAtomic(ValueObject &valobj); bool MsvcStlAtomicSummaryProvider(ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); SyntheticChildrenFrontEnd * diff --git a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp index 3ec3245..c871861 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/MsvcStlAtomic.cpp @@ -83,7 +83,9 @@ llvm::Expected<size_t> lldb_private::formatters:: lldb_private::SyntheticChildrenFrontEnd * lldb_private::formatters::MsvcStlAtomicSyntheticFrontEndCreator( CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp); + if (valobj_sp && IsMsvcStlAtomic(*valobj_sp)) + return new MsvcStlAtomicSyntheticFrontEnd(valobj_sp); + return nullptr; } bool lldb_private::formatters::MsvcStlAtomicSummaryProvider( @@ -100,3 +102,9 @@ bool lldb_private::formatters::MsvcStlAtomicSummaryProvider( } return false; } + +bool lldb_private::formatters::IsMsvcStlAtomic(ValueObject &valobj) { + if (auto valobj_sp = valobj.GetNonSyntheticValue()) + return valobj_sp->GetChildMemberWithName("_Storage") != nullptr; + return false; +} diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp index cc0c9e7..6d8f41a 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp @@ -14,6 +14,7 @@ #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/lldb-enumerations.h" +#include "llvm/ADT/Sequence.h" using namespace lldb; using namespace lldb_private; @@ -266,22 +267,47 @@ bool ClassDescriptorV2::method_list_t::Read(Process *process, return true; } -bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr, - lldb::addr_t relative_selector_base_addr, - bool is_small, bool has_direct_sel) { - size_t ptr_size = process->GetAddressByteSize(); - size_t size = GetSize(process, is_small); +llvm::SmallVector<ClassDescriptorV2::method_t, 0> +ClassDescriptorV2::ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses, + lldb::addr_t relative_selector_base_addr, + bool is_small, bool has_direct_sel) const { + lldb_private::Process *process = m_runtime.GetProcess(); + if (!process) + return {}; - DataBufferHeap buffer(size, '\0'); - Status error; + const size_t size = method_t::GetSize(process, is_small); + const size_t num_methods = addresses.size(); - process->ReadMemory(addr, buffer.GetBytes(), size, error); - if (error.Fail()) { - return false; + llvm::SmallVector<uint8_t, 0> buffer(num_methods * size, 0); + llvm::DenseSet<uint32_t> failed_indices; + + for (auto [idx, addr] : llvm::enumerate(addresses)) { + Status error; + process->ReadMemory(addr, buffer.data() + idx * size, size, error); + if (error.Fail()) + failed_indices.insert(idx); } - DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), - ptr_size); + llvm::SmallVector<method_t, 0> methods; + methods.reserve(num_methods); + for (auto [idx, addr] : llvm::enumerate(addresses)) { + if (failed_indices.contains(idx)) + continue; + DataExtractor extractor(buffer.data() + idx * size, size, + process->GetByteOrder(), + process->GetAddressByteSize()); + methods.push_back(method_t()); + methods.back().Read(extractor, process, addr, relative_selector_base_addr, + is_small, has_direct_sel); + } + + return methods; +} + +bool ClassDescriptorV2::method_t::Read(DataExtractor &extractor, + Process *process, lldb::addr_t addr, + lldb::addr_t relative_selector_base_addr, + bool is_small, bool has_direct_sel) { lldb::offset_t cursor = 0; if (is_small) { @@ -291,11 +317,11 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr, m_name_ptr = addr + nameref_offset; + Status error; if (!has_direct_sel) { // The SEL offset points to a SELRef. We need to dereference twice. - m_name_ptr = process->ReadUnsignedIntegerFromMemory(m_name_ptr, ptr_size, - 0, error); - if (!error.Success()) + m_name_ptr = process->ReadPointerFromMemory(m_name_ptr, error); + if (error.Fail()) return false; } else if (relative_selector_base_addr != LLDB_INVALID_ADDRESS) { m_name_ptr = relative_selector_base_addr + nameref_offset; @@ -308,13 +334,13 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr, m_imp_ptr = extractor.GetAddress_unchecked(&cursor); } + Status error; process->ReadCStringFromMemory(m_name_ptr, m_name, error); - if (error.Fail()) { + if (error.Fail()) return false; - } process->ReadCStringFromMemory(m_types_ptr, m_types, error); - return !error.Fail(); + return error.Success(); } bool ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr) { @@ -447,17 +473,19 @@ ClassDescriptorV2::GetMethodList(Process *process, 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())) + auto idx_to_method_addr = [&](uint32_t idx) { + return method_list.m_first_ptr + (idx * method_list.m_entsize); + }; + llvm::SmallVector<addr_t> addresses = llvm::to_vector(llvm::map_range( + llvm::seq<uint32_t>(method_list.m_count), idx_to_method_addr)); + + llvm::SmallVector<method_t, 0> methods = + ReadMethods(addresses, m_runtime.GetRelativeSelectorBaseAddr(), + method_list.m_is_small, method_list.m_has_direct_selector); + + for (const auto &method : methods) + if (instance_method_func(method.m_name.c_str(), method.m_types.c_str())) break; - } return true; } diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h index 920a5eb..78b3311 100644 --- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h @@ -172,11 +172,16 @@ private: + field_size; // IMP imp; } - bool Read(Process *process, lldb::addr_t addr, + bool Read(DataExtractor &extractor, Process *process, lldb::addr_t addr, lldb::addr_t relative_selector_base_addr, bool is_small, bool has_direct_sel); }; + llvm::SmallVector<method_t, 0> + ReadMethods(llvm::ArrayRef<lldb::addr_t> addresses, + lldb::addr_t relative_selector_base_addr, bool is_small, + bool has_direct_sel) const; + struct ivar_list_t { uint32_t m_entsize; uint32_t m_count; diff --git a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp index f538fc6..57d88f6 100644 --- a/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp +++ b/lldb/source/Plugins/Platform/Android/PlatformAndroid.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/UriParser.h" diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp index b468171..2e02076 100644 --- a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.cpp @@ -22,7 +22,7 @@ using namespace lldb_private::process_gdb_remote; using namespace lldb_private::wasm; RegisterContextWasm::RegisterContextWasm( - wasm::ThreadWasm &thread, uint32_t concrete_frame_idx, + ThreadGDBRemote &thread, uint32_t concrete_frame_idx, GDBRemoteDynamicRegisterInfoSP reg_info_sp) : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false, false) {} diff --git a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h index 7e63eb8..6ca31e5 100644 --- a/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h +++ b/lldb/source/Plugins/Process/wasm/RegisterContextWasm.h @@ -10,6 +10,7 @@ #define LLDB_SOURCE_PLUGINS_PROCESS_WASM_REGISTERCONTEXTWASM_H #include "Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h" +#include "Plugins/Process/gdb-remote/ThreadGDBRemote.h" #include "ThreadWasm.h" #include "Utility/WasmVirtualRegisters.h" #include "lldb/lldb-private-types.h" @@ -34,7 +35,7 @@ class RegisterContextWasm : public process_gdb_remote::GDBRemoteRegisterContext { public: RegisterContextWasm( - wasm::ThreadWasm &thread, uint32_t concrete_frame_idx, + process_gdb_remote::ThreadGDBRemote &thread, uint32_t concrete_frame_idx, process_gdb_remote::GDBRemoteDynamicRegisterInfoSP reg_info_sp); ~RegisterContextWasm() override; diff --git a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp index 99845dd..319c5e2 100644 --- a/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp +++ b/lldb/source/Plugins/Process/wasm/UnwindWasm.cpp @@ -9,6 +9,7 @@ #include "UnwindWasm.h" #include "Plugins/Process/gdb-remote/ThreadGDBRemote.h" #include "ProcessWasm.h" +#include "RegisterContextWasm.h" #include "ThreadWasm.h" #include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" @@ -18,21 +19,6 @@ using namespace lldb_private; using namespace process_gdb_remote; using namespace wasm; -class WasmGDBRemoteRegisterContext : public GDBRemoteRegisterContext { -public: - WasmGDBRemoteRegisterContext(ThreadGDBRemote &thread, - uint32_t concrete_frame_idx, - GDBRemoteDynamicRegisterInfoSP ®_info_sp, - uint64_t pc) - : GDBRemoteRegisterContext(thread, concrete_frame_idx, reg_info_sp, false, - false) { - // Wasm does not have a fixed set of registers but relies on a mechanism - // named local and global variables to store information such as the stack - // pointer. The only actual register is the PC. - PrivateSetRegisterValue(0, pc); - } -}; - lldb::RegisterContextSP UnwindWasm::DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) { if (m_frames.size() <= frame->GetFrameIndex()) @@ -43,9 +29,9 @@ UnwindWasm::DoCreateRegisterContextForFrame(lldb_private::StackFrame *frame) { ProcessWasm *wasm_process = static_cast<ProcessWasm *>(thread->GetProcess().get()); - return std::make_shared<WasmGDBRemoteRegisterContext>( - *gdb_thread, frame->GetConcreteFrameIndex(), - wasm_process->GetRegisterInfo(), m_frames[frame->GetFrameIndex()]); + return std::make_shared<RegisterContextWasm>(*gdb_thread, + frame->GetConcreteFrameIndex(), + wasm_process->GetRegisterInfo()); } uint32_t UnwindWasm::DoGetFrameCount() { diff --git a/lldb/source/Target/RegisterContextUnwind.cpp b/lldb/source/Target/RegisterContextUnwind.cpp index c6d15fc..252bee2 100644 --- a/lldb/source/Target/RegisterContextUnwind.cpp +++ b/lldb/source/Target/RegisterContextUnwind.cpp @@ -52,6 +52,14 @@ static ConstString GetSymbolOrFunctionName(const SymbolContext &sym_ctx) { return ConstString(); } +static bool CallFrameAddressIsValid(ABISP abi_sp, lldb::addr_t cfa) { + if (cfa == LLDB_INVALID_ADDRESS) + return false; + if (abi_sp) + return abi_sp->CallFrameAddressIsValid(cfa); + return cfa != 0 && cfa != 1; +} + RegisterContextUnwind::RegisterContextUnwind(Thread &thread, const SharedPtr &next_frame, SymbolContext &sym_ctx, @@ -448,7 +456,7 @@ void RegisterContextUnwind::InitializeNonZerothFrame() { ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa); // A couple of sanity checks.. - if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) { + if (!CallFrameAddressIsValid(abi_sp, m_cfa)) { UnwindLogMsg("could not find a valid cfa address"); m_frame_type = eNotAValidFrame; return; @@ -1847,9 +1855,11 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; + ProcessSP process_sp = m_thread.GetProcess(); + ABISP abi_sp = process_sp ? process_sp->GetABI() : nullptr; if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetCFAValue(), new_cfa) || - new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { + active_row->GetCFAValue(), new_cfa) || + !CallFrameAddressIsValid(abi_sp, new_cfa)) { UnwindLogMsg("failed to get cfa with fallback unwindplan"); m_fallback_unwind_plan_sp.reset(); m_full_unwind_plan_sp = original_full_unwind_plan_sp; @@ -1870,10 +1880,9 @@ bool RegisterContextUnwind::TryFallbackUnwindPlan() { if (ReadRegisterValueFromRegisterLocation(regloc, reg_info, reg_value)) { new_caller_pc_value = reg_value.GetAsUInt64(); - if (ProcessSP process_sp = m_thread.GetProcess()) { - if (ABISP abi_sp = process_sp->GetABI()) - new_caller_pc_value = abi_sp->FixCodeAddress(new_caller_pc_value); - } + if (process_sp) + new_caller_pc_value = + process_sp->FixCodeAddress(new_caller_pc_value); } } } @@ -1932,9 +1941,11 @@ bool RegisterContextUnwind::ForceSwitchToFallbackUnwindPlan() { active_row->GetCFAValue().GetValueType() != UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; + ProcessSP process_sp = m_thread.GetProcess(); + ABISP abi_sp = process_sp ? process_sp->GetABI() : nullptr; if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row->GetCFAValue(), new_cfa) || - new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { + active_row->GetCFAValue(), new_cfa) || + !CallFrameAddressIsValid(abi_sp, new_cfa)) { UnwindLogMsg("failed to get cfa with fallback unwindplan"); m_fallback_unwind_plan_sp.reset(); return false; @@ -2055,8 +2066,7 @@ bool RegisterContextUnwind::ReadFrameAddress( RegisterNumber cfa_reg(m_thread, row_register_kind, fa.GetRegisterNumber()); if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { - if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || - cfa_reg_contents == 1) { + if (!CallFrameAddressIsValid(abi_sp, cfa_reg_contents)) { UnwindLogMsg( "Got an invalid CFA register value - reg %s (%d), value 0x%" PRIx64, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), |