diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 |
commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /lldb/source/Core | |
parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
download | src-cfca06d7963fa0909f90483b42a6d7d194d01e08.tar.gz src-cfca06d7963fa0909f90483b42a6d7d194d01e08.zip |
Vendor import of llvm-project master 2e10b7a39b9, the last commit beforevendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9vendor/llvm-project/master
the llvmorg-12-init tag, from which release/11.x was branched.
Notes
Notes:
svn path=/vendor/llvm-project/master/; revision=363578
svn path=/vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9/; revision=363579; tag=vendor/llvm-project/llvmorg-11-init-20887-g2e10b7a39b9
Diffstat (limited to 'lldb/source/Core')
46 files changed, 1270 insertions, 2522 deletions
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index b9a7b4a3894a..9d52f1db8918 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -1,4 +1,4 @@ -//===-- Address.cpp ---------------------------------------------*- C++ -*-===// +//===-- Address.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -415,7 +415,7 @@ bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, case DumpStyleSectionNameOffset: if (section_sp) { - section_sp->DumpName(s); + section_sp->DumpName(s->AsRawOstream()); s->Printf(" + %" PRIu64, m_offset); } else { DumpAddress(s->AsRawOstream(), m_offset, addr_size); diff --git a/lldb/source/Core/AddressRange.cpp b/lldb/source/Core/AddressRange.cpp index 83a1e54157d8..0868ac5e0888 100644 --- a/lldb/source/Core/AddressRange.cpp +++ b/lldb/source/Core/AddressRange.cpp @@ -1,4 +1,4 @@ -//===-- AddressRange.cpp ----------------------------------------*- C++ -*-===// +//===-- AddressRange.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/AddressResolver.cpp b/lldb/source/Core/AddressResolver.cpp index 974d99b62065..16b849b721de 100644 --- a/lldb/source/Core/AddressResolver.cpp +++ b/lldb/source/Core/AddressResolver.cpp @@ -1,4 +1,4 @@ -//===-- AddressResolver.cpp -------------------------------------*- C++ -*-===// +//===-- AddressResolver.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/AddressResolverFileLine.cpp b/lldb/source/Core/AddressResolverFileLine.cpp index 4122b5d3b747..b0d8dcdde2de 100644 --- a/lldb/source/Core/AddressResolverFileLine.cpp +++ b/lldb/source/Core/AddressResolverFileLine.cpp @@ -1,4 +1,4 @@ -//===-- AddressResolverFileLine.cpp -----------------------------*- C++ -*-===// +//===-- AddressResolverFileLine.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/AddressResolverName.cpp b/lldb/source/Core/AddressResolverName.cpp index 6b9b7b2de723..51ab6435e8fb 100644 --- a/lldb/source/Core/AddressResolverName.cpp +++ b/lldb/source/Core/AddressResolverName.cpp @@ -1,4 +1,4 @@ -//===-- AddressResolverName.cpp ---------------------------------*- C++ -*-===// +//===-- AddressResolverName.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -91,7 +91,7 @@ AddressResolverName::SearchCallback(SearchFilter &filter, if (context.module_sp) { context.module_sp->FindSymbolsWithNameAndType(m_func_name, eSymbolTypeCode, sym_list); - context.module_sp->FindFunctions(m_func_name, nullptr, + context.module_sp->FindFunctions(m_func_name, CompilerDeclContext(), eFunctionNameTypeAuto, include_symbols, include_inlines, func_list); } diff --git a/lldb/source/Core/Communication.cpp b/lldb/source/Core/Communication.cpp index 0afd897a2093..b358e70b1a91 100644 --- a/lldb/source/Core/Communication.cpp +++ b/lldb/source/Core/Communication.cpp @@ -1,4 +1,4 @@ -//===-- Communication.cpp ---------------------------------------*- C++ -*-===// +//===-- Communication.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -71,8 +71,8 @@ Communication::~Communication() { void Communication::Clear() { SetReadThreadBytesReceivedCallback(nullptr, nullptr); - Disconnect(nullptr); StopReadThread(nullptr); + Disconnect(nullptr); } ConnectionStatus Communication::Connect(const char *url, Status *error_ptr) { @@ -93,6 +93,8 @@ ConnectionStatus Communication::Disconnect(Status *error_ptr) { LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), "{0} Communication::Disconnect ()", this); + assert((!m_read_thread_enabled || m_read_thread_did_exit) && + "Disconnecting while the read thread is running is racy!"); lldb::ConnectionSP connection_sp(m_connection_sp); if (connection_sp) { ConnectionStatus status = connection_sp->Disconnect(error_ptr); @@ -315,16 +317,12 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { Status error; ConnectionStatus status = eConnectionStatusSuccess; bool done = false; + bool disconnect = false; while (!done && comm->m_read_thread_enabled) { size_t bytes_read = comm->ReadFromConnection( buf, sizeof(buf), std::chrono::seconds(5), status, &error); - if (bytes_read > 0) + if (bytes_read > 0 || status == eConnectionStatusEndOfFile) comm->AppendBytesToCache(buf, bytes_read, true, status); - else if ((bytes_read == 0) && status == eConnectionStatusEndOfFile) { - if (comm->GetCloseOnEOF()) - comm->Disconnect(); - comm->AppendBytesToCache(buf, bytes_read, true, status); - } switch (status) { case eConnectionStatusSuccess: @@ -332,11 +330,12 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { case eConnectionStatusEndOfFile: done = true; + disconnect = comm->GetCloseOnEOF(); break; case eConnectionStatusError: // Check GetError() for details if (error.GetType() == eErrorTypePOSIX && error.GetError() == EIO) { // EIO on a pipe is usually caused by remote shutdown - comm->Disconnect(); + disconnect = comm->GetCloseOnEOF(); done = true; } if (error.Fail()) @@ -365,9 +364,22 @@ lldb::thread_result_t Communication::ReadThread(lldb::thread_arg_t p) { if (log) LLDB_LOGF(log, "%p Communication::ReadThread () thread exiting...", p); - comm->m_read_thread_did_exit = true; + // Handle threads wishing to synchronize with us. + { + // Prevent new ones from showing up. + comm->m_read_thread_did_exit = true; + + // Unblock any existing thread waiting for the synchronization signal. + comm->BroadcastEvent(eBroadcastBitNoMorePendingInput); + + // Wait for the thread to finish... + std::lock_guard<std::mutex> guard(comm->m_synchronize_mutex); + // ... and disconnect. + if (disconnect) + comm->Disconnect(); + } + // Let clients know that this thread is exiting - comm->BroadcastEvent(eBroadcastBitNoMorePendingInput); comm->BroadcastEvent(eBroadcastBitReadThreadDidExit); return {}; } @@ -399,10 +411,10 @@ void Communication::SynchronizeWithReadThread() { listener_sp->GetEvent(event_sp, llvm::None); } -void Communication::SetConnection(Connection *connection) { +void Communication::SetConnection(std::unique_ptr<Connection> connection) { Disconnect(nullptr); StopReadThread(nullptr); - m_connection_sp.reset(connection); + m_connection_sp = std::move(connection); } const char * diff --git a/lldb/source/Core/CoreProperties.td b/lldb/source/Core/CoreProperties.td index 014927c65c6f..b04738175f34 100644 --- a/lldb/source/Core/CoreProperties.td +++ b/lldb/source/Core/CoreProperties.td @@ -9,6 +9,10 @@ let Definition = "modulelist" in { Global, DefaultStringValue<"">, Desc<"The path to the clang modules cache directory (-fmodules-cache-path).">; + def SymLinkPaths: Property<"debug-info-symlink-paths", "FileSpecList">, + Global, + DefaultStringValue<"">, + Desc<"Debug info path which should be resolved while parsing, relative to the host filesystem.">; } let Definition = "debugger" in { @@ -18,7 +22,7 @@ let Definition = "debugger" in { Desc<"If true all confirmation prompts will receive their default reply.">; def DisassemblyFormat: Property<"disassembly-format", "FormatEntity">, Global, - DefaultStringValue<"{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${function.changed}\\\\n{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${current-pc-arrow} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: ">, + DefaultStringValue<"{${function.initial-function}{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${function.changed}\\\\n{${module.file.basename}`}{${function.name-without-args}}:\\\\n}{${ansi.fg.yellow}${current-pc-arrow}${ansi.normal} }${addr-file-or-load}{ <${function.concrete-only-addr-offset-no-padding}>}: ">, Desc<"The default disassembly format string to use when disassembling instruction sequences.">; def FrameFormat: Property<"frame-format", "FormatEntity">, Global, @@ -71,6 +75,14 @@ let Definition = "debugger" in { Global, DefaultStringValue<"${ansi.normal}">, Desc<"When displaying the column marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the column to be marked.">; + def StopShowLineMarkerAnsiPrefix: Property<"stop-show-line-ansi-prefix", "String">, + Global, + DefaultStringValue<"${ansi.fg.yellow}">, + Desc<"When displaying the line marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format at the immediately before the line to be marked.">; + def StopShowLineMarkerAnsiSuffix: Property<"stop-show-line-ansi-suffix", "String">, + Global, + DefaultStringValue<"${ansi.normal}">, + Desc<"When displaying the line marker in a color-enabled (i.e. ANSI) terminal, use the ANSI terminal code specified in this format immediately after the line to be marked.">; def TerminalWidth: Property<"term-width", "SInt64">, Global, DefaultUnsignedValue<80>, @@ -91,6 +103,10 @@ let Definition = "debugger" in { Global, DefaultTrue, Desc<"Whether to use Ansi color codes or not.">; + def UseSourceCache: Property<"use-source-cache", "Boolean">, + Global, + DefaultTrue, + Desc<"Whether to cache source files in memory or not.">; def AutoOneLineSummaries: Property<"auto-one-line-summaries", "Boolean">, Global, DefaultTrue, diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp index 33f72a0896cb..5f4f1e266d81 100644 --- a/lldb/source/Core/Debugger.cpp +++ b/lldb/source/Core/Debugger.cpp @@ -1,4 +1,4 @@ -//===-- Debugger.cpp --------------------------------------------*- C++ -*-===// +//===-- Debugger.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -135,84 +135,6 @@ static constexpr OptionEnumValueElement g_language_enumerators[] = { }, }; -#define MODULE_WITH_FUNC \ - "{ " \ - "${module.file.basename}{`${function.name-with-args}" \ - "{${frame.no-debug}${function.pc-offset}}}}" - -#define MODULE_WITH_FUNC_NO_ARGS \ - "{ " \ - "${module.file.basename}{`${function.name-without-args}" \ - "{${frame.no-debug}${function.pc-offset}}}}" - -#define FILE_AND_LINE \ - "{ at ${ansi.fg.cyan}${line.file.basename}${ansi.normal}" \ - ":${ansi.fg.yellow}${line.number}${ansi.normal}" \ - "{:${ansi.fg.yellow}${line.column}${ansi.normal}}}" - -#define IS_OPTIMIZED "{${function.is-optimized} [opt]}" - -#define IS_ARTIFICIAL "{${frame.is-artificial} [artificial]}" - -#define DEFAULT_THREAD_FORMAT \ - "thread #${thread.index}: tid = ${thread.id%tid}" \ - "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \ - "{, name = ${ansi.fg.green}'${thread.name}'${ansi.normal}}" \ - "{, queue = ${ansi.fg.green}'${thread.queue}'${ansi.normal}}" \ - "{, activity = " \ - "${ansi.fg.green}'${thread.info.activity.name}'${ansi.normal}}" \ - "{, ${thread.info.trace_messages} messages}" \ - "{, stop reason = ${ansi.fg.red}${thread.stop-reason}${ansi.normal}}" \ - "{\\nReturn value: ${thread.return-value}}" \ - "{\\nCompleted expression: ${thread.completed-expression}}" \ - "\\n" - -#define DEFAULT_THREAD_STOP_FORMAT \ - "thread #${thread.index}{, name = '${thread.name}'}" \ - "{, queue = ${ansi.fg.green}'${thread.queue}'${ansi.normal}}" \ - "{, activity = " \ - "${ansi.fg.green}'${thread.info.activity.name}'${ansi.normal}}" \ - "{, ${thread.info.trace_messages} messages}" \ - "{, stop reason = ${ansi.fg.red}${thread.stop-reason}${ansi.normal}}" \ - "{\\nReturn value: ${thread.return-value}}" \ - "{\\nCompleted expression: ${thread.completed-expression}}" \ - "\\n" - -#define DEFAULT_FRAME_FORMAT \ - "frame #${frame.index}: " \ - "${ansi.fg.yellow}${frame.pc}${ansi.normal}" MODULE_WITH_FUNC FILE_AND_LINE \ - IS_OPTIMIZED IS_ARTIFICIAL "\\n" - -#define DEFAULT_FRAME_FORMAT_NO_ARGS \ - "frame #${frame.index}: " \ - "${ansi.fg.yellow}${frame.pc}${ansi.normal}" MODULE_WITH_FUNC_NO_ARGS \ - FILE_AND_LINE IS_OPTIMIZED IS_ARTIFICIAL "\\n" - -// Three parts to this disassembly format specification: -// 1. If this is a new function/symbol (no previous symbol/function), print -// dylib`funcname:\n -// 2. If this is a symbol context change (different from previous -// symbol/function), print -// dylib`funcname:\n -// 3. print -// address <+offset>: -#define DEFAULT_DISASSEMBLY_FORMAT \ - "{${function.initial-function}{${module.file.basename}`}{${function.name-" \ - "without-args}}:\\n}{${function.changed}\\n{${module.file.basename}`}{${" \ - "function.name-without-args}}:\\n}{${current-pc-arrow} " \ - "}${addr-file-or-load}{ " \ - "<${function.concrete-only-addr-offset-no-padding}>}: " - -// gdb's disassembly format can be emulated with ${current-pc-arrow}${addr- -// file-or-load}{ <${function.name-without-args}${function.concrete-only-addr- -// offset-no-padding}>}: - -// lldb's original format for disassembly would look like this format string - -// {${function.initial-function}{${module.file.basename}`}{${function.name- -// without- -// args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name- -// without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}: - static constexpr OptionEnumValueElement s_stop_show_column_values[] = { { eStopShowColumnAnsiOrCaret, @@ -290,6 +212,11 @@ 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. + if (!GetUseSourceCache()) { + m_source_file_cache.Clear(); + } } else if (is_load_script && target_sp && load_script_old_value == eLoadScriptFromSymFileWarn) { if (target_sp->TargetProperties::GetLoadScriptFromSymbolFile() == @@ -388,6 +315,9 @@ uint32_t Debugger::GetTerminalWidth() const { } bool Debugger::SetTerminalWidth(uint32_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); } @@ -416,6 +346,20 @@ bool Debugger::SetUseColor(bool b) { return ret; } +bool Debugger::GetUseSourceCache() const { + const uint32_t idx = ePropertyUseSourceCache; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, 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); + if (!ret) { + m_source_file_cache.Clear(); + } + return ret; +} bool Debugger::GetHighlightSource() const { const uint32_t idx = ePropertyHighlightSource; return m_collection_sp->GetPropertyAtIndexAsBoolean( @@ -438,6 +382,16 @@ llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const { return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); } +llvm::StringRef Debugger::GetStopShowLineMarkerAnsiPrefix() const { + const uint32_t idx = ePropertyStopShowLineMarkerAnsiPrefix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + +llvm::StringRef Debugger::GetStopShowLineMarkerAnsiSuffix() const { + const uint32_t idx = ePropertyStopShowLineMarkerAnsiSuffix; + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); +} + uint32_t Debugger::GetStopSourceLineCount(bool before) const { const uint32_t idx = before ? ePropertyStopLineCountBefore : ePropertyStopLineCountAfter; @@ -708,7 +662,7 @@ 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_input_reader_stack(), m_instance_name(), m_loaded_plugins(), + m_io_handler_stack(), m_instance_name(), m_loaded_plugins(), m_event_handler_thread(), m_io_handler_thread(), m_sync_broadcaster(nullptr, "lldb.debugger.sync"), m_forward_listener_sp(), m_clear_once() { @@ -870,15 +824,15 @@ ExecutionContext Debugger::GetSelectedExecutionContext() { } void Debugger::DispatchInputInterrupt() { - std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); - IOHandlerSP reader_sp(m_input_reader_stack.Top()); + std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); + IOHandlerSP reader_sp(m_io_handler_stack.Top()); if (reader_sp) reader_sp->Interrupt(); } void Debugger::DispatchInputEndOfFile() { - std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); - IOHandlerSP reader_sp(m_input_reader_stack.Top()); + std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); + IOHandlerSP reader_sp(m_io_handler_stack.Top()); if (reader_sp) reader_sp->GotEOF(); } @@ -886,81 +840,107 @@ void Debugger::DispatchInputEndOfFile() { void Debugger::ClearIOHandlers() { // The bottom input reader should be the main debugger input reader. We do // not want to close that one here. - std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); - while (m_input_reader_stack.GetSize() > 1) { - IOHandlerSP reader_sp(m_input_reader_stack.Top()); + std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); + while (m_io_handler_stack.GetSize() > 1) { + IOHandlerSP reader_sp(m_io_handler_stack.Top()); if (reader_sp) PopIOHandler(reader_sp); } } -void Debugger::ExecuteIOHandlers() { +void Debugger::RunIOHandlers() { + IOHandlerSP reader_sp = m_io_handler_stack.Top(); while (true) { - IOHandlerSP reader_sp(m_input_reader_stack.Top()); if (!reader_sp) break; reader_sp->Run(); + { + std::lock_guard<std::recursive_mutex> guard( + m_io_handler_synchronous_mutex); + + // Remove all input readers that are done from the top of the stack + while (true) { + IOHandlerSP top_reader_sp = m_io_handler_stack.Top(); + if (top_reader_sp && top_reader_sp->GetIsDone()) + PopIOHandler(top_reader_sp); + else + break; + } + reader_sp = m_io_handler_stack.Top(); + } + } + ClearIOHandlers(); +} + +void Debugger::RunIOHandlerSync(const IOHandlerSP &reader_sp) { + std::lock_guard<std::recursive_mutex> guard(m_io_handler_synchronous_mutex); + + PushIOHandler(reader_sp); + IOHandlerSP top_reader_sp = reader_sp; + + while (top_reader_sp) { + if (!top_reader_sp) + break; - // Remove all input readers that are done from the top of the stack + top_reader_sp->Run(); + + // Don't unwind past the starting point. + if (top_reader_sp.get() == reader_sp.get()) { + if (PopIOHandler(reader_sp)) + break; + } + + // If we pushed new IO handlers, pop them if they're done or restart the + // loop to run them if they're not. while (true) { - IOHandlerSP top_reader_sp = m_input_reader_stack.Top(); - if (top_reader_sp && top_reader_sp->GetIsDone()) + top_reader_sp = m_io_handler_stack.Top(); + if (top_reader_sp && top_reader_sp->GetIsDone()) { PopIOHandler(top_reader_sp); - else + // Don't unwind past the starting point. + if (top_reader_sp.get() == reader_sp.get()) + return; + } else { break; + } } } - ClearIOHandlers(); } bool Debugger::IsTopIOHandler(const lldb::IOHandlerSP &reader_sp) { - return m_input_reader_stack.IsTop(reader_sp); + return m_io_handler_stack.IsTop(reader_sp); } bool Debugger::CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type) { - return m_input_reader_stack.CheckTopIOHandlerTypes(top_type, second_top_type); + return m_io_handler_stack.CheckTopIOHandlerTypes(top_type, second_top_type); } void Debugger::PrintAsync(const char *s, size_t len, bool is_stdout) { lldb_private::StreamFile &stream = is_stdout ? GetOutputStream() : GetErrorStream(); - m_input_reader_stack.PrintAsync(&stream, s, len); + m_io_handler_stack.PrintAsync(&stream, s, len); } ConstString Debugger::GetTopIOHandlerControlSequence(char ch) { - return m_input_reader_stack.GetTopIOHandlerControlSequence(ch); + return m_io_handler_stack.GetTopIOHandlerControlSequence(ch); } const char *Debugger::GetIOHandlerCommandPrefix() { - return m_input_reader_stack.GetTopIOHandlerCommandPrefix(); + return m_io_handler_stack.GetTopIOHandlerCommandPrefix(); } const char *Debugger::GetIOHandlerHelpPrologue() { - return m_input_reader_stack.GetTopIOHandlerHelpPrologue(); + return m_io_handler_stack.GetTopIOHandlerHelpPrologue(); } -void Debugger::RunIOHandler(const IOHandlerSP &reader_sp) { - PushIOHandler(reader_sp); - - IOHandlerSP top_reader_sp = reader_sp; - while (top_reader_sp) { - top_reader_sp->Run(); - - if (top_reader_sp.get() == reader_sp.get()) { - if (PopIOHandler(reader_sp)) - break; - } +bool Debugger::RemoveIOHandler(const IOHandlerSP &reader_sp) { + return PopIOHandler(reader_sp); +} - while (true) { - top_reader_sp = m_input_reader_stack.Top(); - if (top_reader_sp && top_reader_sp->GetIsDone()) - PopIOHandler(top_reader_sp); - else - break; - } - } +void Debugger::RunIOHandlerAsync(const IOHandlerSP &reader_sp, + bool cancel_top_handler) { + PushIOHandler(reader_sp, cancel_top_handler); } void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out, @@ -970,8 +950,8 @@ void Debugger::AdoptTopIOHandlerFilesIfInvalid(FileSP &in, StreamFileSP &out, // input reader's in/out/err streams, or fall back to the debugger file // handles, or we fall back onto stdin/stdout/stderr as a last resort. - std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); - IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); + std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); + IOHandlerSP top_reader_sp(m_io_handler_stack.Top()); // If no STDIN has been set, then set it appropriately if (!in || !in->IsValid()) { if (top_reader_sp) @@ -1009,17 +989,17 @@ void Debugger::PushIOHandler(const IOHandlerSP &reader_sp, if (!reader_sp) return; - std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); + std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); // Get the current top input reader... - IOHandlerSP top_reader_sp(m_input_reader_stack.Top()); + IOHandlerSP top_reader_sp(m_io_handler_stack.Top()); // Don't push the same IO handler twice... if (reader_sp == top_reader_sp) return; // Push our new input reader - m_input_reader_stack.Push(reader_sp); + m_io_handler_stack.Push(reader_sp); reader_sp->Activate(); // Interrupt the top input reader to it will exit its Run() function and let @@ -1035,23 +1015,23 @@ bool Debugger::PopIOHandler(const IOHandlerSP &pop_reader_sp) { if (!pop_reader_sp) return false; - std::lock_guard<std::recursive_mutex> guard(m_input_reader_stack.GetMutex()); + std::lock_guard<std::recursive_mutex> guard(m_io_handler_stack.GetMutex()); // The reader on the stop of the stack is done, so let the next read on the // stack refresh its prompt and if there is one... - if (m_input_reader_stack.IsEmpty()) + if (m_io_handler_stack.IsEmpty()) return false; - IOHandlerSP reader_sp(m_input_reader_stack.Top()); + IOHandlerSP reader_sp(m_io_handler_stack.Top()); if (pop_reader_sp != reader_sp) return false; reader_sp->Deactivate(); reader_sp->Cancel(); - m_input_reader_stack.Pop(); + m_io_handler_stack.Pop(); - reader_sp = m_input_reader_stack.Top(); + reader_sp = m_io_handler_stack.Top(); if (reader_sp) reader_sp->Activate(); @@ -1174,17 +1154,22 @@ bool Debugger::EnableLog(llvm::StringRef channel, if (pos != m_log_streams.end()) log_stream_sp = pos->second.lock(); if (!log_stream_sp) { - llvm::sys::fs::OpenFlags flags = llvm::sys::fs::OF_Text; + File::OpenOptions flags = + File::eOpenOptionWrite | File::eOpenOptionCanCreate; if (log_options & LLDB_LOG_OPTION_APPEND) - flags |= llvm::sys::fs::OF_Append; - int FD; - if (std::error_code ec = llvm::sys::fs::openFileForWrite( - log_file, FD, llvm::sys::fs::CD_CreateAlways, flags)) { - error_stream << "Unable to open log file: " << ec.message(); + flags |= File::eOpenOptionAppend; + else + flags |= File::eOpenOptionTruncate; + auto file = FileSystem::Instance().Open( + FileSpec(log_file), flags, lldb::eFilePermissionsFileDefault, false); + if (!file) { + // FIXME: This gets garbled when called from the log command. + error_stream << "Unable to open log file: " << log_file; return false; } - log_stream_sp = - std::make_shared<llvm::raw_fd_ostream>(FD, should_close, unbuffered); + + log_stream_sp = std::make_shared<llvm::raw_fd_ostream>( + (*file)->GetDescriptor(), should_close, unbuffered); m_log_streams[log_file] = log_stream_sp; } } @@ -1503,9 +1488,9 @@ bool Debugger::StartEventHandlerThread() { listener_sp->StartListeningForEvents(&m_sync_broadcaster, eBroadcastBitEventThreadIsListening); - auto thread_name = + llvm::StringRef thread_name = full_name.GetLength() < llvm::get_max_thread_name_length() - ? full_name.AsCString() + ? full_name.GetStringRef() : "dbg.evt-handler"; // Use larger 8MB stack for this thread @@ -1542,7 +1527,7 @@ void Debugger::StopEventHandlerThread() { lldb::thread_result_t Debugger::IOHandlerThread(lldb::thread_arg_t arg) { Debugger *debugger = (Debugger *)arg; - debugger->ExecuteIOHandlers(); + debugger->RunIOHandlers(); debugger->StopEventHandlerThread(); return {}; } diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp index 33172cc8868e..4da823c7a243 100644 --- a/lldb/source/Core/Disassembler.cpp +++ b/lldb/source/Core/Disassembler.cpp @@ -1,4 +1,4 @@ -//===-- Disassembler.cpp ----------------------------------------*- C++ -*-===// +//===-- Disassembler.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -89,124 +89,57 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, return DisassemblerSP(); } -DisassemblerSP Disassembler::FindPluginForTarget(const TargetSP target_sp, +DisassemblerSP Disassembler::FindPluginForTarget(const Target &target, const ArchSpec &arch, const char *flavor, const char *plugin_name) { - if (target_sp && flavor == nullptr) { + if (flavor == nullptr) { // FIXME - we don't have the mechanism in place to do per-architecture // settings. But since we know that for now we only support flavors on x86 // & x86_64, if (arch.GetTriple().getArch() == llvm::Triple::x86 || arch.GetTriple().getArch() == llvm::Triple::x86_64) - flavor = target_sp->GetDisassemblyFlavor(); + flavor = target.GetDisassemblyFlavor(); } return FindPlugin(arch, flavor, plugin_name); } -static void ResolveAddress(const ExecutionContext &exe_ctx, const Address &addr, - Address &resolved_addr) { +static Address ResolveAddress(Target &target, const Address &addr) { if (!addr.IsSectionOffset()) { + Address resolved_addr; // If we weren't passed in a section offset address range, try and resolve // it to something - Target *target = exe_ctx.GetTargetPtr(); - if (target) { - bool is_resolved = - target->GetSectionLoadList().IsEmpty() ? - target->GetImages().ResolveFileAddress(addr.GetOffset(), - resolved_addr) : - target->GetSectionLoadList().ResolveLoadAddress(addr.GetOffset(), - resolved_addr); - - // We weren't able to resolve the address, just treat it as a raw address - if (is_resolved && resolved_addr.IsValid()) - return; - } - } - resolved_addr = addr; -} - -size_t Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, - const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, - SymbolContextList &sc_list, - uint32_t num_instructions, - bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, - uint32_t options, Stream &strm) { - size_t success_count = 0; - const size_t count = sc_list.GetSize(); - SymbolContext sc; - AddressRange range; - const uint32_t scope = - eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol; - const bool use_inline_block_range = true; - for (size_t i = 0; i < count; ++i) { - if (!sc_list.GetContextAtIndex(i, sc)) - break; - for (uint32_t range_idx = 0; - sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); - ++range_idx) { - if (Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm)) { - ++success_count; - strm.EOL(); - } - } - } - return success_count; -} - -bool Disassembler::Disassemble( - Debugger &debugger, const ArchSpec &arch, const char *plugin_name, - const char *flavor, const ExecutionContext &exe_ctx, ConstString name, - Module *module, uint32_t num_instructions, bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { - // If no name is given there's nothing to disassemble. - if (!name) - return false; - - const bool include_symbols = true; - const bool include_inlines = true; - - // Find functions matching the given name. - SymbolContextList sc_list; - if (module) { - module->FindFunctions(name, nullptr, eFunctionNameTypeAuto, include_symbols, - include_inlines, sc_list); - } else if (exe_ctx.GetTargetPtr()) { - exe_ctx.GetTargetPtr()->GetImages().FindFunctions( - name, eFunctionNameTypeAuto, include_symbols, include_inlines, sc_list); + bool is_resolved = target.GetSectionLoadList().IsEmpty() + ? target.GetImages().ResolveFileAddress( + addr.GetOffset(), resolved_addr) + : target.GetSectionLoadList().ResolveLoadAddress( + addr.GetOffset(), resolved_addr); + + // We weren't able to resolve the address, just treat it as a raw address + if (is_resolved && resolved_addr.IsValid()) + return resolved_addr; } - - // If no functions were found there's nothing to disassemble. - if (sc_list.IsEmpty()) - return false; - - return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, sc_list, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + return addr; } lldb::DisassemblerSP Disassembler::DisassembleRange( const ArchSpec &arch, const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, const AddressRange &range, - bool prefer_file_cache) { + Target &target, const AddressRange &range, bool prefer_file_cache) { if (range.GetByteSize() <= 0) return {}; if (!range.GetBaseAddress().IsValid()) return {}; - lldb::DisassemblerSP disasm_sp = Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name); + lldb::DisassemblerSP disasm_sp = + Disassembler::FindPluginForTarget(target, arch, flavor, plugin_name); if (!disasm_sp) return {}; - const size_t bytes_disassembled = - disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache); + const size_t bytes_disassembled = disasm_sp->ParseInstructions( + target, range.GetBaseAddress(), {Limit::Bytes, range.GetByteSize()}, + nullptr, prefer_file_cache); if (bytes_disassembled == 0) return {}; @@ -238,63 +171,28 @@ Disassembler::DisassembleBytes(const ArchSpec &arch, const char *plugin_name, bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, const char *plugin_name, const char *flavor, const ExecutionContext &exe_ctx, - const AddressRange &disasm_range, - uint32_t num_instructions, + const Address &address, Limit limit, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { - if (!disasm_range.GetByteSize()) + if (!exe_ctx.GetTargetPtr()) return false; lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); - + exe_ctx.GetTargetRef(), arch, flavor, plugin_name)); if (!disasm_sp) return false; - AddressRange range; - ResolveAddress(exe_ctx, disasm_range.GetBaseAddress(), - range.GetBaseAddress()); - range.SetByteSize(disasm_range.GetByteSize()); - const bool prefer_file_cache = false; - size_t bytes_disassembled = - disasm_sp->ParseInstructions(&exe_ctx, range, &strm, prefer_file_cache); - if (bytes_disassembled == 0) - return false; - - return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); -} - -bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, - const char *plugin_name, const char *flavor, - const ExecutionContext &exe_ctx, - const Address &start_address, - uint32_t num_instructions, - bool mixed_source_and_assembly, - uint32_t num_mixed_context_lines, - uint32_t options, Stream &strm) { - if (num_instructions == 0) - return false; - - lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget( - exe_ctx.GetTargetSP(), arch, flavor, plugin_name)); - if (!disasm_sp) - return false; - - Address addr; - ResolveAddress(exe_ctx, start_address, addr); - const bool prefer_file_cache = false; size_t bytes_disassembled = disasm_sp->ParseInstructions( - &exe_ctx, addr, num_instructions, prefer_file_cache); + exe_ctx.GetTargetRef(), address, limit, &strm, prefer_file_cache); if (bytes_disassembled == 0) return false; - return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + disasm_sp->PrintInstructions(debugger, arch, exe_ctx, + mixed_source_and_assembly, + num_mixed_context_lines, options, strm); + return true; } Disassembler::SourceLine @@ -380,21 +278,16 @@ bool Disassembler::ElideMixedSourceAndDisassemblyLine( return false; } -bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, - Debugger &debugger, const ArchSpec &arch, +void Disassembler::PrintInstructions(Debugger &debugger, const ArchSpec &arch, const ExecutionContext &exe_ctx, - uint32_t num_instructions, bool mixed_source_and_assembly, uint32_t num_mixed_context_lines, uint32_t options, Stream &strm) { // We got some things disassembled... - size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize(); - - if (num_instructions > 0 && num_instructions < num_instructions_found) - num_instructions_found = num_instructions; + size_t num_instructions_found = GetInstructionList().GetSize(); const uint32_t max_opcode_byte_size = - disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize(); + GetInstructionList().GetMaxOpcocdeByteSize(); SymbolContext sc; SymbolContext prev_sc; AddressRange current_source_line_range; @@ -435,8 +328,7 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, size_t address_text_size = 0; for (size_t i = 0; i < num_instructions_found; ++i) { - Instruction *inst = - disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get(); + Instruction *inst = GetInstructionList().GetInstructionAtIndex(i).get(); if (inst) { const Address &addr = inst->GetAddress(); ModuleSP module_sp(addr.GetModule()); @@ -485,8 +377,7 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, previous_symbol = nullptr; SourceLine previous_line; for (size_t i = 0; i < num_instructions_found; ++i) { - Instruction *inst = - disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get(); + Instruction *inst = GetInstructionList().GetInstructionAtIndex(i).get(); if (inst) { const Address &addr = inst->GetAddress(); @@ -646,8 +537,6 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, break; } } - - return true; } bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, @@ -675,9 +564,10 @@ bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch, range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE); } - return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range, - num_instructions, mixed_source_and_assembly, - num_mixed_context_lines, options, strm); + return Disassemble( + debugger, arch, plugin_name, flavor, exe_ctx, range.GetBaseAddress(), + {Limit::Instructions, num_instructions}, mixed_source_and_assembly, + num_mixed_context_lines, options, strm); } Instruction::Instruction(const Address &address, AddressClass addr_class) @@ -1182,82 +1072,44 @@ InstructionList::GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr, return GetIndexOfInstructionAtAddress(address); } -size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx, - const AddressRange &range, - Stream *error_strm_ptr, - bool prefer_file_cache) { - if (exe_ctx) { - Target *target = exe_ctx->GetTargetPtr(); - const addr_t byte_size = range.GetByteSize(); - if (target == nullptr || byte_size == 0 || - !range.GetBaseAddress().IsValid()) - return 0; - - auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0'); - - Status error; - lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; - const size_t bytes_read = target->ReadMemory( - range.GetBaseAddress(), prefer_file_cache, data_sp->GetBytes(), - data_sp->GetByteSize(), error, &load_addr); - - if (bytes_read > 0) { - if (bytes_read != data_sp->GetByteSize()) - data_sp->SetByteSize(bytes_read); - DataExtractor data(data_sp, m_arch.GetByteOrder(), - m_arch.GetAddressByteSize()); - const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; - return DecodeInstructions(range.GetBaseAddress(), data, 0, UINT32_MAX, - false, data_from_file); - } else if (error_strm_ptr) { - const char *error_cstr = error.AsCString(); - if (error_cstr) { - error_strm_ptr->Printf("error: %s\n", error_cstr); - } - } - } else if (error_strm_ptr) { - error_strm_ptr->PutCString("error: invalid execution context\n"); - } - return 0; -} - -size_t Disassembler::ParseInstructions(const ExecutionContext *exe_ctx, - const Address &start, - uint32_t num_instructions, +size_t Disassembler::ParseInstructions(Target &target, Address start, + Limit limit, Stream *error_strm_ptr, bool prefer_file_cache) { m_instruction_list.Clear(); - if (exe_ctx == nullptr || num_instructions == 0 || !start.IsValid()) + if (!start.IsValid()) return 0; - Target *target = exe_ctx->GetTargetPtr(); - // Calculate the max buffer size we will need in order to disassemble - const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize(); - - if (target == nullptr || byte_size == 0) - return 0; + start = ResolveAddress(target, start); - DataBufferHeap *heap_buffer = new DataBufferHeap(byte_size, '\0'); - DataBufferSP data_sp(heap_buffer); + addr_t byte_size = limit.value; + if (limit.kind == Limit::Instructions) + byte_size *= m_arch.GetMaximumOpcodeByteSize(); + auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0'); Status error; lldb::addr_t load_addr = LLDB_INVALID_ADDRESS; const size_t bytes_read = - target->ReadMemory(start, prefer_file_cache, heap_buffer->GetBytes(), - byte_size, error, &load_addr); - + target.ReadMemory(start, prefer_file_cache, data_sp->GetBytes(), + data_sp->GetByteSize(), error, &load_addr); const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS; - if (bytes_read == 0) + if (bytes_read == 0) { + if (error_strm_ptr) { + if (const char *error_cstr = error.AsCString()) + error_strm_ptr->Printf("error: %s\n", error_cstr); + } return 0; + } + + if (bytes_read != data_sp->GetByteSize()) + data_sp->SetByteSize(bytes_read); DataExtractor data(data_sp, m_arch.GetByteOrder(), m_arch.GetAddressByteSize()); - - const bool append_instructions = true; - DecodeInstructions(start, data, 0, num_instructions, append_instructions, - data_from_file); - - return m_instruction_list.GetSize(); + return DecodeInstructions(start, data, 0, + limit.kind == Limit::Instructions ? limit.value + : UINT32_MAX, + false, data_from_file); } // Disassembler copy constructor @@ -1346,7 +1198,7 @@ void PseudoInstruction::SetOpcode(size_t opcode_size, void *opcode_data) { } void PseudoInstruction::SetDescription(llvm::StringRef description) { - m_description = description; + m_description = std::string(description); } Instruction::Operand Instruction::Operand::BuildRegister(ConstString &r) { diff --git a/lldb/source/Core/DumpDataExtractor.cpp b/lldb/source/Core/DumpDataExtractor.cpp index b5e1071b72ae..dbfedfae27a8 100644 --- a/lldb/source/Core/DumpDataExtractor.cpp +++ b/lldb/source/Core/DumpDataExtractor.cpp @@ -1,4 +1,4 @@ -//===-- DumpDataExtractor.cpp -----------------------------------*- C++ -*-===// +//===-- DumpDataExtractor.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -128,6 +128,104 @@ static lldb::offset_t DumpAPInt(Stream *s, const DataExtractor &data, return offset; } +/// Dumps decoded instructions to a stream. +static lldb::offset_t DumpInstructions(const DataExtractor &DE, Stream *s, + ExecutionContextScope *exe_scope, + offset_t start_offset, + uint64_t base_addr, + size_t number_of_instructions) { + offset_t offset = start_offset; + + TargetSP target_sp; + if (exe_scope) + target_sp = exe_scope->CalculateTarget(); + if (target_sp) { + DisassemblerSP disassembler_sp( + Disassembler::FindPlugin(target_sp->GetArchitecture(), + target_sp->GetDisassemblyFlavor(), nullptr)); + if (disassembler_sp) { + lldb::addr_t addr = base_addr + start_offset; + lldb_private::Address so_addr; + bool data_from_file = true; + if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { + data_from_file = false; + } else { + if (target_sp->GetSectionLoadList().IsEmpty() || + !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) + so_addr.SetRawAddress(addr); + } + + size_t bytes_consumed = disassembler_sp->DecodeInstructions( + so_addr, DE, start_offset, number_of_instructions, false, + data_from_file); + + if (bytes_consumed) { + offset += bytes_consumed; + const bool show_address = base_addr != LLDB_INVALID_ADDRESS; + const bool show_bytes = true; + ExecutionContext exe_ctx; + exe_scope->CalculateExecutionContext(exe_ctx); + disassembler_sp->GetInstructionList().Dump(s, show_address, show_bytes, + &exe_ctx); + } + } + } else + s->Printf("invalid target"); + + return offset; +} + +/// Prints the specific escape sequence of the given character to the stream. +/// If the character doesn't have a known specific escape sequence (e.g., '\a', +/// '\n' but not generic escape sequences such as'\x12'), this function will +/// not modify the stream and return false. +static bool TryDumpSpecialEscapedChar(Stream &s, const char c) { + switch (c) { + case '\033': + // Common non-standard escape code for 'escape'. + s.Printf("\\e"); + return true; + case '\a': + s.Printf("\\a"); + return true; + case '\b': + s.Printf("\\b"); + return true; + case '\f': + s.Printf("\\f"); + return true; + case '\n': + s.Printf("\\n"); + return true; + case '\r': + s.Printf("\\r"); + return true; + case '\t': + s.Printf("\\t"); + return true; + case '\v': + s.Printf("\\v"); + return true; + case '\0': + s.Printf("\\0"); + return true; + default: + return false; + } +} + +/// Dump the character to a stream. A character that is not printable will be +/// represented by its escape sequence. +static void DumpCharacter(Stream &s, const char c) { + if (TryDumpSpecialEscapedChar(s, c)) + return; + if (llvm::isPrint(c)) { + s.PutChar(c); + return; + } + s.Printf("\\x%2.2x", c); +} + lldb::offset_t lldb_private::DumpDataExtractor( const DataExtractor &DE, Stream *s, offset_t start_offset, lldb::Format item_format, size_t item_byte_size, size_t item_count, @@ -147,44 +245,9 @@ lldb::offset_t lldb_private::DumpDataExtractor( offset_t offset = start_offset; - if (item_format == eFormatInstruction) { - TargetSP target_sp; - if (exe_scope) - target_sp = exe_scope->CalculateTarget(); - if (target_sp) { - DisassemblerSP disassembler_sp(Disassembler::FindPlugin( - target_sp->GetArchitecture(), - target_sp->GetDisassemblyFlavor(), nullptr)); - if (disassembler_sp) { - lldb::addr_t addr = base_addr + start_offset; - lldb_private::Address so_addr; - bool data_from_file = true; - if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) { - data_from_file = false; - } else { - if (target_sp->GetSectionLoadList().IsEmpty() || - !target_sp->GetImages().ResolveFileAddress(addr, so_addr)) - so_addr.SetRawAddress(addr); - } - - size_t bytes_consumed = disassembler_sp->DecodeInstructions( - so_addr, DE, start_offset, item_count, false, data_from_file); - - if (bytes_consumed) { - offset += bytes_consumed; - const bool show_address = base_addr != LLDB_INVALID_ADDRESS; - const bool show_bytes = true; - ExecutionContext exe_ctx; - exe_scope->CalculateExecutionContext(exe_ctx); - disassembler_sp->GetInstructionList().Dump(s, show_address, - show_bytes, &exe_ctx); - } - } - } else - s->Printf("invalid target"); - - return offset; - } + if (item_format == eFormatInstruction) + return DumpInstructions(DE, s, exe_scope, start_offset, base_addr, + item_count); if ((item_format == eFormatOSType || item_format == eFormatAddressInfo) && item_byte_size > 8) @@ -284,43 +347,14 @@ lldb::offset_t lldb_private::DumpDataExtractor( const uint64_t ch = DE.GetMaxU64Bitfield(&offset, item_byte_size, item_bit_size, item_bit_offset); - if (isprint(ch)) + if (llvm::isPrint(ch)) s->Printf("%c", (char)ch); else if (item_format != eFormatCharPrintable) { - switch (ch) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - case '\0': - s->Printf("\\0"); - break; - default: + if (!TryDumpSpecialEscapedChar(*s, ch)) { if (item_byte_size == 1) s->Printf("\\x%2.2x", (uint8_t)ch); else s->Printf("%" PRIu64, ch); - break; } } else { s->PutChar(NON_PRINTABLE_CHAR); @@ -375,42 +409,7 @@ lldb::offset_t lldb_private::DumpDataExtractor( s->PutChar('\''); for (uint32_t i = 0; i < item_byte_size; ++i) { uint8_t ch = (uint8_t)(uval64 >> ((item_byte_size - i - 1) * 8)); - if (isprint(ch)) - s->Printf("%c", ch); - else { - switch (ch) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - case '\0': - s->Printf("\\0"); - break; - default: - s->Printf("\\x%2.2x", ch); - break; - } - } + DumpCharacter(*s, ch); } s->PutChar('\''); } break; @@ -425,40 +424,7 @@ lldb::offset_t lldb_private::DumpDataExtractor( s->PutChar('\"'); while (const char c = *cstr) { - if (isprint(c)) { - s->PutChar(c); - } else { - switch (c) { - case '\033': - s->Printf("\\e"); - break; - case '\a': - s->Printf("\\a"); - break; - case '\b': - s->Printf("\\b"); - break; - case '\f': - s->Printf("\\f"); - break; - case '\n': - s->Printf("\\n"); - break; - case '\r': - s->Printf("\\r"); - break; - case '\t': - s->Printf("\\t"); - break; - case '\v': - s->Printf("\\v"); - break; - default: - s->Printf("\\x%2.2x", c); - break; - } - } - + DumpCharacter(*s, c); ++cstr; } diff --git a/lldb/source/Core/DumpRegisterValue.cpp b/lldb/source/Core/DumpRegisterValue.cpp index 74b02413f101..2018d618f1d1 100644 --- a/lldb/source/Core/DumpRegisterValue.cpp +++ b/lldb/source/Core/DumpRegisterValue.cpp @@ -1,4 +1,4 @@ -//===-- DumpRegisterValue.cpp -----------------------------------*- C++ -*-===// +//===-- DumpRegisterValue.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -33,7 +33,7 @@ bool lldb_private::DumpRegisterValue(const RegisterValue ®_val, Stream *s, format_string.Printf("%%%us", reg_name_right_align_at); else format_string.Printf("%%s"); - std::string fmt = format_string.GetString(); + std::string fmt = std::string(format_string.GetString()); if (prefix_with_name) { if (reg_info->name) { s->Printf(fmt.c_str(), reg_info->name); diff --git a/lldb/source/Core/DynamicLoader.cpp b/lldb/source/Core/DynamicLoader.cpp index 57130d6fa57a..ceccbe437e1d 100644 --- a/lldb/source/Core/DynamicLoader.cpp +++ b/lldb/source/Core/DynamicLoader.cpp @@ -1,4 +1,4 @@ -//===-- DynamicLoader.cpp ---------------------------------------*- C++ -*-===// +//===-- DynamicLoader.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -193,7 +193,7 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file, if (error.Success() && memory_info.GetMapped() && memory_info.GetRange().GetRangeBase() == base_addr && !(memory_info.GetName().IsEmpty())) { - ModuleSpec new_module_spec(FileSpec(memory_info.GetName().AsCString()), + ModuleSpec new_module_spec(FileSpec(memory_info.GetName().GetStringRef()), target.GetArchitecture()); if ((module_sp = modules.FindFirstModule(new_module_spec))) { diff --git a/lldb/source/Core/EmulateInstruction.cpp b/lldb/source/Core/EmulateInstruction.cpp index 62942fb715b3..f7f56e9fc54f 100644 --- a/lldb/source/Core/EmulateInstruction.cpp +++ b/lldb/source/Core/EmulateInstruction.cpp @@ -1,4 +1,4 @@ -//===-- EmulateInstruction.cpp ----------------------------------*- C++ -*-===// +//===-- EmulateInstruction.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/FileLineResolver.cpp b/lldb/source/Core/FileLineResolver.cpp index 7d91d1a3e472..37435f9e9047 100644 --- a/lldb/source/Core/FileLineResolver.cpp +++ b/lldb/source/Core/FileLineResolver.cpp @@ -1,4 +1,4 @@ -//===-- FileLineResolver.cpp ------------------------------------*- C++ -*-===// +//===-- FileLineResolver.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/FileSpecList.cpp b/lldb/source/Core/FileSpecList.cpp index 6651324fa362..3ada7b495fdb 100644 --- a/lldb/source/Core/FileSpecList.cpp +++ b/lldb/source/Core/FileSpecList.cpp @@ -1,4 +1,4 @@ -//===-- FileSpecList.cpp ----------------------------------------*- C++ -*-===// +//===-- FileSpecList.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp index 7aa1eced34f3..d491ac14bec8 100644 --- a/lldb/source/Core/FormatEntity.cpp +++ b/lldb/source/Core/FormatEntity.cpp @@ -1,4 +1,4 @@ -//===-- FormatEntity.cpp ----------------------------------------*- C++ -*-===// +//===-- FormatEntity.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -46,7 +46,6 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/Utility/RegisterValue.h" -#include "lldb/Utility/SharingPtr.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringList.h" @@ -166,6 +165,7 @@ static FormatEntity::Entry::Definition g_thread_child_entries[] = { ENTRY("queue", ThreadQueue), ENTRY("name", ThreadName), ENTRY("stop-reason", ThreadStopReason), + ENTRY("stop-reason-raw", ThreadStopReasonRaw), ENTRY("return-value", ThreadReturnValue), ENTRY("completed-expression", ThreadCompletedExpression), }; @@ -328,6 +328,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) { ENUM_TO_CSTR(ThreadName); ENUM_TO_CSTR(ThreadQueue); ENUM_TO_CSTR(ThreadStopReason); + ENUM_TO_CSTR(ThreadStopReasonRaw); ENUM_TO_CSTR(ThreadReturnValue); ENUM_TO_CSTR(ThreadCompletedExpression); ENUM_TO_CSTR(ScriptThread); @@ -1273,15 +1274,23 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, case Entry::Type::ThreadStopReason: if (exe_ctx) { - Thread *thread = exe_ctx->GetThreadPtr(); - if (thread) { - StopInfoSP stop_info_sp = thread->GetStopInfo(); - if (stop_info_sp && stop_info_sp->IsValid()) { - const char *cstr = stop_info_sp->GetDescription(); - if (cstr && cstr[0]) { - s.PutCString(cstr); - return true; - } + if (Thread *thread = exe_ctx->GetThreadPtr()) { + std::string stop_description = thread->GetStopDescription(); + if (!stop_description.empty()) { + s.PutCString(stop_description); + return true; + } + } + } + return false; + + case Entry::Type::ThreadStopReasonRaw: + if (exe_ctx) { + if (Thread *thread = exe_ctx->GetThreadPtr()) { + std::string stop_description = thread->GetStopDescriptionRaw(); + if (!stop_description.empty()) { + s.PutCString(stop_description); + return true; } } } @@ -1544,7 +1553,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, sc->block->GetInlinedFunctionInfo(); if (inline_info) { s.PutCString(" [inlined] "); - inline_info->GetName(sc->function->GetLanguage()).Dump(&s); + inline_info->GetName().Dump(&s); } } } @@ -1628,8 +1637,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, if (inline_info) { s.PutCString(cstr); s.PutCString(" [inlined] "); - cstr = - inline_info->GetName(sc->function->GetLanguage()).GetCString(); + cstr = inline_info->GetName().GetCString(); } VariableList args; @@ -1750,12 +1758,11 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, case Entry::Type::FunctionMangledName: { const char *name = nullptr; if (sc->symbol) - name = sc->symbol->GetMangled() - .GetName(sc->symbol->GetLanguage(), Mangled::ePreferMangled) - .AsCString(); + name = + sc->symbol->GetMangled().GetName(Mangled::ePreferMangled).AsCString(); else if (sc->function) name = sc->function->GetMangled() - .GetName(sc->symbol->GetLanguage(), Mangled::ePreferMangled) + .GetName(Mangled::ePreferMangled) .AsCString(); if (!name) @@ -1766,7 +1773,7 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, if (const InlineFunctionInfo *inline_info = sc->block->GetInlinedFunctionInfo()) { s.PutCString(" [inlined] "); - inline_info->GetName(sc->function->GetLanguage()).Dump(&s); + inline_info->GetName().Dump(&s); } } return true; @@ -2340,10 +2347,10 @@ bool FormatEntity::FormatFileSpec(const FileSpec &file_spec, Stream &s, file_spec.Dump(s.AsRawOstream()); return true; } else if (variable_name.equals(".basename")) { - s.PutCString(file_spec.GetFilename().AsCString("")); + s.PutCString(file_spec.GetFilename().GetStringRef()); return true; } else if (variable_name.equals(".dirname")) { - s.PutCString(file_spec.GetFilename().AsCString("")); + s.PutCString(file_spec.GetFilename().GetStringRef()); return true; } return false; @@ -2402,7 +2409,7 @@ void FormatEntity::AutoComplete(CompletionRequest &request) { llvm::StringRef partial_variable(str.substr(dollar_pos + 2)); if (partial_variable.empty()) { - // Suggest all top level entites as we are just past "${" + // Suggest all top level entities as we are just past "${" StringList new_matches; AddMatches(&g_root, str, llvm::StringRef(), new_matches); request.AddCompletions(new_matches); diff --git a/lldb/source/Core/Highlighter.cpp b/lldb/source/Core/Highlighter.cpp index c3c614aac210..04d993b8305c 100644 --- a/lldb/source/Core/Highlighter.cpp +++ b/lldb/source/Core/Highlighter.cpp @@ -1,4 +1,4 @@ -//===-- Highlighter.cpp -----------------------------------------*- C++ -*-===// +//===-- Highlighter.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/IOHandler.cpp b/lldb/source/Core/IOHandler.cpp index 4021a6d7f327..6cf09aaa7f9d 100644 --- a/lldb/source/Core/IOHandler.cpp +++ b/lldb/source/Core/IOHandler.cpp @@ -1,4 +1,4 @@ -//===-- IOHandler.cpp -------------------------------------------*- C++ -*-===// +//===-- IOHandler.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -125,6 +125,8 @@ void IOHandlerStack::PrintAsync(Stream *stream, const char *s, size_t len) { std::lock_guard<std::recursive_mutex> guard(m_mutex); if (m_top) m_top->PrintAsync(stream, s, len); + else + stream->Write(s, len); } } @@ -251,9 +253,9 @@ IOHandlerEditline::IOHandlerEditline( m_input_sp && m_input_sp->GetIsRealTerminal(); if (use_editline) { - m_editline_up.reset(new Editline(editline_name, GetInputFILE(), - GetOutputFILE(), GetErrorFILE(), - m_color_prompts)); + m_editline_up = std::make_unique<Editline>(editline_name, GetInputFILE(), + GetOutputFILE(), GetErrorFILE(), + m_color_prompts); m_editline_up->SetIsInputCompleteCallback(IsInputCompleteCallback, this); m_editline_up->SetAutoCompleteCallback(AutoCompleteCallback, this); // See if the delegate supports fixing indentation @@ -287,12 +289,20 @@ void IOHandlerEditline::Deactivate() { m_delegate.IOHandlerDeactivated(*this); } +void IOHandlerEditline::TerminalSizeChanged() { +#if LLDB_ENABLE_LIBEDIT + if (m_editline_up) + m_editline_up->TerminalSizeChanged(); +#endif +} + // Split out a line from the buffer, if there is a full one to get. static Optional<std::string> SplitLine(std::string &line_buffer) { size_t pos = line_buffer.find('\n'); if (pos == std::string::npos) return None; - std::string line = StringRef(line_buffer.c_str(), pos).rtrim("\n\r"); + std::string line = + std::string(StringRef(line_buffer.c_str(), pos).rtrim("\n\r")); line_buffer = line_buffer.substr(pos + 1); return line; } @@ -300,7 +310,7 @@ static Optional<std::string> SplitLine(std::string &line_buffer) { // If the final line of the file ends without a end-of-line, return // it as a line anyway. static Optional<std::string> SplitLineEOF(std::string &line_buffer) { - if (llvm::all_of(line_buffer, isspace)) + if (llvm::all_of(line_buffer, llvm::isSpace)) return None; std::string line = std::move(line_buffer); line_buffer.clear(); @@ -443,7 +453,7 @@ const char *IOHandlerEditline::GetPrompt() { } bool IOHandlerEditline::SetPrompt(llvm::StringRef prompt) { - m_prompt = prompt; + m_prompt = std::string(prompt); #if LLDB_ENABLE_LIBEDIT if (m_editline_up) @@ -458,7 +468,7 @@ const char *IOHandlerEditline::GetContinuationPrompt() { } void IOHandlerEditline::SetContinuationPrompt(llvm::StringRef prompt) { - m_continuation_prompt = prompt; + m_continuation_prompt = std::string(prompt); #if LLDB_ENABLE_LIBEDIT if (m_editline_up) diff --git a/lldb/source/Core/IOHandlerCursesGUI.cpp b/lldb/source/Core/IOHandlerCursesGUI.cpp index 1661b465efaf..f8fc91772198 100644 --- a/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -1,4 +1,4 @@ -//===-- IOHandlerCursesGUI.cpp ----------------------------------*- C++ -*-===// +//===-- IOHandlerCursesGUI.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -744,7 +744,8 @@ protected: bool m_is_subwin; private: - DISALLOW_COPY_AND_ASSIGN(Window); + Window(const Window &) = delete; + const Window &operator=(const Window &) = delete; }; class MenuDelegate { @@ -918,7 +919,7 @@ void Menu::DrawMenuTitle(Window &window, bool highlight) { const attr_t hilgight_attr = A_REVERSE; if (highlight) window.AttributeOn(hilgight_attr); - if (isprint(shortcut_key)) { + if (llvm::isPrint(shortcut_key)) { size_t lower_pos = m_name.find(tolower(shortcut_key)); size_t upper_pos = m_name.find(toupper(shortcut_key)); const char *name = m_name.c_str(); @@ -947,7 +948,7 @@ void Menu::DrawMenuTitle(Window &window, bool highlight) { window.AttributeOff(hilgight_attr); if (m_key_name.empty()) { - if (!underlined_shortcut && isprint(m_key_value)) { + if (!underlined_shortcut && llvm::isPrint(m_key_value)) { window.AttributeOn(COLOR_PAIR(3)); window.Printf(" (%c)", m_key_value); window.AttributeOff(COLOR_PAIR(3)); @@ -2714,7 +2715,7 @@ static const char *CursesKeyToCString(int ch) { case KEY_ESCAPE: return "escape"; default: - if (isprint(ch)) + if (llvm::isPrint(ch)) snprintf(g_desc, sizeof(g_desc), "%c", ch); else snprintf(g_desc, sizeof(g_desc), "\\x%2.2x", ch); @@ -3909,7 +3910,7 @@ IOHandlerCursesGUI::IOHandlerCursesGUI(Debugger &debugger) void IOHandlerCursesGUI::Activate() { IOHandler::Activate(); if (!m_app_ap) { - m_app_ap.reset(new Application(GetInputFILE(), GetOutputFILE())); + m_app_ap = std::make_unique<Application>(GetInputFILE(), GetOutputFILE()); // This is both a window and a menu delegate std::shared_ptr<ApplicationDelegate> app_delegate_sp( diff --git a/lldb/source/Core/Mangled.cpp b/lldb/source/Core/Mangled.cpp index 15baffd212af..143ec8770bf4 100644 --- a/lldb/source/Core/Mangled.cpp +++ b/lldb/source/Core/Mangled.cpp @@ -1,4 +1,4 @@ -//===-- Mangled.cpp ---------------------------------------------*- C++ -*-===// +//===-- Mangled.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -142,9 +142,8 @@ void Mangled::Clear() { // Compare the string values. int Mangled::Compare(const Mangled &a, const Mangled &b) { - return ConstString::Compare( - a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), - b.GetName(lldb::eLanguageTypeUnknown, ePreferMangled)); + return ConstString::Compare(a.GetName(ePreferMangled), + b.GetName(ePreferMangled)); } // Set the string value in this objects. If "mangled" is true, then the mangled @@ -182,7 +181,7 @@ void Mangled::SetValue(ConstString name) { // Local helpers for different demangling implementations. static char *GetMSVCDemangledStr(const char *M) { char *demangled_cstr = llvm::microsoftDemangle( - M, nullptr, nullptr, nullptr, + M, nullptr, nullptr, nullptr, nullptr, llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention | llvm::MSDF_NoMemberType)); @@ -295,8 +294,7 @@ bool Mangled::DemangleWithRichManglingInfo( // class will need to use this accessor if it wishes to decode the demangled // name. The result is cached and will be kept until a new string value is // supplied to this object, or until the end of the object's lifetime. -ConstString -Mangled::GetDemangledName(lldb::LanguageType language) const { +ConstString Mangled::GetDemangledName() const { // Check to make sure we have a valid mangled name and that we haven't // already decoded our mangled name. if (m_mangled && m_demangled.IsNull()) { @@ -341,26 +339,24 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { } ConstString -Mangled::GetDisplayDemangledName(lldb::LanguageType language) const { - return GetDemangledName(language); +Mangled::GetDisplayDemangledName() const { + return GetDemangledName(); } -bool Mangled::NameMatches(const RegularExpression ®ex, - lldb::LanguageType language) const { - if (m_mangled && regex.Execute(m_mangled.AsCString())) +bool Mangled::NameMatches(const RegularExpression ®ex) const { + if (m_mangled && regex.Execute(m_mangled.GetStringRef())) return true; - ConstString demangled = GetDemangledName(language); - return demangled && regex.Execute(demangled.AsCString()); + ConstString demangled = GetDemangledName(); + return demangled && regex.Execute(demangled.GetStringRef()); } // Get the demangled name if there is one, else return the mangled name. -ConstString Mangled::GetName(lldb::LanguageType language, - Mangled::NamePreference preference) const { +ConstString Mangled::GetName(Mangled::NamePreference preference) const { if (preference == ePreferMangled && m_mangled) return m_mangled; - ConstString demangled = GetDemangledName(language); + ConstString demangled = GetDemangledName(); if (preference == ePreferDemangledWithoutArguments) { return get_demangled_name_without_arguments(m_mangled, demangled); @@ -417,12 +413,10 @@ lldb::LanguageType Mangled::GuessLanguage() const { const char *mangled_name = mangled.GetCString(); if (CPlusPlusLanguage::IsCPPMangledName(mangled_name)) return lldb::eLanguageTypeC_plus_plus; - else if (ObjCLanguage::IsPossibleObjCMethodName(mangled_name)) - return lldb::eLanguageTypeObjC; } else { // ObjC names aren't really mangled, so they won't necessarily be in the // mangled name slot. - ConstString demangled_name = GetDemangledName(lldb::eLanguageTypeUnknown); + ConstString demangled_name = GetDemangledName(); if (demangled_name && ObjCLanguage::IsPossibleObjCMethodName(demangled_name.GetCString())) return lldb::eLanguageTypeObjC; @@ -436,8 +430,7 @@ Stream &operator<<(Stream &s, const Mangled &obj) { if (obj.GetMangledName()) s << "mangled = '" << obj.GetMangledName() << "'"; - ConstString demangled = - obj.GetDemangledName(lldb::eLanguageTypeUnknown); + ConstString demangled = obj.GetDemangledName(); if (demangled) s << ", demangled = '" << demangled << '\''; else diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 031892abdd24..b76659ee3e07 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1,4 +1,4 @@ -//===-- Module.cpp ----------------------------------------------*- C++ -*-===// +//===-- Module.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,6 +18,7 @@ #include "lldb/Core/Section.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" +#include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/CompileUnit.h" @@ -33,7 +34,6 @@ #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Language.h" -#include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" @@ -147,11 +147,16 @@ Module::Module(const ModuleSpec &module_spec) : module_spec.GetObjectName().AsCString(""), module_spec.GetObjectName().IsEmpty() ? "" : ")"); + auto data_sp = module_spec.GetData(); + lldb::offset_t file_size = 0; + if (data_sp) + file_size = data_sp->GetByteSize(); + // First extract all module specifications from the file using the local file // path. If there are no specifications, then don't fill anything in ModuleSpecList modules_specs; - if (ObjectFile::GetModuleSpecifications(module_spec.GetFileSpec(), 0, 0, - modules_specs) == 0) + if (ObjectFile::GetModuleSpecifications( + module_spec.GetFileSpec(), 0, file_size, modules_specs, data_sp) == 0) return; // Now make sure that one of the module specifications matches what we just @@ -170,11 +175,20 @@ Module::Module(const ModuleSpec &module_spec) return; } - if (module_spec.GetFileSpec()) - m_mod_time = FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec()); - else if (matching_module_spec.GetFileSpec()) - m_mod_time = - FileSystem::Instance().GetModificationTime(matching_module_spec.GetFileSpec()); + // Set m_data_sp if it was initially provided in the ModuleSpec. Note that + // we cannot use the data_sp variable here, because it will have been + // modified by GetModuleSpecifications(). + if (auto module_spec_data_sp = module_spec.GetData()) { + m_data_sp = module_spec_data_sp; + m_mod_time = {}; + } else { + if (module_spec.GetFileSpec()) + m_mod_time = + FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec()); + else if (matching_module_spec.GetFileSpec()) + m_mod_time = FileSystem::Instance().GetModificationTime( + matching_module_spec.GetFileSpec()); + } // Copy the architecture from the actual spec if we got one back, else use // the one that was specified @@ -297,7 +311,9 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp, const size_t bytes_read = process_sp->ReadMemory(header_addr, data_up->GetBytes(), data_up->GetByteSize(), readmem_error); - if (bytes_read == size_to_read) { + if (bytes_read < size_to_read) + data_up->SetByteSize(bytes_read); + if (data_up->GetByteSize() > 0) { DataBufferSP data_sp(data_up.release()); m_objfile_sp = ObjectFile::FindPlugin(shared_from_this(), process_sp, header_addr, data_sp); @@ -364,11 +380,11 @@ void Module::ParseAllDebugSymbols() { if (num_comp_units == 0) return; - SymbolContext sc; - sc.module_sp = shared_from_this(); SymbolFile *symbols = GetSymbolFile(); for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) { + SymbolContext sc; + sc.module_sp = shared_from_this(); sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get(); if (!sc.comp_unit) continue; @@ -595,7 +611,7 @@ uint32_t Module::ResolveSymbolContextsForFileSpec( } void Module::FindGlobalVariables(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, size_t max_matches, VariableList &variables) { if (SymbolFile *symbols = GetSymbolFile()) symbols->FindGlobalVariables(name, parent_decl_ctx, max_matches, variables); @@ -783,7 +799,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, } void Module::FindFunctions(ConstString name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, bool include_symbols, bool include_inlines, SymbolContextList &sc_list) { @@ -920,7 +936,7 @@ void Module::FindAddressesForLine(const lldb::TargetSP target_sp, } void Module::FindTypes_Impl( - ConstString name, const CompilerDeclContext *parent_decl_ctx, + ConstString name, const CompilerDeclContext &parent_decl_ctx, size_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { @@ -932,7 +948,7 @@ void Module::FindTypes_Impl( } void Module::FindTypesInNamespace(ConstString type_name, - const CompilerDeclContext *parent_decl_ctx, + const CompilerDeclContext &parent_decl_ctx, size_t max_matches, TypeList &type_list) { TypeMap types_map; llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files; @@ -974,10 +990,11 @@ void Module::FindTypes( exact_match = type_scope.consume_front("::"); ConstString type_basename_const_str(type_basename); - FindTypes_Impl(type_basename_const_str, nullptr, max_matches, + FindTypes_Impl(type_basename_const_str, CompilerDeclContext(), max_matches, searched_symbol_files, typesmap); if (typesmap.GetSize()) - typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, + typesmap.RemoveMismatchedTypes(std::string(type_scope), + std::string(type_basename), type_class, exact_match); } else { // The type is not in a namespace/class scope, just search for it by @@ -985,16 +1002,18 @@ void Module::FindTypes( if (type_class != eTypeClassAny && !type_basename.empty()) { // The "type_name_cstr" will have been modified if we have a valid type // class prefix (like "struct", "class", "union", "typedef" etc). - FindTypes_Impl(ConstString(type_basename), nullptr, UINT_MAX, - searched_symbol_files, typesmap); - typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, + FindTypes_Impl(ConstString(type_basename), CompilerDeclContext(), + UINT_MAX, searched_symbol_files, typesmap); + typesmap.RemoveMismatchedTypes(std::string(type_scope), + std::string(type_basename), type_class, exact_match); } else { - FindTypes_Impl(name, nullptr, UINT_MAX, searched_symbol_files, typesmap); + FindTypes_Impl(name, CompilerDeclContext(), UINT_MAX, + searched_symbol_files, typesmap); if (exact_match) { std::string name_str(name.AsCString("")); - typesmap.RemoveMismatchedTypes(type_scope, name_str, type_class, - exact_match); + typesmap.RemoveMismatchedTypes(std::string(type_scope), name_str, + type_class, exact_match); } } } @@ -1105,6 +1124,10 @@ void Module::ReportError(const char *format, ...) { } bool Module::FileHasChanged() const { + // We have provided the DataBuffer for this module to avoid accessing the + // filesystem. We never want to reload those files. + if (m_data_sp) + return false; if (!m_file_has_changed) m_file_has_changed = (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time); @@ -1224,12 +1247,19 @@ ObjectFile *Module::GetObjectFile() { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "Module::GetObjectFile () module = %s", GetFileSpec().GetFilename().AsCString("")); - DataBufferSP data_sp; lldb::offset_t data_offset = 0; - const lldb::offset_t file_size = - FileSystem::Instance().GetByteSize(m_file); + lldb::offset_t file_size = 0; + + if (m_data_sp) + file_size = m_data_sp->GetByteSize(); + else if (m_file) + file_size = FileSystem::Instance().GetByteSize(m_file); + if (file_size > m_object_offset) { m_did_load_objfile = true; + // FindPlugin will modify its data_sp argument. Do not let it + // modify our m_data_sp member. + auto data_sp = m_data_sp; m_objfile_sp = ObjectFile::FindPlugin( shared_from_this(), &m_file, m_object_offset, file_size - m_object_offset, data_sp, data_offset); @@ -1409,7 +1439,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) { if (FileSystem::Instance().IsDirectory(file)) { std::string new_path(file.GetPath()); std::string old_path(obj_file->GetFileSpec().GetPath()); - if (old_path.find(new_path) == 0) { + if (llvm::StringRef(old_path).startswith(new_path)) { // We specified the same bundle as the symbol file that we already // have return; @@ -1591,6 +1621,19 @@ bool Module::RemapSourceFile(llvm::StringRef path, return m_source_mappings.RemapPath(path, new_path); } +void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) { + XcodeSDK sdk(sdk_name.str()); + ConstString sdk_path(HostInfo::GetXcodeSDKPath(sdk)); + if (!sdk_path) + return; + // If the SDK changed for a previously registered source path, update it. + // This could happend with -fdebug-prefix-map, otherwise it's unlikely. + ConstString sysroot_cs(sysroot); + if (!m_source_mappings.Replace(sysroot_cs, sdk_path, true)) + // In the general case, however, append it to the list. + m_source_mappings.Append(sysroot_cs, sdk_path, false); +} + bool Module::MergeArchitecture(const ArchSpec &arch_spec) { if (!arch_spec.IsValid()) return false; diff --git a/lldb/source/Core/ModuleChild.cpp b/lldb/source/Core/ModuleChild.cpp index 2fcb2ffca137..6e04bb4589e3 100644 --- a/lldb/source/Core/ModuleChild.cpp +++ b/lldb/source/Core/ModuleChild.cpp @@ -1,4 +1,4 @@ -//===-- ModuleChild.cpp -----------------------------------------*- C++ -*-===// +//===-- ModuleChild.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/ModuleList.cpp b/lldb/source/Core/ModuleList.cpp index 07100bb81dca..0345678ddaff 100644 --- a/lldb/source/Core/ModuleList.cpp +++ b/lldb/source/Core/ModuleList.cpp @@ -1,4 +1,4 @@ -//===-- ModuleList.cpp ------------------------------------------*- C++ -*-===// +//===-- ModuleList.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -12,6 +12,7 @@ #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/OptionValueFileSpec.h" +#include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" #include "lldb/Symbol/LocateSymbolFile.h" @@ -77,6 +78,8 @@ ModuleListProperties::ModuleListProperties() { m_collection_sp = std::make_shared<OptionValueProperties>(ConstString("symbols")); m_collection_sp->Initialize(g_modulelist_properties); + m_collection_sp->SetValueChangedCallback(ePropertySymLinkPaths, + [this] { UpdateSymlinkMappings(); }); llvm::SmallString<128> path; clang::driver::Driver::getDefaultModuleCachePath(path); @@ -106,6 +109,28 @@ bool ModuleListProperties::SetClangModulesCachePath(llvm::StringRef path) { nullptr, ePropertyClangModulesCachePath, path); } +void ModuleListProperties::UpdateSymlinkMappings() { + FileSpecList list = m_collection_sp + ->GetPropertyAtIndexAsOptionValueFileSpecList( + nullptr, false, ePropertySymLinkPaths) + ->GetCurrentValue(); + llvm::sys::ScopedWriter lock(m_symlink_paths_mutex); + const bool notify = false; + m_symlink_paths.Clear(notify); + for (FileSpec symlink : list) { + FileSpec resolved; + Status status = FileSystem::Instance().Readlink(symlink, resolved); + if (status.Success()) + m_symlink_paths.Append(ConstString(symlink.GetPath()), + ConstString(resolved.GetPath()), notify); + } +} + +PathMappingList ModuleListProperties::GetSymlinkMappings() const { + llvm::sys::ScopedReader lock(m_symlink_paths_mutex); + return m_symlink_paths; +} + ModuleList::ModuleList() : m_modules(), m_modules_mutex(), m_notifier(nullptr) {} @@ -338,7 +363,7 @@ void ModuleList::FindFunctions(ConstString name, std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctions(lookup_info.GetLookupName(), nullptr, + (*pos)->FindFunctions(lookup_info.GetLookupName(), CompilerDeclContext(), lookup_info.GetNameTypeMask(), include_symbols, include_inlines, sc_list); } @@ -351,8 +376,8 @@ void ModuleList::FindFunctions(ConstString name, std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindFunctions(name, nullptr, name_type_mask, include_symbols, - include_inlines, sc_list); + (*pos)->FindFunctions(name, CompilerDeclContext(), name_type_mask, + include_symbols, include_inlines, sc_list); } } } @@ -409,7 +434,8 @@ void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches, std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { - (*pos)->FindGlobalVariables(name, nullptr, max_matches, variable_list); + (*pos)->FindGlobalVariables(name, CompilerDeclContext(), max_matches, + variable_list); } } @@ -565,10 +591,6 @@ size_t ModuleList::GetSize() const { } void ModuleList::Dump(Stream *s) const { - // s.Printf("%.*p: ", (int)sizeof(void*) * 2, this); - // s.Indent(); - // s << "ModuleList\n"; - std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { @@ -807,7 +829,7 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, if (!FileSystem::Instance().IsDirectory(search_path_spec)) continue; search_path_spec.AppendPathComponent( - module_spec.GetFileSpec().GetFilename().AsCString()); + module_spec.GetFileSpec().GetFilename().GetStringRef()); if (!FileSystem::Instance().Exists(search_path_spec)) continue; diff --git a/lldb/source/Core/Opcode.cpp b/lldb/source/Core/Opcode.cpp index 6ca46de40de2..b544064b061e 100644 --- a/lldb/source/Core/Opcode.cpp +++ b/lldb/source/Core/Opcode.cpp @@ -1,4 +1,4 @@ -//===-- Opcode.cpp ----------------------------------------------*- C++ -*-===// +//===-- Opcode.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp index e8bfef724378..3545ef66cc38 100644 --- a/lldb/source/Core/PluginManager.cpp +++ b/lldb/source/Core/PluginManager.cpp @@ -1,4 +1,4 @@ -//===-- PluginManager.cpp ---------------------------------------*- C++ -*-===// +//===-- PluginManager.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,38 +16,24 @@ #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StringList.h" - -#if defined(_WIN32) -#include "lldb/Host/windows/PosixApi.h" -#endif - #include "llvm/ADT/StringRef.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/raw_ostream.h" - +#include <assert.h> #include <map> #include <memory> #include <mutex> #include <string> #include <utility> #include <vector> - -#include <assert.h> - -namespace lldb_private { -class CommandInterpreter; -} +#if defined(_WIN32) +#include "lldb/Host/windows/PosixApi.h" +#endif using namespace lldb; using namespace lldb_private; -enum PluginAction { - ePluginRegisterInstance, - ePluginUnregisterInstance, - ePluginGetInstanceAtIndex -}; - typedef bool (*PluginInitCallback)(); typedef void (*PluginTermCallback)(); @@ -92,7 +78,6 @@ template <typename FPtrTy> static FPtrTy CastToFPtr(void *VPtr) { static FileSystem::EnumerateDirectoryResult LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, llvm::StringRef path) { - // PluginManager *plugin_manager = (PluginManager *)baton; Status error; namespace fs = llvm::sys::fs; @@ -156,7 +141,6 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, } void PluginManager::Initialize() { -#if 1 const bool find_directories = true; const bool find_files = true; const bool find_other = true; @@ -178,7 +162,6 @@ void PluginManager::Initialize() { LoadPluginCallback, nullptr); } } -#endif } void PluginManager::Terminate() { @@ -197,99 +180,127 @@ void PluginManager::Terminate() { plugin_map.clear(); } -#pragma mark ABI +template <typename Callback> struct PluginInstance { + typedef Callback CallbackType; -struct ABIInstance { - ABIInstance() : name(), description(), create_callback(nullptr) {} + PluginInstance() = default; + PluginInstance(ConstString name, std::string description, + Callback create_callback = nullptr, + DebuggerInitializeCallback debugger_init_callback = nullptr) + : name(name), description(std::move(description)), + create_callback(create_callback), + debugger_init_callback(debugger_init_callback) {} ConstString name; std::string description; - ABICreateInstance create_callback; + Callback create_callback; + DebuggerInitializeCallback debugger_init_callback; }; -typedef std::vector<ABIInstance> ABIInstances; +template <typename Instance> class PluginInstances { +public: + template <typename... Args> + bool RegisterPlugin(ConstString name, const char *description, + typename Instance::CallbackType callback, + Args &&... args) { + if (!callback) + return false; + assert((bool)name); + Instance instance = + Instance(name, description, callback, std::forward<Args>(args)...); + m_instances.push_back(instance); + return false; + } -static std::recursive_mutex &GetABIInstancesMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} + bool UnregisterPlugin(typename Instance::CallbackType callback) { + if (!callback) + return false; + auto pos = m_instances.begin(); + auto end = m_instances.end(); + for (; pos != end; ++pos) { + if (pos->create_callback == callback) { + m_instances.erase(pos); + return true; + } + } + return false; + } + + typename Instance::CallbackType GetCallbackAtIndex(uint32_t idx) { + if (Instance *instance = GetInstanceAtIndex(idx)) + return instance->create_callback; + return nullptr; + } + + const char *GetDescriptionAtIndex(uint32_t idx) { + if (Instance *instance = GetInstanceAtIndex(idx)) + return instance->description.c_str(); + return nullptr; + } + + const char *GetNameAtIndex(uint32_t idx) { + if (Instance *instance = GetInstanceAtIndex(idx)) + return instance->name.GetCString(); + return nullptr; + } + + typename Instance::CallbackType GetCallbackForName(ConstString name) { + if (!name) + return nullptr; + for (auto &instance : m_instances) { + if (name == instance.name) + return instance.create_callback; + } + return nullptr; + } + + void PerformDebuggerCallback(Debugger &debugger) { + for (auto &instance : m_instances) { + if (instance.debugger_init_callback) + instance.debugger_init_callback(debugger); + } + } + + const std::vector<Instance> &GetInstances() const { return m_instances; } + std::vector<Instance> &GetInstances() { return m_instances; } + +private: + Instance *GetInstanceAtIndex(uint32_t idx) { + if (idx < m_instances.size()) + return &m_instances[idx]; + return nullptr; + } + std::vector<Instance> m_instances; +}; + +#pragma mark ABI + +typedef PluginInstance<ABICreateInstance> ABIInstance; +typedef PluginInstances<ABIInstance> ABIInstances; static ABIInstances &GetABIInstances() { static ABIInstances g_instances; return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, +bool PluginManager::RegisterPlugin(ConstString name, const char *description, ABICreateInstance create_callback) { - if (create_callback) { - ABIInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex()); - GetABIInstances().push_back(instance); - return true; - } - return false; + return GetABIInstances().RegisterPlugin(name, description, create_callback); } bool PluginManager::UnregisterPlugin(ABICreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex()); - ABIInstances &instances = GetABIInstances(); - - ABIInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetABIInstances().UnregisterPlugin(create_callback); } ABICreateInstance PluginManager::GetABICreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex()); - ABIInstances &instances = GetABIInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -ABICreateInstance -PluginManager::GetABICreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetABIInstancesMutex()); - ABIInstances &instances = GetABIInstances(); - - ABIInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetABIInstances().GetCallbackAtIndex(idx); } #pragma mark Architecture -struct ArchitectureInstance { - ConstString name; - std::string description; - PluginManager::ArchitectureCreateInstance create_callback; -}; - +typedef PluginInstance<ArchitectureCreateInstance> ArchitectureInstance; typedef std::vector<ArchitectureInstance> ArchitectureInstances; -static std::mutex &GetArchitectureMutex() { - static std::mutex g_architecture_mutex; - return g_architecture_mutex; -} - static ArchitectureInstances &GetArchitectureInstances() { static ArchitectureInstances g_instances; return g_instances; @@ -298,13 +309,12 @@ static ArchitectureInstances &GetArchitectureInstances() { void PluginManager::RegisterPlugin(ConstString name, llvm::StringRef description, ArchitectureCreateInstance create_callback) { - std::lock_guard<std::mutex> guard(GetArchitectureMutex()); - GetArchitectureInstances().push_back({name, description, create_callback}); + GetArchitectureInstances().push_back( + {name, std::string(description), create_callback}); } void PluginManager::UnregisterPlugin( ArchitectureCreateInstance create_callback) { - std::lock_guard<std::mutex> guard(GetArchitectureMutex()); auto &instances = GetArchitectureInstances(); for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) { @@ -318,7 +328,6 @@ void PluginManager::UnregisterPlugin( std::unique_ptr<Architecture> PluginManager::CreateArchitectureInstance(const ArchSpec &arch) { - std::lock_guard<std::mutex> guard(GetArchitectureMutex()); for (const auto &instances : GetArchitectureInstances()) { if (auto plugin_up = instances.create_callback(arch)) return plugin_up; @@ -328,104 +337,39 @@ PluginManager::CreateArchitectureInstance(const ArchSpec &arch) { #pragma mark Disassembler -struct DisassemblerInstance { - DisassemblerInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - DisassemblerCreateInstance create_callback; -}; - -typedef std::vector<DisassemblerInstance> DisassemblerInstances; - -static std::recursive_mutex &GetDisassemblerMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<DisassemblerCreateInstance> DisassemblerInstance; +typedef PluginInstances<DisassemblerInstance> DisassemblerInstances; static DisassemblerInstances &GetDisassemblerInstances() { static DisassemblerInstances g_instances; return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, +bool PluginManager::RegisterPlugin(ConstString name, const char *description, DisassemblerCreateInstance create_callback) { - if (create_callback) { - DisassemblerInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex()); - GetDisassemblerInstances().push_back(instance); - return true; - } - return false; + return GetDisassemblerInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( DisassemblerCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex()); - DisassemblerInstances &instances = GetDisassemblerInstances(); - - DisassemblerInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetDisassemblerInstances().UnregisterPlugin(create_callback); } DisassemblerCreateInstance PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex()); - DisassemblerInstances &instances = GetDisassemblerInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetDisassemblerInstances().GetCallbackAtIndex(idx); } DisassemblerCreateInstance -PluginManager::GetDisassemblerCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetDisassemblerMutex()); - DisassemblerInstances &instances = GetDisassemblerInstances(); - - DisassemblerInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; +PluginManager::GetDisassemblerCreateCallbackForPluginName(ConstString name) { + return GetDisassemblerInstances().GetCallbackForName(name); } #pragma mark DynamicLoader -struct DynamicLoaderInstance { - DynamicLoaderInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - DynamicLoaderCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector<DynamicLoaderInstance> DynamicLoaderInstances; - -static std::recursive_mutex &GetDynamicLoaderMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<DynamicLoaderCreateInstance> DynamicLoaderInstance; +typedef PluginInstances<DynamicLoaderInstance> DynamicLoaderInstances; static DynamicLoaderInstances &GetDynamicLoaderInstances() { static DynamicLoaderInstances g_instances; @@ -436,81 +380,29 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, DynamicLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - DynamicLoaderInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); - GetDynamicLoaderInstances().push_back(instance); - } - return false; + return GetDynamicLoaderInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } bool PluginManager::UnregisterPlugin( DynamicLoaderCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); - DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); - - DynamicLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetDynamicLoaderInstances().UnregisterPlugin(create_callback); } DynamicLoaderCreateInstance PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); - DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetDynamicLoaderInstances().GetCallbackAtIndex(idx); } DynamicLoaderCreateInstance -PluginManager::GetDynamicLoaderCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); - DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); - - DynamicLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; +PluginManager::GetDynamicLoaderCreateCallbackForPluginName(ConstString name) { + return GetDynamicLoaderInstances().GetCallbackForName(name); } #pragma mark JITLoader -struct JITLoaderInstance { - JITLoaderInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - JITLoaderCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector<JITLoaderInstance> JITLoaderInstances; - -static std::recursive_mutex &GetJITLoaderMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<JITLoaderCreateInstance> JITLoaderInstance; +typedef PluginInstances<JITLoaderInstance> JITLoaderInstances; static JITLoaderInstances &GetJITLoaderInstances() { static JITLoaderInstances g_instances; @@ -521,77 +413,24 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, JITLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - JITLoaderInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); - GetJITLoaderInstances().push_back(instance); - } - return false; + return GetJITLoaderInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } bool PluginManager::UnregisterPlugin(JITLoaderCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); - JITLoaderInstances &instances = GetJITLoaderInstances(); - - JITLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetJITLoaderInstances().UnregisterPlugin(create_callback); } JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); - JITLoaderInstances &instances = GetJITLoaderInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -JITLoaderCreateInstance PluginManager::GetJITLoaderCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); - JITLoaderInstances &instances = GetJITLoaderInstances(); - - JITLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetJITLoaderInstances().GetCallbackAtIndex(idx); } #pragma mark EmulateInstruction -struct EmulateInstructionInstance { - EmulateInstructionInstance() - : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - EmulateInstructionCreateInstance create_callback; -}; - -typedef std::vector<EmulateInstructionInstance> EmulateInstructionInstances; - -static std::recursive_mutex &GetEmulateInstructionMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<EmulateInstructionCreateInstance> + EmulateInstructionInstance; +typedef PluginInstances<EmulateInstructionInstance> EmulateInstructionInstances; static EmulateInstructionInstances &GetEmulateInstructionInstances() { static EmulateInstructionInstances g_instances; @@ -601,80 +440,30 @@ static EmulateInstructionInstances &GetEmulateInstructionInstances() { bool PluginManager::RegisterPlugin( ConstString name, const char *description, EmulateInstructionCreateInstance create_callback) { - if (create_callback) { - EmulateInstructionInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex()); - GetEmulateInstructionInstances().push_back(instance); - } - return false; + return GetEmulateInstructionInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( EmulateInstructionCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex()); - EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); - - EmulateInstructionInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetEmulateInstructionInstances().UnregisterPlugin(create_callback); } EmulateInstructionCreateInstance PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex()); - EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetEmulateInstructionInstances().GetCallbackAtIndex(idx); } EmulateInstructionCreateInstance PluginManager::GetEmulateInstructionCreateCallbackForPluginName( ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetEmulateInstructionMutex()); - EmulateInstructionInstances &instances = GetEmulateInstructionInstances(); - - EmulateInstructionInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetEmulateInstructionInstances().GetCallbackForName(name); } #pragma mark OperatingSystem -struct OperatingSystemInstance { - OperatingSystemInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - OperatingSystemCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector<OperatingSystemInstance> OperatingSystemInstances; - -static std::recursive_mutex &GetOperatingSystemMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<OperatingSystemCreateInstance> OperatingSystemInstance; +typedef PluginInstances<OperatingSystemInstance> OperatingSystemInstances; static OperatingSystemInstances &GetOperatingSystemInstances() { static OperatingSystemInstances g_instances; @@ -685,158 +474,70 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, OperatingSystemCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - OperatingSystemInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); - GetOperatingSystemInstances().push_back(instance); - } - return false; + return GetOperatingSystemInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } bool PluginManager::UnregisterPlugin( OperatingSystemCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); - OperatingSystemInstances &instances = GetOperatingSystemInstances(); - - OperatingSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetOperatingSystemInstances().UnregisterPlugin(create_callback); } OperatingSystemCreateInstance PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); - OperatingSystemInstances &instances = GetOperatingSystemInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetOperatingSystemInstances().GetCallbackAtIndex(idx); } OperatingSystemCreateInstance -PluginManager::GetOperatingSystemCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); - OperatingSystemInstances &instances = GetOperatingSystemInstances(); - - OperatingSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; +PluginManager::GetOperatingSystemCreateCallbackForPluginName(ConstString name) { + return GetOperatingSystemInstances().GetCallbackForName(name); } #pragma mark Language -struct LanguageInstance { - LanguageInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - LanguageCreateInstance create_callback; -}; - -typedef std::vector<LanguageInstance> LanguageInstances; - -static std::recursive_mutex &GetLanguageMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<LanguageCreateInstance> LanguageInstance; +typedef PluginInstances<LanguageInstance> LanguageInstances; static LanguageInstances &GetLanguageInstances() { static LanguageInstances g_instances; return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, +bool PluginManager::RegisterPlugin(ConstString name, const char *description, LanguageCreateInstance create_callback) { - if (create_callback) { - LanguageInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex()); - GetLanguageInstances().push_back(instance); - } - return false; + return GetLanguageInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin(LanguageCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex()); - LanguageInstances &instances = GetLanguageInstances(); - - LanguageInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetLanguageInstances().UnregisterPlugin(create_callback); } LanguageCreateInstance PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex()); - LanguageInstances &instances = GetLanguageInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -LanguageCreateInstance -PluginManager::GetLanguageCreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetLanguageMutex()); - LanguageInstances &instances = GetLanguageInstances(); - - LanguageInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetLanguageInstances().GetCallbackAtIndex(idx); } #pragma mark LanguageRuntime -struct LanguageRuntimeInstance { - LanguageRuntimeInstance() : name(), description(), create_callback(nullptr) {} +struct LanguageRuntimeInstance + : public PluginInstance<LanguageRuntimeCreateInstance> { + LanguageRuntimeInstance( + ConstString name, std::string description, CallbackType create_callback, + DebuggerInitializeCallback debugger_init_callback, + LanguageRuntimeGetCommandObject command_callback, + LanguageRuntimeGetExceptionPrecondition precondition_callback) + : PluginInstance<LanguageRuntimeCreateInstance>( + name, std::move(description), create_callback, + debugger_init_callback), + command_callback(command_callback), + precondition_callback(precondition_callback) {} - ConstString name; - std::string description; - LanguageRuntimeCreateInstance create_callback; LanguageRuntimeGetCommandObject command_callback; LanguageRuntimeGetExceptionPrecondition precondition_callback; }; -typedef std::vector<LanguageRuntimeInstance> LanguageRuntimeInstances; - -static std::recursive_mutex &GetLanguageRuntimeMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances<LanguageRuntimeInstance> LanguageRuntimeInstances; static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { static LanguageRuntimeInstances g_instances; @@ -848,51 +549,24 @@ bool PluginManager::RegisterPlugin( LanguageRuntimeCreateInstance create_callback, LanguageRuntimeGetCommandObject command_callback, LanguageRuntimeGetExceptionPrecondition precondition_callback) { - if (create_callback) { - LanguageRuntimeInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.command_callback = command_callback; - instance.precondition_callback = precondition_callback; - std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); - GetLanguageRuntimeInstances().push_back(instance); - } - return false; + return GetLanguageRuntimeInstances().RegisterPlugin( + name, description, create_callback, nullptr, command_callback, + precondition_callback); } bool PluginManager::UnregisterPlugin( LanguageRuntimeCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); - - LanguageRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetLanguageRuntimeInstances().UnregisterPlugin(create_callback); } LanguageRuntimeCreateInstance PluginManager::GetLanguageRuntimeCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetLanguageRuntimeInstances().GetCallbackAtIndex(idx); } LanguageRuntimeGetCommandObject PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); + const auto &instances = GetLanguageRuntimeInstances().GetInstances(); if (idx < instances.size()) return instances[idx].command_callback; return nullptr; @@ -900,45 +574,16 @@ PluginManager::GetLanguageRuntimeGetCommandObjectAtIndex(uint32_t idx) { LanguageRuntimeGetExceptionPrecondition PluginManager::GetLanguageRuntimeGetExceptionPreconditionAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); + const auto &instances = GetLanguageRuntimeInstances().GetInstances(); if (idx < instances.size()) return instances[idx].precondition_callback; return nullptr; } -LanguageRuntimeCreateInstance -PluginManager::GetLanguageRuntimeCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetLanguageRuntimeMutex()); - LanguageRuntimeInstances &instances = GetLanguageRuntimeInstances(); - - LanguageRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; -} - #pragma mark SystemRuntime -struct SystemRuntimeInstance { - SystemRuntimeInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - SystemRuntimeCreateInstance create_callback; -}; - -typedef std::vector<SystemRuntimeInstance> SystemRuntimeInstances; - -static std::recursive_mutex &GetSystemRuntimeMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<SystemRuntimeCreateInstance> SystemRuntimeInstance; +typedef PluginInstances<SystemRuntimeInstance> SystemRuntimeInstances; static SystemRuntimeInstances &GetSystemRuntimeInstances() { static SystemRuntimeInstances g_instances; @@ -948,83 +593,39 @@ static SystemRuntimeInstances &GetSystemRuntimeInstances() { bool PluginManager::RegisterPlugin( ConstString name, const char *description, SystemRuntimeCreateInstance create_callback) { - if (create_callback) { - SystemRuntimeInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); - GetSystemRuntimeInstances().push_back(instance); - } - return false; + return GetSystemRuntimeInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( SystemRuntimeCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); - SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); - - SystemRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetSystemRuntimeInstances().UnregisterPlugin(create_callback); } SystemRuntimeCreateInstance PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); - SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -SystemRuntimeCreateInstance -PluginManager::GetSystemRuntimeCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetSystemRuntimeMutex()); - SystemRuntimeInstances &instances = GetSystemRuntimeInstances(); - - SystemRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetSystemRuntimeInstances().GetCallbackAtIndex(idx); } #pragma mark ObjectFile -struct ObjectFileInstance { - ObjectFileInstance() - : name(), description(), create_callback(nullptr), - create_memory_callback(nullptr), get_module_specifications(nullptr), - save_core(nullptr) {} +struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> { + ObjectFileInstance( + ConstString name, std::string description, CallbackType create_callback, + ObjectFileCreateMemoryInstance create_memory_callback, + ObjectFileGetModuleSpecifications get_module_specifications, + ObjectFileSaveCore save_core) + : PluginInstance<ObjectFileCreateInstance>(name, std::move(description), + create_callback), + create_memory_callback(create_memory_callback), + get_module_specifications(get_module_specifications), + save_core(save_core) {} - ConstString name; - std::string description; - ObjectFileCreateInstance create_callback; ObjectFileCreateMemoryInstance create_memory_callback; ObjectFileGetModuleSpecifications get_module_specifications; ObjectFileSaveCore save_core; }; - -typedef std::vector<ObjectFileInstance> ObjectFileInstances; - -static std::recursive_mutex &GetObjectFileMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances<ObjectFileInstance> ObjectFileInstances; static ObjectFileInstances &GetObjectFileInstances() { static ObjectFileInstances g_instances; @@ -1037,51 +638,23 @@ bool PluginManager::RegisterPlugin( ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, ObjectFileSaveCore save_core) { - if (create_callback) { - ObjectFileInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.create_memory_callback = create_memory_callback; - instance.save_core = save_core; - instance.get_module_specifications = get_module_specifications; - std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); - GetObjectFileInstances().push_back(instance); - } - return false; + return GetObjectFileInstances().RegisterPlugin( + name, description, create_callback, create_memory_callback, + get_module_specifications, save_core); } bool PluginManager::UnregisterPlugin(ObjectFileCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - - ObjectFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetObjectFileInstances().UnregisterPlugin(create_callback); } ObjectFileCreateInstance PluginManager::GetObjectFileCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetObjectFileInstances().GetCallbackAtIndex(idx); } ObjectFileCreateMemoryInstance PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); + const auto &instances = GetObjectFileInstances().GetInstances(); if (idx < instances.size()) return instances[idx].create_memory_callback; return nullptr; @@ -1090,41 +663,21 @@ PluginManager::GetObjectFileCreateMemoryCallbackAtIndex(uint32_t idx) { ObjectFileGetModuleSpecifications PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex( uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); + const auto &instances = GetObjectFileInstances().GetInstances(); if (idx < instances.size()) return instances[idx].get_module_specifications; return nullptr; } -ObjectFileCreateInstance -PluginManager::GetObjectFileCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - - ObjectFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; -} - ObjectFileCreateMemoryInstance PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - - ObjectFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_memory_callback; - } + if (!name) + return nullptr; + const auto &instances = GetObjectFileInstances().GetInstances(); + for (auto &instance : instances) { + if (instance.name == name) + return instance.create_memory_callback; } return nullptr; } @@ -1132,12 +685,9 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, const FileSpec &outfile) { Status error; - std::lock_guard<std::recursive_mutex> guard(GetObjectFileMutex()); - ObjectFileInstances &instances = GetObjectFileInstances(); - - ObjectFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->save_core && pos->save_core(process_sp, outfile, error)) + auto &instances = GetObjectFileInstances().GetInstances(); + for (auto &instance : instances) { + if (instance.save_core && instance.save_core(process_sp, outfile, error)) return error; } error.SetErrorString( @@ -1147,23 +697,18 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, #pragma mark ObjectContainer -struct ObjectContainerInstance { - ObjectContainerInstance() - : name(), description(), create_callback(nullptr), - get_module_specifications(nullptr) {} +struct ObjectContainerInstance + : public PluginInstance<ObjectContainerCreateInstance> { + ObjectContainerInstance( + ConstString name, std::string description, CallbackType create_callback, + ObjectFileGetModuleSpecifications get_module_specifications) + : PluginInstance<ObjectContainerCreateInstance>( + name, std::move(description), create_callback), + get_module_specifications(get_module_specifications) {} - ConstString name; - std::string description; - ObjectContainerCreateInstance create_callback; ObjectFileGetModuleSpecifications get_module_specifications; }; - -typedef std::vector<ObjectContainerInstance> ObjectContainerInstances; - -static std::recursive_mutex &GetObjectContainerMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances<ObjectContainerInstance> ObjectContainerInstances; static ObjectContainerInstances &GetObjectContainerInstances() { static ObjectContainerInstances g_instances; @@ -1174,67 +719,24 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, ObjectContainerCreateInstance create_callback, ObjectFileGetModuleSpecifications get_module_specifications) { - if (create_callback) { - ObjectContainerInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.get_module_specifications = get_module_specifications; - std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); - GetObjectContainerInstances().push_back(instance); - } - return false; + return GetObjectContainerInstances().RegisterPlugin( + name, description, create_callback, get_module_specifications); } bool PluginManager::UnregisterPlugin( ObjectContainerCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); - ObjectContainerInstances &instances = GetObjectContainerInstances(); - - ObjectContainerInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetObjectContainerInstances().UnregisterPlugin(create_callback); } ObjectContainerCreateInstance PluginManager::GetObjectContainerCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); - ObjectContainerInstances &instances = GetObjectContainerInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -ObjectContainerCreateInstance -PluginManager::GetObjectContainerCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); - ObjectContainerInstances &instances = GetObjectContainerInstances(); - - ObjectContainerInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetObjectContainerInstances().GetCallbackAtIndex(idx); } ObjectFileGetModuleSpecifications PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetObjectContainerMutex()); - ObjectContainerInstances &instances = GetObjectContainerInstances(); + const auto &instances = GetObjectContainerInstances().GetInstances(); if (idx < instances.size()) return instances[idx].get_module_specifications; return nullptr; @@ -1242,23 +744,8 @@ PluginManager::GetObjectContainerGetModuleSpecificationsCallbackAtIndex( #pragma mark Platform -struct PlatformInstance { - PlatformInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - PlatformCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector<PlatformInstance> PlatformInstances; - -static std::recursive_mutex &GetPlatformInstancesMutex() { - static std::recursive_mutex g_platform_instances_mutex; - return g_platform_instances_mutex; -} +typedef PluginInstance<PlatformCreateInstance> PlatformInstance; +typedef PluginInstances<PlatformInstance> PlatformInstances; static PlatformInstances &GetPlatformInstances() { static PlatformInstances g_platform_instances; @@ -1269,114 +756,44 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, PlatformCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); + return GetPlatformInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); +} - PlatformInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - GetPlatformInstances().push_back(instance); - return true; - } - return false; +bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { + return GetPlatformInstances().UnregisterPlugin(create_callback); } const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - if (idx < instances.size()) - return instances[idx].name.GetCString(); - return nullptr; + return GetPlatformInstances().GetNameAtIndex(idx); } const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - if (idx < instances.size()) - return instances[idx].description.c_str(); - return nullptr; -} - -bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - - PlatformInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetPlatformInstances().GetDescriptionAtIndex(idx); } PlatformCreateInstance PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetPlatformInstances().GetCallbackAtIndex(idx); } PlatformCreateInstance PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - - PlatformInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetPlatformInstances().GetCallbackForName(name); } void PluginManager::AutoCompletePlatformName(llvm::StringRef name, CompletionRequest &request) { - if (name.empty()) - return; - - std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - llvm::StringRef name_sref(name); - - PlatformInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - llvm::StringRef plugin_name(pos->name.GetCString()); - if (plugin_name.startswith(name_sref)) - request.AddCompletion(plugin_name.data()); + for (const auto &instance : GetPlatformInstances().GetInstances()) { + if (instance.name.GetStringRef().startswith(name)) + request.AddCompletion(instance.name.GetCString()); } } #pragma mark Process -struct ProcessInstance { - ProcessInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - ProcessCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector<ProcessInstance> ProcessInstances; - -static std::recursive_mutex &GetProcessMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<ProcessCreateInstance> ProcessInstance; +typedef PluginInstances<ProcessInstance> ProcessInstances; static ProcessInstances &GetProcessInstances() { static ProcessInstances g_instances; @@ -1387,95 +804,55 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, ProcessCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - ProcessInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); - GetProcessInstances().push_back(instance); - } - return false; + return GetProcessInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } -const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - if (idx < instances.size()) - return instances[idx].name.GetCString(); - return nullptr; +bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { + return GetProcessInstances().UnregisterPlugin(create_callback); } -const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - if (idx < instances.size()) - return instances[idx].description.c_str(); - return nullptr; +const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { + return GetProcessInstances().GetNameAtIndex(idx); } -bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - - ProcessInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; +const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { + return GetProcessInstances().GetDescriptionAtIndex(idx); } ProcessCreateInstance PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetProcessInstances().GetCallbackAtIndex(idx); } ProcessCreateInstance PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - - ProcessInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } + return GetProcessInstances().GetCallbackForName(name); +} + +void PluginManager::AutoCompleteProcessName(llvm::StringRef name, + CompletionRequest &request) { + for (const auto &instance : GetProcessInstances().GetInstances()) { + if (instance.name.GetStringRef().startswith(name)) + request.AddCompletion(instance.name.GetCString(), instance.description); } - return nullptr; } #pragma mark ScriptInterpreter -struct ScriptInterpreterInstance { - ScriptInterpreterInstance() - : name(), language(lldb::eScriptLanguageNone), description(), - create_callback(nullptr) {} +struct ScriptInterpreterInstance + : public PluginInstance<ScriptInterpreterCreateInstance> { + ScriptInterpreterInstance(ConstString name, std::string description, + CallbackType create_callback, + lldb::ScriptLanguage language) + : PluginInstance<ScriptInterpreterCreateInstance>( + name, std::move(description), create_callback), + language(language) {} - ConstString name; - lldb::ScriptLanguage language; - std::string description; - ScriptInterpreterCreateInstance create_callback; + lldb::ScriptLanguage language = lldb::eScriptLanguageNone; }; -typedef std::vector<ScriptInterpreterInstance> ScriptInterpreterInstances; - -static std::recursive_mutex &GetScriptInterpreterMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances<ScriptInterpreterInstance> ScriptInterpreterInstances; static ScriptInterpreterInstances &GetScriptInterpreterInstances() { static ScriptInterpreterInstances g_instances; @@ -1486,61 +863,31 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, lldb::ScriptLanguage script_language, ScriptInterpreterCreateInstance create_callback) { - if (!create_callback) - return false; - ScriptInterpreterInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.language = script_language; - std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); - GetScriptInterpreterInstances().push_back(instance); - return false; + return GetScriptInterpreterInstances().RegisterPlugin( + name, description, create_callback, script_language); } bool PluginManager::UnregisterPlugin( ScriptInterpreterCreateInstance create_callback) { - if (!create_callback) - return false; - std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); - ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); - - ScriptInterpreterInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback != create_callback) - continue; - - instances.erase(pos); - return true; - } - return false; + return GetScriptInterpreterInstances().UnregisterPlugin(create_callback); } ScriptInterpreterCreateInstance PluginManager::GetScriptInterpreterCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); - ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; + return GetScriptInterpreterInstances().GetCallbackAtIndex(idx); } lldb::ScriptInterpreterSP PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, Debugger &debugger) { - std::lock_guard<std::recursive_mutex> guard(GetScriptInterpreterMutex()); - ScriptInterpreterInstances &instances = GetScriptInterpreterInstances(); - - ScriptInterpreterInstances::iterator pos, end = instances.end(); + const auto &instances = GetScriptInterpreterInstances().GetInstances(); ScriptInterpreterCreateInstance none_instance = nullptr; - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->language == lldb::eScriptLanguageNone) - none_instance = pos->create_callback; + for (const auto &instance : instances) { + if (instance.language == lldb::eScriptLanguageNone) + none_instance = instance.create_callback; - if (script_lang == pos->language) - return pos->create_callback(debugger); + if (script_lang == instance.language) + return instance.create_callback(debugger); } // If we didn't find one, return the ScriptInterpreter for the null language. @@ -1548,29 +895,24 @@ PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, return none_instance(debugger); } -#pragma mark - #pragma mark StructuredDataPlugin -// StructuredDataPlugin - -struct StructuredDataPluginInstance { - StructuredDataPluginInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr), filter_callback(nullptr) {} - - ConstString name; - std::string description; - StructuredDataPluginCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; - StructuredDataFilterLaunchInfo filter_callback; +struct StructuredDataPluginInstance + : public PluginInstance<StructuredDataPluginCreateInstance> { + StructuredDataPluginInstance( + ConstString name, std::string description, CallbackType create_callback, + DebuggerInitializeCallback debugger_init_callback, + StructuredDataFilterLaunchInfo filter_callback) + : PluginInstance<StructuredDataPluginCreateInstance>( + name, std::move(description), create_callback, + debugger_init_callback), + filter_callback(filter_callback) {} + + StructuredDataFilterLaunchInfo filter_callback = nullptr; }; -typedef std::vector<StructuredDataPluginInstance> StructuredDataPluginInstances; - -static std::recursive_mutex &GetStructuredDataPluginMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances<StructuredDataPluginInstance> + StructuredDataPluginInstances; static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { static StructuredDataPluginInstances g_instances; @@ -1582,70 +924,25 @@ bool PluginManager::RegisterPlugin( StructuredDataPluginCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback, StructuredDataFilterLaunchInfo filter_callback) { - if (create_callback) { - StructuredDataPluginInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - instance.filter_callback = filter_callback; - std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); - GetStructuredDataPluginInstances().push_back(instance); - } - return false; + return GetStructuredDataPluginInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback, + filter_callback); } bool PluginManager::UnregisterPlugin( StructuredDataPluginCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); - StructuredDataPluginInstances &instances = - GetStructuredDataPluginInstances(); - - StructuredDataPluginInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetStructuredDataPluginInstances().UnregisterPlugin(create_callback); } StructuredDataPluginCreateInstance PluginManager::GetStructuredDataPluginCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); - StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -StructuredDataPluginCreateInstance -PluginManager::GetStructuredDataPluginCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); - StructuredDataPluginInstances &instances = - GetStructuredDataPluginInstances(); - - StructuredDataPluginInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetStructuredDataPluginInstances().GetCallbackAtIndex(idx); } StructuredDataFilterLaunchInfo PluginManager::GetStructuredDataFilterCallbackAtIndex( uint32_t idx, bool &iteration_complete) { - std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); - StructuredDataPluginInstances &instances = GetStructuredDataPluginInstances(); + const auto &instances = GetStructuredDataPluginInstances().GetInstances(); if (idx < instances.size()) { iteration_complete = false; return instances[idx].filter_callback; @@ -1657,23 +954,8 @@ PluginManager::GetStructuredDataFilterCallbackAtIndex( #pragma mark SymbolFile -struct SymbolFileInstance { - SymbolFileInstance() - : name(), description(), create_callback(nullptr), - debugger_init_callback(nullptr) {} - - ConstString name; - std::string description; - SymbolFileCreateInstance create_callback; - DebuggerInitializeCallback debugger_init_callback; -}; - -typedef std::vector<SymbolFileInstance> SymbolFileInstances; - -static std::recursive_mutex &GetSymbolFileMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<SymbolFileCreateInstance> SymbolFileInstance; +typedef PluginInstances<SymbolFileInstance> SymbolFileInstances; static SymbolFileInstances &GetSymbolFileInstances() { static SymbolFileInstances g_instances; @@ -1684,157 +966,49 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, SymbolFileCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { - if (create_callback) { - SymbolFileInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.debugger_init_callback = debugger_init_callback; - std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); - GetSymbolFileInstances().push_back(instance); - } - return false; + return GetSymbolFileInstances().RegisterPlugin( + name, description, create_callback, debugger_init_callback); } bool PluginManager::UnregisterPlugin(SymbolFileCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); - SymbolFileInstances &instances = GetSymbolFileInstances(); - - SymbolFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetSymbolFileInstances().UnregisterPlugin(create_callback); } SymbolFileCreateInstance PluginManager::GetSymbolFileCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); - SymbolFileInstances &instances = GetSymbolFileInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -SymbolFileCreateInstance -PluginManager::GetSymbolFileCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); - SymbolFileInstances &instances = GetSymbolFileInstances(); - - SymbolFileInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetSymbolFileInstances().GetCallbackAtIndex(idx); } #pragma mark SymbolVendor -struct SymbolVendorInstance { - SymbolVendorInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - SymbolVendorCreateInstance create_callback; -}; - -typedef std::vector<SymbolVendorInstance> SymbolVendorInstances; - -static std::recursive_mutex &GetSymbolVendorMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<SymbolVendorCreateInstance> SymbolVendorInstance; +typedef PluginInstances<SymbolVendorInstance> SymbolVendorInstances; static SymbolVendorInstances &GetSymbolVendorInstances() { static SymbolVendorInstances g_instances; return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, +bool PluginManager::RegisterPlugin(ConstString name, const char *description, SymbolVendorCreateInstance create_callback) { - if (create_callback) { - SymbolVendorInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); - GetSymbolVendorInstances().push_back(instance); - } - return false; + return GetSymbolVendorInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( SymbolVendorCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); - SymbolVendorInstances &instances = GetSymbolVendorInstances(); - - SymbolVendorInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetSymbolVendorInstances().UnregisterPlugin(create_callback); } SymbolVendorCreateInstance PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); - SymbolVendorInstances &instances = GetSymbolVendorInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -SymbolVendorCreateInstance -PluginManager::GetSymbolVendorCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetSymbolVendorMutex()); - SymbolVendorInstances &instances = GetSymbolVendorInstances(); - - SymbolVendorInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetSymbolVendorInstances().GetCallbackAtIndex(idx); } #pragma mark UnwindAssembly -struct UnwindAssemblyInstance { - UnwindAssemblyInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - UnwindAssemblyCreateInstance create_callback; -}; - -typedef std::vector<UnwindAssemblyInstance> UnwindAssemblyInstances; - -static std::recursive_mutex &GetUnwindAssemblyMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<UnwindAssemblyCreateInstance> UnwindAssemblyInstance; +typedef PluginInstances<UnwindAssemblyInstance> UnwindAssemblyInstances; static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { static UnwindAssemblyInstances g_instances; @@ -1844,77 +1018,24 @@ static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { bool PluginManager::RegisterPlugin( ConstString name, const char *description, UnwindAssemblyCreateInstance create_callback) { - if (create_callback) { - UnwindAssemblyInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); - GetUnwindAssemblyInstances().push_back(instance); - } - return false; + return GetUnwindAssemblyInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( UnwindAssemblyCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); - UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); - - UnwindAssemblyInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetUnwindAssemblyInstances().UnregisterPlugin(create_callback); } UnwindAssemblyCreateInstance PluginManager::GetUnwindAssemblyCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); - UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -UnwindAssemblyCreateInstance -PluginManager::GetUnwindAssemblyCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetUnwindAssemblyMutex()); - UnwindAssemblyInstances &instances = GetUnwindAssemblyInstances(); - - UnwindAssemblyInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetUnwindAssemblyInstances().GetCallbackAtIndex(idx); } #pragma mark MemoryHistory -struct MemoryHistoryInstance { - MemoryHistoryInstance() : name(), description(), create_callback(nullptr) {} - - ConstString name; - std::string description; - MemoryHistoryCreateInstance create_callback; -}; - -typedef std::vector<MemoryHistoryInstance> MemoryHistoryInstances; - -static std::recursive_mutex &GetMemoryHistoryMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstance<MemoryHistoryCreateInstance> MemoryHistoryInstance; +typedef PluginInstances<MemoryHistoryInstance> MemoryHistoryInstances; static MemoryHistoryInstances &GetMemoryHistoryInstances() { static MemoryHistoryInstances g_instances; @@ -1924,81 +1045,37 @@ static MemoryHistoryInstances &GetMemoryHistoryInstances() { bool PluginManager::RegisterPlugin( ConstString name, const char *description, MemoryHistoryCreateInstance create_callback) { - if (create_callback) { - MemoryHistoryInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); - GetMemoryHistoryInstances().push_back(instance); - } - return false; + return GetMemoryHistoryInstances().RegisterPlugin(name, description, + create_callback); } bool PluginManager::UnregisterPlugin( MemoryHistoryCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); - MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); - - MemoryHistoryInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetMemoryHistoryInstances().UnregisterPlugin(create_callback); } MemoryHistoryCreateInstance PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); - MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -MemoryHistoryCreateInstance -PluginManager::GetMemoryHistoryCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetMemoryHistoryMutex()); - MemoryHistoryInstances &instances = GetMemoryHistoryInstances(); - - MemoryHistoryInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetMemoryHistoryInstances().GetCallbackAtIndex(idx); } #pragma mark InstrumentationRuntime -struct InstrumentationRuntimeInstance { - InstrumentationRuntimeInstance() - : name(), description(), create_callback(nullptr) {} +struct InstrumentationRuntimeInstance + : public PluginInstance<InstrumentationRuntimeCreateInstance> { + InstrumentationRuntimeInstance( + ConstString name, std::string description, CallbackType create_callback, + InstrumentationRuntimeGetType get_type_callback) + : PluginInstance<InstrumentationRuntimeCreateInstance>( + name, std::move(description), create_callback), + get_type_callback(get_type_callback) {} - ConstString name; - std::string description; - InstrumentationRuntimeCreateInstance create_callback; - InstrumentationRuntimeGetType get_type_callback; + InstrumentationRuntimeGetType get_type_callback = nullptr; }; -typedef std::vector<InstrumentationRuntimeInstance> +typedef PluginInstances<InstrumentationRuntimeInstance> InstrumentationRuntimeInstances; -static std::recursive_mutex &GetInstrumentationRuntimeMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} - static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { static InstrumentationRuntimeInstances g_instances; return g_instances; @@ -2008,45 +1085,18 @@ bool PluginManager::RegisterPlugin( ConstString name, const char *description, InstrumentationRuntimeCreateInstance create_callback, InstrumentationRuntimeGetType get_type_callback) { - if (create_callback) { - InstrumentationRuntimeInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.get_type_callback = get_type_callback; - std::lock_guard<std::recursive_mutex> guard( - GetInstrumentationRuntimeMutex()); - GetInstrumentationRuntimeInstances().push_back(instance); - } - return false; + return GetInstrumentationRuntimeInstances().RegisterPlugin( + name, description, create_callback, get_type_callback); } bool PluginManager::UnregisterPlugin( InstrumentationRuntimeCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard( - GetInstrumentationRuntimeMutex()); - InstrumentationRuntimeInstances &instances = - GetInstrumentationRuntimeInstances(); - - InstrumentationRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetInstrumentationRuntimeInstances().UnregisterPlugin(create_callback); } InstrumentationRuntimeGetType PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); - InstrumentationRuntimeInstances &instances = - GetInstrumentationRuntimeInstances(); + const auto &instances = GetInstrumentationRuntimeInstances().GetInstances(); if (idx < instances.size()) return instances[idx].get_type_callback; return nullptr; @@ -2054,48 +1104,27 @@ PluginManager::GetInstrumentationRuntimeGetTypeCallbackAtIndex(uint32_t idx) { InstrumentationRuntimeCreateInstance PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetInstrumentationRuntimeMutex()); - InstrumentationRuntimeInstances &instances = - GetInstrumentationRuntimeInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -InstrumentationRuntimeCreateInstance -PluginManager::GetInstrumentationRuntimeCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard( - GetInstrumentationRuntimeMutex()); - InstrumentationRuntimeInstances &instances = - GetInstrumentationRuntimeInstances(); - - InstrumentationRuntimeInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetInstrumentationRuntimeInstances().GetCallbackAtIndex(idx); } #pragma mark TypeSystem -struct TypeSystemInstance { - ConstString name; - std::string description; - TypeSystemCreateInstance create_callback; +struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> { + TypeSystemInstance(ConstString name, std::string description, + CallbackType create_callback, + LanguageSet supported_languages_for_types, + LanguageSet supported_languages_for_expressions) + : PluginInstance<TypeSystemCreateInstance>(name, std::move(description), + create_callback), + supported_languages_for_types(supported_languages_for_types), + supported_languages_for_expressions( + supported_languages_for_expressions) {} + LanguageSet supported_languages_for_types; LanguageSet supported_languages_for_expressions; }; -typedef std::vector<TypeSystemInstance> TypeSystemInstances; - -static std::recursive_mutex &GetTypeSystemMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances<TypeSystemInstance> TypeSystemInstances; static TypeSystemInstances &GetTypeSystemInstances() { static TypeSystemInstances g_instances; @@ -2107,75 +1136,31 @@ bool PluginManager::RegisterPlugin( TypeSystemCreateInstance create_callback, LanguageSet supported_languages_for_types, LanguageSet supported_languages_for_expressions) { - if (create_callback) { - TypeSystemInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.supported_languages_for_types = supported_languages_for_types; - instance.supported_languages_for_expressions = supported_languages_for_expressions; - std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); - GetTypeSystemInstances().push_back(instance); - } - return false; + return GetTypeSystemInstances().RegisterPlugin( + name, description, create_callback, supported_languages_for_types, + supported_languages_for_expressions); } bool PluginManager::UnregisterPlugin(TypeSystemCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); - TypeSystemInstances &instances = GetTypeSystemInstances(); - - TypeSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetTypeSystemInstances().UnregisterPlugin(create_callback); } TypeSystemCreateInstance PluginManager::GetTypeSystemCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); - TypeSystemInstances &instances = GetTypeSystemInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -TypeSystemCreateInstance -PluginManager::GetTypeSystemCreateCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); - TypeSystemInstances &instances = GetTypeSystemInstances(); - - TypeSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetTypeSystemInstances().GetCallbackAtIndex(idx); } LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() { - std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); + const auto &instances = GetTypeSystemInstances().GetInstances(); LanguageSet all; - TypeSystemInstances &instances = GetTypeSystemInstances(); for (unsigned i = 0; i < instances.size(); ++i) all.bitvector |= instances[i].supported_languages_for_types.bitvector; return all; } LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { - std::lock_guard<std::recursive_mutex> guard(GetTypeSystemMutex()); + const auto &instances = GetTypeSystemInstances().GetInstances(); LanguageSet all; - TypeSystemInstances &instances = GetTypeSystemInstances(); for (unsigned i = 0; i < instances.size(); ++i) all.bitvector |= instances[i].supported_languages_for_expressions.bitvector; return all; @@ -2183,21 +1168,17 @@ LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { #pragma mark REPL -struct REPLInstance { - REPLInstance() : name(), description(), create_callback(nullptr) {} +struct REPLInstance : public PluginInstance<REPLCreateInstance> { + REPLInstance(ConstString name, std::string description, + CallbackType create_callback, LanguageSet supported_languages) + : PluginInstance<REPLCreateInstance>(name, std::move(description), + create_callback), + supported_languages(supported_languages) {} - ConstString name; - std::string description; - REPLCreateInstance create_callback; LanguageSet supported_languages; }; -typedef std::vector<REPLInstance> REPLInstances; - -static std::recursive_mutex &GetREPLMutex() { - static std::recursive_mutex g_instances_mutex; - return g_instances_mutex; -} +typedef PluginInstances<REPLInstance> REPLInstances; static REPLInstances &GetREPLInstances() { static REPLInstances g_instances; @@ -2207,63 +1188,21 @@ static REPLInstances &GetREPLInstances() { bool PluginManager::RegisterPlugin(ConstString name, const char *description, REPLCreateInstance create_callback, LanguageSet supported_languages) { - if (create_callback) { - REPLInstance instance; - assert((bool)name); - instance.name = name; - if (description && description[0]) - instance.description = description; - instance.create_callback = create_callback; - instance.supported_languages = supported_languages; - std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); - GetREPLInstances().push_back(instance); - } - return false; + return GetREPLInstances().RegisterPlugin(name, description, create_callback, + supported_languages); } bool PluginManager::UnregisterPlugin(REPLCreateInstance create_callback) { - if (create_callback) { - std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); - REPLInstances &instances = GetREPLInstances(); - - REPLInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->create_callback == create_callback) { - instances.erase(pos); - return true; - } - } - } - return false; + return GetREPLInstances().UnregisterPlugin(create_callback); } REPLCreateInstance PluginManager::GetREPLCreateCallbackAtIndex(uint32_t idx) { - std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); - REPLInstances &instances = GetREPLInstances(); - if (idx < instances.size()) - return instances[idx].create_callback; - return nullptr; -} - -REPLCreateInstance -PluginManager::GetREPLCreateCallbackForPluginName(ConstString name) { - if (name) { - std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); - REPLInstances &instances = GetREPLInstances(); - - REPLInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->create_callback; - } - } - return nullptr; + return GetREPLInstances().GetCallbackAtIndex(idx); } LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { - std::lock_guard<std::recursive_mutex> guard(GetREPLMutex()); + const auto &instances = GetREPLInstances().GetInstances(); LanguageSet all; - REPLInstances &instances = GetREPLInstances(); for (unsigned i = 0; i < instances.size(); ++i) all.bitvector |= instances[i].supported_languages.bitvector; return all; @@ -2272,88 +1211,21 @@ LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { #pragma mark PluginManager void PluginManager::DebuggerInitialize(Debugger &debugger) { - // Initialize the DynamicLoader plugins - { - std::lock_guard<std::recursive_mutex> guard(GetDynamicLoaderMutex()); - DynamicLoaderInstances &instances = GetDynamicLoaderInstances(); - - DynamicLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->debugger_init_callback) - pos->debugger_init_callback(debugger); - } - } - - // Initialize the JITLoader plugins - { - std::lock_guard<std::recursive_mutex> guard(GetJITLoaderMutex()); - JITLoaderInstances &instances = GetJITLoaderInstances(); - - JITLoaderInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->debugger_init_callback) - pos->debugger_init_callback(debugger); - } - } - - // Initialize the Platform plugins - { - std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex()); - PlatformInstances &instances = GetPlatformInstances(); - - PlatformInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->debugger_init_callback) - pos->debugger_init_callback(debugger); - } - } - - // Initialize the Process plugins - { - std::lock_guard<std::recursive_mutex> guard(GetProcessMutex()); - ProcessInstances &instances = GetProcessInstances(); - - ProcessInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (pos->debugger_init_callback) - pos->debugger_init_callback(debugger); - } - } - - // Initialize the SymbolFile plugins - { - std::lock_guard<std::recursive_mutex> guard(GetSymbolFileMutex()); - for (auto &sym_file : GetSymbolFileInstances()) { - if (sym_file.debugger_init_callback) - sym_file.debugger_init_callback(debugger); - } - } - - // Initialize the OperatingSystem plugins - { - std::lock_guard<std::recursive_mutex> guard(GetOperatingSystemMutex()); - for (auto &os : GetOperatingSystemInstances()) { - if (os.debugger_init_callback) - os.debugger_init_callback(debugger); - } - } - - // Initialize the StructuredDataPlugin plugins - { - std::lock_guard<std::recursive_mutex> guard(GetStructuredDataPluginMutex()); - for (auto &plugin : GetStructuredDataPluginInstances()) { - if (plugin.debugger_init_callback) - plugin.debugger_init_callback(debugger); - } - } + GetDynamicLoaderInstances().PerformDebuggerCallback(debugger); + GetJITLoaderInstances().PerformDebuggerCallback(debugger); + GetPlatformInstances().PerformDebuggerCallback(debugger); + GetProcessInstances().PerformDebuggerCallback(debugger); + GetSymbolFileInstances().PerformDebuggerCallback(debugger); + GetOperatingSystemInstances().PerformDebuggerCallback(debugger); + GetStructuredDataPluginInstances().PerformDebuggerCallback(debugger); } // This is the preferred new way to register plugin specific settings. e.g. // 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) { +static lldb::OptionValuePropertiesSP +GetDebuggerPropertyForPlugins(Debugger &debugger, ConstString plugin_type_name, + ConstString plugin_type_desc, bool can_create) { lldb::OptionValuePropertiesSP parent_properties_sp( debugger.GetValueProperties()); if (parent_properties_sp) { @@ -2422,8 +1294,8 @@ static lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsOldStyle( namespace { typedef lldb::OptionValuePropertiesSP -GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString , - ConstString , bool can_create); +GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString, + bool can_create); lldb::OptionValuePropertiesSP GetSettingForPlugin(Debugger &debugger, ConstString setting_name, @@ -2444,8 +1316,8 @@ GetSettingForPlugin(Debugger &debugger, ConstString setting_name, bool CreateSettingForPlugin( Debugger &debugger, ConstString plugin_type_name, ConstString plugin_type_desc, - const lldb::OptionValuePropertiesSP &properties_sp, - ConstString description, bool is_global_property, + const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, + bool is_global_property, GetDebuggerPropertyForPluginsPtr get_debugger_property = GetDebuggerPropertyForPlugins) { if (properties_sp) { @@ -2471,8 +1343,9 @@ const char *kStructuredDataPluginName("structured-data"); } // anonymous namespace -lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin( - Debugger &debugger, ConstString setting_name) { +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, + ConstString setting_name) { return GetSettingForPlugin(debugger, setting_name, ConstString(kDynamicLoaderPluginName)); } @@ -2551,8 +1424,9 @@ bool PluginManager::CreateSettingForJITLoaderPlugin( static const char *kOperatingSystemPluginName("os"); -lldb::OptionValuePropertiesSP PluginManager::GetSettingForOperatingSystemPlugin( - Debugger &debugger, ConstString setting_name) { +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForOperatingSystemPlugin(Debugger &debugger, + ConstString setting_name) { lldb::OptionValuePropertiesSP properties_sp; lldb::OptionValuePropertiesSP plugin_type_properties_sp( GetDebuggerPropertyForPlugins( @@ -2583,8 +1457,9 @@ bool PluginManager::CreateSettingForOperatingSystemPlugin( return false; } -lldb::OptionValuePropertiesSP PluginManager::GetSettingForStructuredDataPlugin( - Debugger &debugger, ConstString setting_name) { +lldb::OptionValuePropertiesSP +PluginManager::GetSettingForStructuredDataPlugin(Debugger &debugger, + ConstString setting_name) { return GetSettingForPlugin(debugger, setting_name, ConstString(kStructuredDataPluginName)); } diff --git a/lldb/source/Core/RichManglingContext.cpp b/lldb/source/Core/RichManglingContext.cpp index 3d1941ebdd26..2094d96acd7c 100644 --- a/lldb/source/Core/RichManglingContext.cpp +++ b/lldb/source/Core/RichManglingContext.cpp @@ -1,4 +1,4 @@ -//===-- RichManglingContext.cpp ---------------------------------*- C++ -*-===// +//===-- RichManglingContext.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/SearchFilter.cpp b/lldb/source/Core/SearchFilter.cpp index 9902166be522..ea51fb379181 100644 --- a/lldb/source/Core/SearchFilter.cpp +++ b/lldb/source/Core/SearchFilter.cpp @@ -1,4 +1,4 @@ -//===-- SearchFilter.cpp ----------------------------------------*- C++ -*-===// +//===-- SearchFilter.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -75,7 +75,8 @@ SearchFilter::SearchFilter(const TargetSP &target_sp, unsigned char filterType) SearchFilter::~SearchFilter() = default; SearchFilterSP SearchFilter::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &filter_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &filter_dict, Status &error) { SearchFilterSP result_sp; if (!filter_dict.IsValid()) { @@ -109,19 +110,19 @@ SearchFilterSP SearchFilter::CreateFromStructuredData( switch (filter_type) { case Unconstrained: result_sp = SearchFilterForUnconstrainedSearches::CreateFromStructuredData( - target, *subclass_options, error); + target_sp, *subclass_options, error); break; case ByModule: result_sp = SearchFilterByModule::CreateFromStructuredData( - target, *subclass_options, error); + target_sp, *subclass_options, error); break; case ByModules: result_sp = SearchFilterByModuleList::CreateFromStructuredData( - target, *subclass_options, error); + target_sp, *subclass_options, error); break; case ByModulesAndCU: result_sp = SearchFilterByModuleListAndCU::CreateFromStructuredData( - target, *subclass_options, error); + target_sp, *subclass_options, error); break; case Exception: error.SetErrorString("Can't serialize exception breakpoints yet."); @@ -160,9 +161,8 @@ void SearchFilter::GetDescription(Stream *s) {} void SearchFilter::Dump(Stream *s) const {} -lldb::SearchFilterSP SearchFilter::CopyForBreakpoint(Breakpoint &breakpoint) { - SearchFilterSP ret_sp = DoCopyForBreakpoint(breakpoint); - TargetSP target_sp = breakpoint.GetTargetSP(); +lldb::SearchFilterSP SearchFilter::CreateCopy(lldb::TargetSP& target_sp) { + SearchFilterSP ret_sp = DoCreateCopy(); ret_sp->SetTarget(target_sp); return ret_sp; } @@ -212,7 +212,7 @@ void SearchFilter::Search(Searcher &searcher) { searcher.SearchCallback(*this, empty_sc, nullptr); return; } - + DoModuleIteration(empty_sc, searcher); } @@ -362,11 +362,11 @@ Searcher::CallbackReturn SearchFilter::DoFunctionIteration( // Selects a shared library matching a given file spec, consulting the targets // "black list". SearchFilterSP SearchFilterForUnconstrainedSearches::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &data_dict, Status &error) { // No options for an unconstrained search. - return std::make_shared<SearchFilterForUnconstrainedSearches>( - target.shared_from_this()); + return std::make_shared<SearchFilterForUnconstrainedSearches>(target_sp); } StructuredData::ObjectSP @@ -390,8 +390,7 @@ bool SearchFilterForUnconstrainedSearches::ModulePasses( return true; } -lldb::SearchFilterSP SearchFilterForUnconstrainedSearches::DoCopyForBreakpoint( - Breakpoint &breakpoint) { +SearchFilterSP SearchFilterForUnconstrainedSearches::DoCreateCopy() { return std::make_shared<SearchFilterForUnconstrainedSearches>(*this); } @@ -418,12 +417,6 @@ bool SearchFilterByModule::AddressPasses(Address &address) { return true; } -bool SearchFilterByModule::CompUnitPasses(FileSpec &fileSpec) { return true; } - -bool SearchFilterByModule::CompUnitPasses(CompileUnit &compUnit) { - return true; -} - void SearchFilterByModule::Search(Searcher &searcher) { if (!m_target_sp) return; @@ -466,13 +459,13 @@ uint32_t SearchFilterByModule::GetFilterRequiredItems() { void SearchFilterByModule::Dump(Stream *s) const {} -lldb::SearchFilterSP -SearchFilterByModule::DoCopyForBreakpoint(Breakpoint &breakpoint) { +SearchFilterSP SearchFilterByModule::DoCreateCopy() { return std::make_shared<SearchFilterByModule>(*this); } SearchFilterSP SearchFilterByModule::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &data_dict, Status &error) { StructuredData::Array *modules_array; bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList), @@ -497,8 +490,7 @@ SearchFilterSP SearchFilterByModule::CreateFromStructuredData( } FileSpec module_spec(module); - return std::make_shared<SearchFilterByModule>(target.shared_from_this(), - module_spec); + return std::make_shared<SearchFilterByModule>(target_sp, module_spec); } StructuredData::ObjectSP SearchFilterByModule::SerializeToStructuredData() { @@ -545,14 +537,6 @@ bool SearchFilterByModuleList::AddressPasses(Address &address) { return true; } -bool SearchFilterByModuleList::CompUnitPasses(FileSpec &fileSpec) { - return true; -} - -bool SearchFilterByModuleList::CompUnitPasses(CompileUnit &compUnit) { - return true; -} - void SearchFilterByModuleList::Search(Searcher &searcher) { if (!m_target_sp) return; @@ -611,20 +595,20 @@ uint32_t SearchFilterByModuleList::GetFilterRequiredItems() { void SearchFilterByModuleList::Dump(Stream *s) const {} -lldb::SearchFilterSP -SearchFilterByModuleList::DoCopyForBreakpoint(Breakpoint &breakpoint) { +lldb::SearchFilterSP SearchFilterByModuleList::DoCreateCopy() { return std::make_shared<SearchFilterByModuleList>(*this); } SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &data_dict, Status &error) { StructuredData::Array *modules_array; bool success = data_dict.GetValueForKeyAsArray(GetKey(OptionNames::ModList), modules_array); if (!success) - return std::make_shared<SearchFilterByModuleList>(target.shared_from_this(), + return std::make_shared<SearchFilterByModuleList>(target_sp, FileSpecList{}); FileSpecList modules; size_t num_modules = modules_array->GetSize(); @@ -638,8 +622,7 @@ SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData( } modules.EmplaceBack(module); } - return std::make_shared<SearchFilterByModuleList>(target.shared_from_this(), - modules); + return std::make_shared<SearchFilterByModuleList>(target_sp, modules); } void SearchFilterByModuleList::SerializeUnwrapped( @@ -667,7 +650,8 @@ SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU( SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU() = default; lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData( - Target &target, const StructuredData::Dictionary &data_dict, + const lldb::TargetSP& target_sp, + const StructuredData::Dictionary &data_dict, Status &error) { StructuredData::Array *modules_array = nullptr; SearchFilterSP result_sp; @@ -710,7 +694,7 @@ lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData( } return std::make_shared<SearchFilterByModuleListAndCU>( - target.shared_from_this(), modules, cus); + target_sp, modules, cus); } StructuredData::ObjectSP @@ -832,7 +816,6 @@ uint32_t SearchFilterByModuleListAndCU::GetFilterRequiredItems() { void SearchFilterByModuleListAndCU::Dump(Stream *s) const {} -lldb::SearchFilterSP -SearchFilterByModuleListAndCU::DoCopyForBreakpoint(Breakpoint &breakpoint) { +SearchFilterSP SearchFilterByModuleListAndCU::DoCreateCopy() { return std::make_shared<SearchFilterByModuleListAndCU>(*this); } diff --git a/lldb/source/Core/Section.cpp b/lldb/source/Core/Section.cpp index 1697f1f7a5d4..9bf1c62c5ab8 100644 --- a/lldb/source/Core/Section.cpp +++ b/lldb/source/Core/Section.cpp @@ -1,4 +1,4 @@ -//===-- Section.cpp ---------------------------------------------*- C++ -*-===// +//===-- Section.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,6 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Stream.h" #include "lldb/Utility/VMRange.h" #include <inttypes.h> @@ -68,6 +67,8 @@ const char *Section::GetTypeAsCString() const { return "dwarf-aranges"; case eSectionTypeDWARFDebugCuIndex: return "dwarf-cu-index"; + case eSectionTypeDWARFDebugTuIndex: + return "dwarf-tu-index"; case eSectionTypeDWARFDebugFrame: return "dwarf-frame"; case eSectionTypeDWARFDebugInfo: @@ -265,11 +266,8 @@ bool Section::ResolveContainedAddress(addr_t offset, Address &so_addr, so_addr.SetOffset(offset); so_addr.SetSection(const_cast<Section *>(this)->shared_from_this()); -#ifdef LLDB_CONFIGURATION_DEBUG - // For debug builds, ensure that there are no orphaned (i.e., moduleless) - // sections. + // Ensure that there are no orphaned (i.e., moduleless) sections. assert(GetModule().get()); -#endif return true; } @@ -284,15 +282,15 @@ bool Section::ContainsFileAddress(addr_t vm_addr) const { return false; } -void Section::Dump(Stream *s, Target *target, uint32_t depth) const { - // s->Printf("%.*p: ", (int)sizeof(void*) * 2, this); - s->Indent(); - s->Printf("0x%8.8" PRIx64 " %-16s ", GetID(), GetTypeAsCString()); +void Section::Dump(llvm::raw_ostream &s, unsigned indent, Target *target, + uint32_t depth) const { + s.indent(indent); + s << llvm::format("0x%8.8" PRIx64 " %-16s ", GetID(), GetTypeAsCString()); bool resolved = true; addr_t addr = LLDB_INVALID_ADDRESS; if (GetByteSize() == 0) - s->Printf("%39s", ""); + s.indent(39); else { if (target) addr = GetLoadBaseAddress(target); @@ -304,27 +302,27 @@ void Section::Dump(Stream *s, Target *target, uint32_t depth) const { } VMRange range(addr, addr + m_byte_size); - range.Dump(s->AsRawOstream(), 0); + range.Dump(s, 0); } - s->Printf("%c %c%c%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", - resolved ? ' ' : '*', m_readable ? 'r' : '-', - m_writable ? 'w' : '-', m_executable ? 'x' : '-', m_file_offset, - m_file_size, Get()); + s << llvm::format("%c %c%c%c 0x%8.8" PRIx64 " 0x%8.8" PRIx64 " 0x%8.8x ", + resolved ? ' ' : '*', m_readable ? 'r' : '-', + m_writable ? 'w' : '-', m_executable ? 'x' : '-', + m_file_offset, m_file_size, Get()); DumpName(s); - s->EOL(); + s << "\n"; if (depth > 0) - m_children.Dump(s, target, false, depth - 1); + m_children.Dump(s, indent, target, false, depth - 1); } -void Section::DumpName(Stream *s) const { +void Section::DumpName(llvm::raw_ostream &s) const { SectionSP parent_sp(GetParent()); if (parent_sp) { parent_sp->DumpName(s); - s->PutChar('.'); + s << '.'; } else { // The top most section prints the module basename const char *name = nullptr; @@ -337,9 +335,9 @@ void Section::DumpName(Stream *s) const { if ((!name || !name[0]) && module_sp) name = module_sp->GetFileSpec().GetFilename().AsCString(); if (name && name[0]) - s->Printf("%s.", name); + s << name << '.'; } - m_name.Dump(s); + s << m_name; } bool Section::IsDescendant(const Section *section) { @@ -569,31 +567,27 @@ bool SectionList::ContainsSection(user_id_t sect_id) const { return FindSectionByID(sect_id).get() != nullptr; } -void SectionList::Dump(Stream *s, Target *target, bool show_header, - uint32_t depth) const { +void SectionList::Dump(llvm::raw_ostream &s, unsigned indent, Target *target, + bool show_header, uint32_t depth) const { bool target_has_loaded_sections = target && !target->GetSectionLoadList().IsEmpty(); if (show_header && !m_sections.empty()) { - s->Indent(); - s->Printf("SectID Type %s Address " - " Perm File Off. File Size Flags " - " Section Name\n", - target_has_loaded_sections ? "Load" : "File"); - s->Indent(); - s->PutCString("---------- ---------------- " - "--------------------------------------- ---- ---------- " - "---------- " - "---------- ----------------------------\n"); + s.indent(indent); + s << llvm::formatv( + "SectID Type {0} Address " + " Perm File Off. File Size Flags " + " Section Name\n", + target_has_loaded_sections ? "Load" : "File"); + s.indent(indent); + s << "---------- ---------------- " + "--------------------------------------- ---- ---------- " + "---------- " + "---------- ----------------------------\n"; } - const_iterator sect_iter; - const_iterator end = m_sections.end(); - for (sect_iter = m_sections.begin(); sect_iter != end; ++sect_iter) { - (*sect_iter)->Dump(s, target_has_loaded_sections ? target : nullptr, depth); - } - - if (show_header && !m_sections.empty()) - s->IndentLess(); + for (const auto §ion_sp : m_sections) + section_sp->Dump(s, indent, target_has_loaded_sections ? target : nullptr, + depth); } size_t SectionList::Slide(addr_t slide_amount, bool slide_children) { diff --git a/lldb/source/Core/SourceManager.cpp b/lldb/source/Core/SourceManager.cpp index 8e0cc57f80c1..7414dd281d43 100644 --- a/lldb/source/Core/SourceManager.cpp +++ b/lldb/source/Core/SourceManager.cpp @@ -1,4 +1,4 @@ -//===-- SourceManager.cpp ---------------------------------------*- C++ -*-===// +//===-- SourceManager.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,6 +22,7 @@ #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/AnsiTerminal.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferLLVM.h" @@ -51,27 +52,24 @@ static inline bool is_newline_char(char ch) { return ch == '\n' || ch == '\r'; } // SourceManager constructor SourceManager::SourceManager(const TargetSP &target_sp) - : m_last_file_sp(), m_last_line(0), m_last_count(0), m_default_set(false), + : m_last_line(0), m_last_count(0), m_default_set(false), m_target_wp(target_sp), m_debugger_wp(target_sp->GetDebugger().shared_from_this()) {} SourceManager::SourceManager(const DebuggerSP &debugger_sp) - : m_last_file_sp(), m_last_line(0), m_last_count(0), m_default_set(false), - m_target_wp(), m_debugger_wp(debugger_sp) {} + : m_last_line(0), m_last_count(0), m_default_set(false), m_target_wp(), + m_debugger_wp(debugger_sp) {} // Destructor SourceManager::~SourceManager() {} SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { - bool same_as_previous = - m_last_file_sp && - FileSpec::Match(file_spec, m_last_file_sp->GetFileSpec()); + if (!file_spec) + return nullptr; DebuggerSP debugger_sp(m_debugger_wp.lock()); FileSP file_sp; - if (same_as_previous) - file_sp = m_last_file_sp; - else if (debugger_sp) + if (debugger_sp && debugger_sp->GetUseSourceCache()) file_sp = debugger_sp->GetSourceFileCache().FindSourceFile(file_spec); TargetSP target_sp(m_target_wp.lock()); @@ -94,7 +92,7 @@ SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { else file_sp = std::make_shared<File>(file_spec, debugger_sp); - if (debugger_sp) + if (debugger_sp && debugger_sp->GetUseSourceCache()) debugger_sp->GetSourceFileCache().AddSourceFile(file_sp); } return file_sp; @@ -148,6 +146,10 @@ static bool should_show_stop_column_with_caret(DebuggerSP debugger_sp) { return value == eStopShowColumnCaret; } +static bool should_show_stop_line_with_ansi(DebuggerSP debugger_sp) { + return debugger_sp && debugger_sp->GetUseColor(); +} + size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( uint32_t start_line, uint32_t count, uint32_t curr_line, uint32_t column, const char *current_line_cstr, Stream *s, @@ -173,10 +175,10 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( m_last_line = start_line; m_last_count = count; - if (m_last_file_sp.get()) { + if (FileSP last_file_sp = GetLastFile()) { const uint32_t end_line = start_line + count - 1; for (uint32_t line = start_line; line <= end_line; ++line) { - if (!m_last_file_sp->LineIsValid(line)) { + if (!last_file_sp->LineIsValid(line)) { m_last_line = UINT32_MAX; break; } @@ -191,8 +193,20 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( ::snprintf(prefix, sizeof(prefix), " "); } - s->Printf("%s%2.2s %-4u\t", prefix, - line == curr_line ? current_line_cstr : "", line); + char buffer[3]; + sprintf(buffer, "%2.2s", (line == curr_line) ? current_line_cstr : ""); + std::string current_line_highlight(buffer); + + auto debugger_sp = m_debugger_wp.lock(); + if (should_show_stop_line_with_ansi(debugger_sp)) { + current_line_highlight = ansi::FormatAnsiTerminalCodes( + (debugger_sp->GetStopShowLineMarkerAnsiPrefix() + + current_line_highlight + + debugger_sp->GetStopShowLineMarkerAnsiSuffix()) + .str()); + } + + s->Printf("%s%s %-4u\t", prefix, current_line_highlight.c_str(), line); // So far we treated column 0 as a special 'no column value', but // DisplaySourceLines starts counting columns from 0 (and no column is @@ -202,12 +216,12 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( columnToHighlight = column - 1; size_t this_line_size = - m_last_file_sp->DisplaySourceLines(line, columnToHighlight, 0, 0, s); + last_file_sp->DisplaySourceLines(line, columnToHighlight, 0, 0, s); if (column != 0 && line == curr_line && - should_show_stop_column_with_caret(m_debugger_wp.lock())) { + should_show_stop_column_with_caret(debugger_sp)) { // Display caret cursor. std::string src_line; - m_last_file_sp->GetLine(line, src_line); + last_file_sp->GetLine(line, src_line); s->Printf(" \t"); // Insert a space for every non-tab character in the source line. for (size_t i = 0; i + 1 < column && i < src_line.length(); ++i) @@ -238,10 +252,11 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbers( else start_line = 1; - if (m_last_file_sp.get() != file_sp.get()) { + FileSP last_file_sp(GetLastFile()); + if (last_file_sp.get() != file_sp.get()) { if (line == 0) m_last_line = 0; - m_last_file_sp = file_sp; + m_last_file_spec = file_spec; } return DisplaySourceLinesWithLineNumbersUsingLastFile( start_line, count, line, column, current_line_cstr, s, bp_locs); @@ -251,14 +266,15 @@ size_t SourceManager::DisplayMoreWithLineNumbers( Stream *s, uint32_t count, bool reverse, const SymbolContextList *bp_locs) { // If we get called before anybody has set a default file and line, then try // to figure it out here. - const bool have_default_file_line = m_last_file_sp && m_last_line > 0; + FileSP last_file_sp(GetLastFile()); + const bool have_default_file_line = last_file_sp && m_last_line > 0; if (!m_default_set) { FileSpec tmp_spec; uint32_t tmp_line; GetDefaultFileAndLine(tmp_spec, tmp_line); } - if (m_last_file_sp) { + if (last_file_sp) { if (m_last_line == UINT32_MAX) return 0; @@ -293,22 +309,21 @@ size_t SourceManager::DisplayMoreWithLineNumbers( bool SourceManager::SetDefaultFileAndLine(const FileSpec &file_spec, uint32_t line) { - FileSP old_file_sp = m_last_file_sp; - m_last_file_sp = GetFile(file_spec); - m_default_set = true; - if (m_last_file_sp) { + FileSP file_sp(GetFile(file_spec)); + + if (file_sp) { m_last_line = line; + m_last_file_spec = file_spec; return true; } else { - m_last_file_sp = old_file_sp; return false; } } bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { - if (m_last_file_sp) { - file_spec = m_last_file_sp->GetFileSpec(); + if (FileSP last_file_sp = GetLastFile()) { + file_spec = m_last_file_spec; line = m_last_line; return true; } else if (!m_default_set) { @@ -325,7 +340,7 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { ConstString main_name("main"); bool symbols_okay = false; // Force it to be a debug symbol. bool inlines_okay = true; - executable_ptr->FindFunctions(main_name, nullptr, + executable_ptr->FindFunctions(main_name, CompilerDeclContext(), lldb::eFunctionNameTypeBase, inlines_okay, symbols_okay, sc_list); size_t num_matches = sc_list.GetSize(); @@ -338,7 +353,7 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { .GetBaseAddress() .CalculateSymbolContextLineEntry(line_entry)) { SetDefaultFileAndLine(line_entry.file, line_entry.line); - file_spec = m_last_file_sp->GetFileSpec(); + file_spec = m_last_file_spec; line = m_last_line; return true; } @@ -679,7 +694,7 @@ bool SourceManager::File::GetLine(uint32_t line_no, std::string &buffer) { } void SourceManager::SourceFileCache::AddSourceFile(const FileSP &file_sp) { - FileSpec file_spec; + FileSpec file_spec = file_sp->GetFileSpec(); FileCache::iterator pos = m_file_cache.find(file_spec); if (pos == m_file_cache.end()) m_file_cache[file_spec] = file_sp; diff --git a/lldb/source/Core/StreamAsynchronousIO.cpp b/lldb/source/Core/StreamAsynchronousIO.cpp index d283749144e1..04195a6d13ea 100644 --- a/lldb/source/Core/StreamAsynchronousIO.cpp +++ b/lldb/source/Core/StreamAsynchronousIO.cpp @@ -1,4 +1,4 @@ -//===-- StreamAsynchronousIO.cpp --------------------------------*- C++ -*-===// +//===-- StreamAsynchronousIO.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/StreamFile.cpp b/lldb/source/Core/StreamFile.cpp index 475c27ec4117..43a9df802f7e 100644 --- a/lldb/source/Core/StreamFile.cpp +++ b/lldb/source/Core/StreamFile.cpp @@ -1,4 +1,4 @@ -//===-- StreamFile.cpp ------------------------------------------*- C++ -*-===// +//===-- StreamFile.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/UserSettingsController.cpp b/lldb/source/Core/UserSettingsController.cpp index 3a656766dcec..b9f7d5eaa687 100644 --- a/lldb/source/Core/UserSettingsController.cpp +++ b/lldb/source/Core/UserSettingsController.cpp @@ -1,4 +1,4 @@ -//====-- UserSettingsController.cpp ------------------------------*- C++-*-===// +//===-- UserSettingsController.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/Value.cpp b/lldb/source/Core/Value.cpp index c70ab98dcdfa..63467644cdef 100644 --- a/lldb/source/Core/Value.cpp +++ b/lldb/source/Core/Value.cpp @@ -1,4 +1,4 @@ -//===-- Value.cpp -----------------------------------------------*- C++ -*-===// +//===-- Value.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp index 1dd9a6cf62c3..3a775b07e5e1 100644 --- a/lldb/source/Core/ValueObject.cpp +++ b/lldb/source/Core/ValueObject.cpp @@ -1,4 +1,4 @@ -//===-- ValueObject.cpp -----------------------------------------*- C++ -*-===// +//===-- ValueObject.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,6 @@ #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Expression/ExpressionVariable.h" #include "lldb/Host/Config.h" -#include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Declaration.h" @@ -46,7 +45,6 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" #include "lldb/Utility/Scalar.h" -#include "lldb/Utility/SharingPtr.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-private-types.h" @@ -106,12 +104,13 @@ ValueObject::ValueObject(ValueObject &parent) // ValueObject constructor ValueObject::ValueObject(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, AddressType child_ptr_or_ref_addr_type) : UserID(++g_value_obj_uid), // Unique identifier for every value object m_parent(nullptr), m_root(nullptr), m_update_point(exe_scope), m_name(), m_data(), m_value(), m_error(), m_value_str(), m_old_value_str(), m_location_str(), m_summary_str(), m_object_desc_str(), - m_manager(), m_children(), m_synthetic_children(), + m_manager(&manager), m_children(), m_synthetic_children(), m_dynamic_value(nullptr), m_synthetic_value(nullptr), m_deref_valobj(nullptr), m_format(eFormatDefault), m_last_format(eFormatDefault), m_last_format_mgr_revision(0), @@ -135,65 +134,12 @@ ValueObject::ValueObject(ExecutionContextScope *exe_scope, m_data.SetAddressByteSize(arch.GetAddressByteSize()); } } - m_manager = new ValueObjectManager(); m_manager->ManageObject(this); } // Destructor ValueObject::~ValueObject() {} -void ValueObject::UpdateChildrenAddressType() { - Value::ValueType value_type = m_value.GetValueType(); - ExecutionContext exe_ctx(GetExecutionContextRef()); - Process *process = exe_ctx.GetProcessPtr(); - const bool process_is_alive = process && process->IsAlive(); - const uint32_t type_info = GetCompilerType().GetTypeInfo(); - const bool is_pointer_or_ref = - (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0; - - switch (value_type) { - case Value::eValueTypeFileAddress: - // If this type is a pointer, then its children will be considered load - // addresses if the pointer or reference is dereferenced, but only if - // the process is alive. - // - // There could be global variables like in the following code: - // struct LinkedListNode { Foo* foo; LinkedListNode* next; }; - // Foo g_foo1; - // Foo g_foo2; - // LinkedListNode g_second_node = { &g_foo2, NULL }; - // LinkedListNode g_first_node = { &g_foo1, &g_second_node }; - // - // When we aren't running, we should be able to look at these variables - // using the "target variable" command. Children of the "g_first_node" - // always will be of the same address type as the parent. But children - // of the "next" member of LinkedListNode will become load addresses if - // we have a live process, or remain a file address if it was a file - // address. - if (process_is_alive && is_pointer_or_ref) - SetAddressTypeOfChildren(eAddressTypeLoad); - else - SetAddressTypeOfChildren(eAddressTypeFile); - break; - case Value::eValueTypeHostAddress: - // Same as above for load addresses, except children of pointer or refs - // are always load addresses. Host addresses are used to store freeze - // dried variables. If this type is a struct, the entire struct - // contents will be copied into the heap of the - // LLDB process, but we do not currently follow any pointers. - if (is_pointer_or_ref) - SetAddressTypeOfChildren(eAddressTypeLoad); - else - SetAddressTypeOfChildren(eAddressTypeHost); - break; - case Value::eValueTypeLoadAddress: - case Value::eValueTypeScalar: - case Value::eValueTypeVector: - SetAddressTypeOfChildren(eAddressTypeLoad); - break; - } -} - bool ValueObject::UpdateValueIfNeeded(bool update_format) { bool did_change_formats = false; @@ -416,7 +362,7 @@ const char *ValueObject::GetLocationAsCStringImpl(const Value &value, uint32_t addr_nibble_size = data.GetAddressByteSize() * 2; sstr.Printf("0x%*.*llx", addr_nibble_size, addr_nibble_size, value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS)); - m_location_str = sstr.GetString(); + m_location_str = std::string(sstr.GetString()); } break; } } @@ -576,15 +522,13 @@ size_t ValueObject::GetIndexOfChildWithName(ConstString name) { ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name, bool can_create) { - // when getting a child by name, it could be buried inside some base classes - // (which really aren't part of the expression path), so we need a vector of - // indexes that can get us down to the correct child - ValueObjectSP child_sp; - - // We may need to update our value if we are dynamic + // We may need to update our value if we are dynamic. if (IsPossibleDynamicType()) UpdateValueIfNeeded(false); + // When getting a child by name, it could be buried inside some base classes + // (which really aren't part of the expression path), so we need a vector of + // indexes that can get us down to the correct child. std::vector<uint32_t> child_indexes; bool omit_empty_base_classes = true; @@ -594,20 +538,13 @@ ValueObjectSP ValueObject::GetChildMemberWithName(ConstString name, const size_t num_child_indexes = GetCompilerType().GetIndexOfChildMemberWithName( name.GetCString(), omit_empty_base_classes, child_indexes); - if (num_child_indexes > 0) { - std::vector<uint32_t>::const_iterator pos = child_indexes.begin(); - std::vector<uint32_t>::const_iterator end = child_indexes.end(); - - child_sp = GetChildAtIndex(*pos, can_create); - for (++pos; pos != end; ++pos) { - if (child_sp) { - ValueObjectSP new_child_sp(child_sp->GetChildAtIndex(*pos, can_create)); - child_sp = new_child_sp; - } else { - child_sp.reset(); - } - } - } + if (num_child_indexes == 0) + return nullptr; + + ValueObjectSP child_sp = GetSP(); + for (uint32_t idx : child_indexes) + if (child_sp) + child_sp = child_sp->GetChildAtIndex(idx, can_create); return child_sp; } @@ -689,6 +626,16 @@ ValueObject *ValueObject::CreateChildAtIndex(size_t idx, language_flags); } + // In case of an incomplete type, try to use the ValueObject's + // synthetic value to create the child ValueObject. + if (!valobj && synthetic_array_member) { + if (ValueObjectSP synth_valobj_sp = GetSyntheticValue()) { + valobj = synth_valobj_sp + ->GetChildAtIndex(synthetic_index, synthetic_array_member) + .get(); + } + } + return valobj; } @@ -766,7 +713,7 @@ bool ValueObject::IsCStringContainer(bool check_pointer) { return true; addr_t cstr_address = LLDB_INVALID_ADDRESS; AddressType cstr_address_type = eAddressTypeInvalid; - cstr_address = GetAddressOf(true, &cstr_address_type); + cstr_address = GetPointerValue(&cstr_address_type); return (cstr_address != LLDB_INVALID_ADDRESS); } @@ -1120,7 +1067,7 @@ const char *ValueObject::GetObjectDescription() { if (LanguageRuntime *runtime = process->GetLanguageRuntime(language)) { StreamString s; if (runtime->GetObjectDescription(s, *this)) { - m_object_desc_str.append(s.GetString()); + m_object_desc_str.append(std::string(s.GetString())); return m_object_desc_str.c_str(); } } @@ -1200,6 +1147,7 @@ uint64_t ValueObject::GetValueAsUnsigned(uint64_t fail_value, bool *success) { if (ResolveValue(scalar)) { if (success) *success = true; + scalar.MakeUnsigned(); return scalar.ULongLong(fail_value); } // fallthrough, otherwise... @@ -1217,6 +1165,7 @@ int64_t ValueObject::GetValueAsSigned(int64_t fail_value, bool *success) { if (ResolveValue(scalar)) { if (success) *success = true; + scalar.MakeSigned(); return scalar.SLongLong(fail_value); } // fallthrough, otherwise... @@ -1447,7 +1396,7 @@ bool ValueObject::DumpPrintableRepresentation( break; case eValueObjectRepresentationStyleExpressionPath: - GetExpressionPath(strm, false); + GetExpressionPath(strm); str = strm.GetString(); break; } @@ -1553,7 +1502,7 @@ addr_t ValueObject::GetPointerValue(AddressType *address_type) { case Value::eValueTypeLoadAddress: case Value::eValueTypeFileAddress: { lldb::offset_t data_offset = 0; - address = m_data.GetPointer(&data_offset); + address = m_data.GetAddress(&data_offset); } break; } @@ -1652,13 +1601,13 @@ bool ValueObject::GetDeclaration(Declaration &decl) { } ConstString ValueObject::GetTypeName() { - return GetCompilerType().GetConstTypeName(); + return GetCompilerType().GetTypeName(); } ConstString ValueObject::GetDisplayTypeName() { return GetTypeName(); } ConstString ValueObject::GetQualifiedTypeName() { - return GetCompilerType().GetConstQualifiedTypeName(); + return GetCompilerType().GetTypeName(); } LanguageType ValueObject::GetObjectRuntimeLanguage() { @@ -1720,7 +1669,7 @@ bool ValueObject::IsRuntimeSupportValue() { return false; if (auto *runtime = process->GetLanguageRuntime(GetVariable()->GetLanguage())) - if (runtime->IsWhitelistedRuntimeValue(GetName())) + if (runtime->IsAllowedRuntimeValue(GetName())) return false; return true; @@ -1935,10 +1884,7 @@ ValueObject::GetSyntheticExpressionPathChild(const char *expression, return synthetic_child_sp; } -void ValueObject::CalculateSyntheticValue(bool use_synthetic) { - if (!use_synthetic) - return; - +void ValueObject::CalculateSyntheticValue() { TargetSP target_sp(GetTargetSP()); if (target_sp && !target_sp->GetEnableSyntheticValue()) { m_synthetic_value = nullptr; @@ -1990,11 +1936,8 @@ ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); } lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); } -ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) { - if (!use_synthetic) - return ValueObjectSP(); - - CalculateSyntheticValue(use_synthetic); +ValueObjectSP ValueObject::GetSyntheticValue() { + CalculateSyntheticValue(); if (m_synthetic_value) return m_synthetic_value->GetSP(); @@ -2008,28 +1951,11 @@ bool ValueObject::HasSyntheticValue() { if (m_synthetic_children_sp.get() == nullptr) return false; - CalculateSyntheticValue(true); + CalculateSyntheticValue(); return m_synthetic_value != nullptr; } -bool ValueObject::GetBaseClassPath(Stream &s) { - if (IsBaseClass()) { - bool parent_had_base_class = - GetParent() && GetParent()->GetBaseClassPath(s); - CompilerType compiler_type = GetCompilerType(); - llvm::Optional<std::string> cxx_class_name = - ClangASTContext::GetCXXClassName(compiler_type); - if (cxx_class_name) { - if (parent_had_base_class) - s.PutCString("::"); - s.PutCString(cxx_class_name.getValue()); - } - return parent_had_base_class || cxx_class_name; - } - return false; -} - ValueObject *ValueObject::GetNonBaseClassParent() { if (GetParent()) { if (GetParent()->IsBaseClass()) @@ -2055,7 +1981,7 @@ bool ValueObject::IsBaseClass(uint32_t &depth) { return true; } -void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes, +void ValueObject::GetExpressionPath(Stream &s, GetExpressionPathFormat epformat) { // synthetic children do not actually "exist" as part of the hierarchy, and // sometimes they are consed up in ways that don't make sense from an @@ -2104,14 +2030,14 @@ void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes, ValueObject *parent = GetParent(); if (parent) - parent->GetExpressionPath(s, qualify_cxx_base_classes, epformat); + parent->GetExpressionPath(s, epformat); // if we are a deref_of_parent just because we are synthetic array members // made up to allow ptr[%d] syntax to work in variable printing, then add our // name ([%d]) to the expression path if (m_is_array_item_for_pointer && epformat == eGetExpressionPathFormatHonorPointers) - s.PutCString(m_name.AsCString()); + s.PutCString(m_name.GetStringRef()); if (!IsBaseClass()) { if (!is_deref_of_parent) { @@ -2139,13 +2065,8 @@ void ValueObject::GetExpressionPath(Stream &s, bool qualify_cxx_base_classes, } const char *name = GetName().GetCString(); - if (name) { - if (qualify_cxx_base_classes) { - if (GetBaseClassPath(s)) - s.PutCString("::"); - } + if (name) s.PutCString(name); - } } } @@ -2834,7 +2755,7 @@ ValueObjectSP ValueObject::Dereference(Status &error) { const bool transparent_pointers = false; CompilerType compiler_type = GetCompilerType(); CompilerType child_compiler_type; - uint64_t language_flags; + uint64_t language_flags = 0; ExecutionContext exe_ctx(GetExecutionContextRef()); @@ -2854,11 +2775,35 @@ ValueObjectSP ValueObject::Dereference(Status &error) { child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid, language_flags); } + + // In case of incomplete child compiler type, use the pointee type and try + // to recreate a new ValueObjectChild using it. + if (!m_deref_valobj) { + if (HasSyntheticValue()) { + child_compiler_type = compiler_type.GetPointeeType(); + + if (child_compiler_type) { + ConstString child_name; + if (!child_name_str.empty()) + child_name.SetCString(child_name_str.c_str()); + + m_deref_valobj = new ValueObjectChild( + *this, child_compiler_type, child_name, child_byte_size, + child_byte_offset, child_bitfield_bit_size, + child_bitfield_bit_offset, child_is_base_class, + child_is_deref_of_parent, eAddressTypeInvalid, language_flags); + } + } + } + } else if (HasSyntheticValue()) { m_deref_valobj = GetSyntheticValue() ->GetChildMemberWithName(ConstString("$$dereference$$"), true) .get(); + } else if (IsSynthetic()) { + m_deref_valobj = + GetChildMemberWithName(ConstString("$$dereference$$"), true).get(); } if (m_deref_valobj) { @@ -2866,7 +2811,7 @@ ValueObjectSP ValueObject::Dereference(Status &error) { return m_deref_valobj->GetSP(); } else { StreamString strm; - GetExpressionPath(strm, true); + GetExpressionPath(strm); if (is_pointer_or_reference_type) error.SetErrorStringWithFormat("dereference failed: (%s) %s", @@ -2892,7 +2837,7 @@ ValueObjectSP ValueObject::AddressOf(Status &error) { switch (address_type) { case eAddressTypeInvalid: { StreamString expr_path_strm; - GetExpressionPath(expr_path_strm, true); + GetExpressionPath(expr_path_strm); error.SetErrorStringWithFormat("'%s' is not in memory", expr_path_strm.GetData()); } break; @@ -2915,7 +2860,7 @@ ValueObjectSP ValueObject::AddressOf(Status &error) { } } else { StreamString expr_path_strm; - GetExpressionPath(expr_path_strm, true); + GetExpressionPath(expr_path_strm); error.SetErrorStringWithFormat("'%s' doesn't have a valid address", expr_path_strm.GetData()); } @@ -3291,19 +3236,17 @@ ValueObjectSP ValueObject::Persist() { if (!persistent_state) return nullptr; - auto prefix = persistent_state->GetPersistentVariablePrefix(); - ConstString name = - persistent_state->GetNextPersistentVariableName(*target_sp, prefix); + ConstString name = persistent_state->GetNextPersistentVariableName(); ValueObjectSP const_result_sp = ValueObjectConstResult::Create(target_sp.get(), GetValue(), name); - ExpressionVariableSP clang_var_sp = + ExpressionVariableSP persistent_var_sp = persistent_state->CreatePersistentVariable(const_result_sp); - clang_var_sp->m_live_sp = clang_var_sp->m_frozen_sp; - clang_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference; + persistent_var_sp->m_live_sp = persistent_var_sp->m_frozen_sp; + persistent_var_sp->m_flags |= ExpressionVariable::EVIsProgramReference; - return clang_var_sp->GetValueObject(); + return persistent_var_sp->GetValueObject(); } bool ValueObject::IsSyntheticChildrenGenerated() { @@ -3364,7 +3307,7 @@ lldb::ValueObjectSP ValueObjectManager::GetSP() { } if (m_use_synthetic) { - lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(m_use_synthetic); + lldb::ValueObjectSP synthetic_sp = m_user_valobj_sp->GetSyntheticValue(); if (synthetic_sp) m_user_valobj_sp = synthetic_sp; } diff --git a/lldb/source/Core/ValueObjectCast.cpp b/lldb/source/Core/ValueObjectCast.cpp index 3a74b6a7fe18..22e856be539b 100644 --- a/lldb/source/Core/ValueObjectCast.cpp +++ b/lldb/source/Core/ValueObjectCast.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectCast.cpp -------------------------------------*- C++ -*-===// +//===-- ValueObjectCast.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -33,8 +33,6 @@ ValueObjectCast::ValueObjectCast(ValueObject &parent, ConstString name, const CompilerType &cast_type) : ValueObject(parent), m_cast_type(cast_type) { SetName(name); - // m_value.SetContext (Value::eContextTypeClangType, - // cast_type.GetOpaqueQualType()); m_value.SetCompilerType(cast_type); } @@ -68,7 +66,6 @@ bool ValueObjectCast::UpdateValue() { m_update_point.SetUpdated(); m_value = m_parent->GetValue(); CompilerType compiler_type(GetCompilerType()); - // m_value.SetContext (Value::eContextTypeClangType, compiler_type); m_value.SetCompilerType(compiler_type); SetAddressTypeOfChildren(m_parent->GetAddressTypeOfChildren()); if (!CanProvideValue()) { diff --git a/lldb/source/Core/ValueObjectChild.cpp b/lldb/source/Core/ValueObjectChild.cpp index 6b4ada154d68..6205ed32c615 100644 --- a/lldb/source/Core/ValueObjectChild.cpp +++ b/lldb/source/Core/ValueObjectChild.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectChild.cpp ------------------------------------*- C++ -*-===// +//===-- ValueObjectChild.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -70,14 +70,14 @@ static void AdjustForBitfieldness(ConstString &name, ConstString ValueObjectChild::GetTypeName() { if (m_type_name.IsEmpty()) { - m_type_name = GetCompilerType().GetConstTypeName(); + m_type_name = GetCompilerType().GetTypeName(); AdjustForBitfieldness(m_type_name, m_bitfield_bit_size); } return m_type_name; } ConstString ValueObjectChild::GetQualifiedTypeName() { - ConstString qualified_name = GetCompilerType().GetConstTypeName(); + ConstString qualified_name = GetCompilerType().GetTypeName(); AdjustForBitfieldness(qualified_name, m_bitfield_bit_size); return qualified_name; } diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp index 71620698da2a..8d84f8e62ccc 100644 --- a/lldb/source/Core/ValueObjectConstResult.cpp +++ b/lldb/source/Core/ValueObjectConstResult.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectConstResult.cpp ------------------------------*- C++ -*-===// +//===-- ValueObjectConstResult.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,16 +29,18 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address) { - return (new ValueObjectConstResult(exe_scope, byte_order, addr_byte_size, - address)) + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, byte_order, + addr_byte_size, address)) ->GetSP(); } ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, ByteOrder byte_order, uint32_t addr_byte_size, lldb::addr_t address) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), m_impl(this, address) { SetIsConstant(); SetValueIsValid(true); @@ -52,15 +54,17 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, ConstString name, const DataExtractor &data, lldb::addr_t address) { - return (new ValueObjectConstResult(exe_scope, compiler_type, name, data, - address)) + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type, + name, data, address)) ->GetSP(); } ValueObjectConstResult::ValueObjectConstResult( - ExecutionContextScope *exe_scope, const CompilerType &compiler_type, - ConstString name, const DataExtractor &data, lldb::addr_t address) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), + ExecutionContextScope *exe_scope, ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, + const DataExtractor &data, lldb::addr_t address) + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), m_impl(this, address) { m_data = data; @@ -86,8 +90,10 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, lldb::ByteOrder data_byte_order, uint32_t data_addr_size, lldb::addr_t address) { - return (new ValueObjectConstResult(exe_scope, compiler_type, name, data_sp, - data_byte_order, data_addr_size, address)) + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type, + name, data_sp, data_byte_order, + data_addr_size, address)) ->GetSP(); } @@ -95,22 +101,24 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, Value &value, ConstString name, Module *module) { - return (new ValueObjectConstResult(exe_scope, value, name, module))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, value, name, + module)) + ->GetSP(); } ValueObjectConstResult::ValueObjectConstResult( - ExecutionContextScope *exe_scope, const CompilerType &compiler_type, - ConstString name, const lldb::DataBufferSP &data_sp, - lldb::ByteOrder data_byte_order, uint32_t data_addr_size, - lldb::addr_t address) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), + ExecutionContextScope *exe_scope, ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, + const lldb::DataBufferSP &data_sp, lldb::ByteOrder data_byte_order, + uint32_t data_addr_size, lldb::addr_t address) + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), m_impl(this, address) { m_data.SetByteOrder(data_byte_order); m_data.SetAddressByteSize(data_addr_size); m_data.SetData(data_sp); m_value.GetScalar() = (uintptr_t)data_sp->GetBytes(); m_value.SetValueType(Value::eValueTypeHostAddress); - // m_value.SetContext(Value::eContextTypeClangType, compiler_type); m_value.SetCompilerType(compiler_type); m_name = name; SetIsConstant(); @@ -124,16 +132,18 @@ ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, lldb::addr_t address, AddressType address_type, uint32_t addr_byte_size) { - return (new ValueObjectConstResult(exe_scope, compiler_type, name, address, - address_type, addr_byte_size)) + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, compiler_type, + name, address, address_type, + addr_byte_size)) ->GetSP(); } ValueObjectConstResult::ValueObjectConstResult( - ExecutionContextScope *exe_scope, const CompilerType &compiler_type, - ConstString name, lldb::addr_t address, AddressType address_type, - uint32_t addr_byte_size) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), + ExecutionContextScope *exe_scope, ValueObjectManager &manager, + const CompilerType &compiler_type, ConstString name, lldb::addr_t address, + AddressType address_type, uint32_t addr_byte_size) + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), m_impl(this, address) { m_value.GetScalar() = address; m_data.SetAddressByteSize(addr_byte_size); @@ -153,7 +163,6 @@ ValueObjectConstResult::ValueObjectConstResult( m_value.SetValueType(Value::eValueTypeHostAddress); break; } - // m_value.SetContext(Value::eContextTypeClangType, compiler_type); m_value.SetCompilerType(compiler_type); m_name = name; SetIsConstant(); @@ -163,21 +172,25 @@ ValueObjectConstResult::ValueObjectConstResult( ValueObjectSP ValueObjectConstResult::Create(ExecutionContextScope *exe_scope, const Status &error) { - return (new ValueObjectConstResult(exe_scope, error))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectConstResult(exe_scope, *manager_sp, error))->GetSP(); } ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const Status &error) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), m_impl(this) { + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), + m_impl(this) { m_error = error; SetIsConstant(); } ValueObjectConstResult::ValueObjectConstResult(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const Value &value, - ConstString name, - Module *module) - : ValueObject(exe_scope), m_type_name(), m_byte_size(0), m_impl(this) { + ConstString name, Module *module) + : ValueObject(exe_scope, manager), m_type_name(), m_byte_size(0), + m_impl(this) { m_value = value; m_name = name; ExecutionContext exe_ctx; @@ -215,7 +228,7 @@ size_t ValueObjectConstResult::CalculateNumChildren(uint32_t max) { ConstString ValueObjectConstResult::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = GetCompilerType().GetConstTypeName(); + m_type_name = GetCompilerType().GetTypeName(); return m_type_name; } diff --git a/lldb/source/Core/ValueObjectConstResultCast.cpp b/lldb/source/Core/ValueObjectConstResultCast.cpp index b47e699e30f1..53ec9db45540 100644 --- a/lldb/source/Core/ValueObjectConstResultCast.cpp +++ b/lldb/source/Core/ValueObjectConstResultCast.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectConstResultCast.cpp --------------------------*- C++ -*-===// +//===-- ValueObjectConstResultCast.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/ValueObjectConstResultChild.cpp b/lldb/source/Core/ValueObjectConstResultChild.cpp index 4e0b303b69d5..13c8393d8081 100644 --- a/lldb/source/Core/ValueObjectConstResultChild.cpp +++ b/lldb/source/Core/ValueObjectConstResultChild.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectConstResultChild.cpp --------------------------*- C++-*-===// +//===-- ValueObjectConstResultChild.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp index de51735736b9..e4cbbec849ec 100644 --- a/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectConstResultImpl.cpp ---------------------------*- C++-*-===// +//===-- ValueObjectConstResultImpl.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -18,7 +18,6 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Scalar.h" -#include "lldb/Utility/SharingPtr.h" #include <string> diff --git a/lldb/source/Core/ValueObjectDynamicValue.cpp b/lldb/source/Core/ValueObjectDynamicValue.cpp index 59037e2b6b25..ca66740cb55d 100644 --- a/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectDynamicValue.cpp ------------------------------*- C++-*-===// +//===-- ValueObjectDynamicValue.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -237,7 +237,6 @@ bool ValueObjectDynamicValue::UpdateValue() { m_dynamic_type_info = runtime->FixUpDynamicType(m_dynamic_type_info, *m_parent); - // m_value.SetContext (Value::eContextTypeClangType, corrected_type); m_value.SetCompilerType(m_dynamic_type_info.GetCompilerType()); m_value.SetValueType(value_type); @@ -328,7 +327,7 @@ bool ValueObjectDynamicValue::SetData(DataExtractor &data, Status &error) { // but NULL'ing out a value should always be allowed lldb::offset_t offset = 0; - if (data.GetPointer(&offset) != 0) { + if (data.GetAddress(&offset) != 0) { error.SetErrorString( "unable to modify dynamic value, use 'expression' command"); return false; diff --git a/lldb/source/Core/ValueObjectList.cpp b/lldb/source/Core/ValueObjectList.cpp index 358a1b14517b..28907261f0a6 100644 --- a/lldb/source/Core/ValueObjectList.cpp +++ b/lldb/source/Core/ValueObjectList.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectList.cpp -------------------------------------*- C++ -*-===// +//===-- ValueObjectList.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +10,6 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Utility/ConstString.h" -#include "lldb/Utility/SharingPtr.h" #include <utility> diff --git a/lldb/source/Core/ValueObjectMemory.cpp b/lldb/source/Core/ValueObjectMemory.cpp index 1a316bf3e7b0..91b2c6084928 100644 --- a/lldb/source/Core/ValueObjectMemory.cpp +++ b/lldb/source/Core/ValueObjectMemory.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectMemory.cpp ---------------------------------*- C++ -*-===// +//===-- ValueObjectMemory.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,21 +32,27 @@ ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp) { - return (new ValueObjectMemory(exe_scope, name, address, type_sp))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectMemory(exe_scope, *manager_sp, name, address, type_sp)) + ->GetSP(); } ValueObjectSP ValueObjectMemory::Create(ExecutionContextScope *exe_scope, llvm::StringRef name, const Address &address, const CompilerType &ast_type) { - return (new ValueObjectMemory(exe_scope, name, address, ast_type))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectMemory(exe_scope, *manager_sp, name, address, + ast_type)) + ->GetSP(); } ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, llvm::StringRef name, const Address &address, lldb::TypeSP &type_sp) - : ValueObject(exe_scope), m_address(address), m_type_sp(type_sp), + : ValueObject(exe_scope, manager), m_address(address), m_type_sp(type_sp), m_compiler_type() { // Do not attempt to construct one of these objects with no variable! assert(m_type_sp.get() != nullptr); @@ -70,10 +76,11 @@ ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, } ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, llvm::StringRef name, const Address &address, const CompilerType &ast_type) - : ValueObject(exe_scope), m_address(address), m_type_sp(), + : ValueObject(exe_scope, manager), m_address(address), m_type_sp(), m_compiler_type(ast_type) { // Do not attempt to construct one of these objects with no variable! assert(m_compiler_type.GetTypeSystem()); @@ -82,8 +89,6 @@ ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope, TargetSP target_sp(GetTargetSP()); SetName(ConstString(name)); - // m_value.SetContext(Value::eContextTypeClangType, - // m_compiler_type.GetOpaqueQualType()); m_value.SetCompilerType(m_compiler_type); lldb::addr_t load_address = m_address.GetLoadAddress(target_sp.get()); if (load_address != LLDB_INVALID_ADDRESS) { @@ -112,7 +117,7 @@ CompilerType ValueObjectMemory::GetCompilerTypeImpl() { ConstString ValueObjectMemory::GetTypeName() { if (m_type_sp) return m_type_sp->GetName(); - return m_compiler_type.GetConstTypeName(); + return m_compiler_type.GetTypeName(); } ConstString ValueObjectMemory::GetDisplayTypeName() { @@ -204,8 +209,6 @@ bool ValueObjectMemory::UpdateValue() { if (m_type_sp) value.SetContext(Value::eContextTypeLLDBType, m_type_sp.get()); else { - // value.SetContext(Value::eContextTypeClangType, - // m_compiler_type.GetOpaqueQualType()); value.SetCompilerType(m_compiler_type); } diff --git a/lldb/source/Core/ValueObjectRegister.cpp b/lldb/source/Core/ValueObjectRegister.cpp index 7e97df6d2a34..ec87c38fb367 100644 --- a/lldb/source/Core/ValueObjectRegister.cpp +++ b/lldb/source/Core/ValueObjectRegister.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectRegister.cpp ---------------------------------*- C++ -*-===// +//===-- ValueObjectRegister.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -35,86 +35,24 @@ class ExecutionContextScope; using namespace lldb; using namespace lldb_private; -#pragma mark ValueObjectRegisterContext - -ValueObjectRegisterContext::ValueObjectRegisterContext( - ValueObject &parent, RegisterContextSP ®_ctx) - : ValueObject(parent), m_reg_ctx_sp(reg_ctx) { - assert(reg_ctx); - m_name.SetCString("Registers"); - SetValueIsValid(true); -} - -ValueObjectRegisterContext::~ValueObjectRegisterContext() {} - -CompilerType ValueObjectRegisterContext::GetCompilerTypeImpl() { - return CompilerType(); -} - -ConstString ValueObjectRegisterContext::GetTypeName() { return ConstString(); } - -ConstString ValueObjectRegisterContext::GetDisplayTypeName() { - return ConstString(); -} - -ConstString ValueObjectRegisterContext::GetQualifiedTypeName() { - return ConstString(); -} - -size_t ValueObjectRegisterContext::CalculateNumChildren(uint32_t max) { - auto reg_set_count = m_reg_ctx_sp->GetRegisterSetCount(); - return reg_set_count <= max ? reg_set_count : max; -} - -uint64_t ValueObjectRegisterContext::GetByteSize() { return 0; } - -bool ValueObjectRegisterContext::UpdateValue() { - m_error.Clear(); - ExecutionContext exe_ctx(GetExecutionContextRef()); - StackFrame *frame = exe_ctx.GetFramePtr(); - if (frame) - m_reg_ctx_sp = frame->GetRegisterContext(); - else - m_reg_ctx_sp.reset(); - - if (m_reg_ctx_sp.get() == nullptr) { - SetValueIsValid(false); - m_error.SetErrorToGenericError(); - } else - SetValueIsValid(true); - - return m_error.Success(); -} - -ValueObject *ValueObjectRegisterContext::CreateChildAtIndex( - size_t idx, bool synthetic_array_member, int32_t synthetic_index) { - ValueObject *new_valobj = nullptr; - - const size_t num_children = GetNumChildren(); - if (idx < num_children) { - ExecutionContext exe_ctx(GetExecutionContextRef()); - new_valobj = new ValueObjectRegisterSet( - exe_ctx.GetBestExecutionContextScope(), m_reg_ctx_sp, idx); - } - - return new_valobj; -} - -#pragma mark - #pragma mark ValueObjectRegisterSet ValueObjectSP ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t set_idx) { - return (new ValueObjectRegisterSet(exe_scope, reg_ctx_sp, set_idx))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectRegisterSet(exe_scope, *manager_sp, reg_ctx_sp, + set_idx)) + ->GetSP(); } ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, lldb::RegisterContextSP ®_ctx, uint32_t reg_set_idx) - : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_set(nullptr), - m_reg_set_idx(reg_set_idx) { + : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), + m_reg_set(nullptr), m_reg_set_idx(reg_set_idx) { assert(reg_ctx); m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx); if (m_reg_set) { @@ -192,7 +130,7 @@ ValueObjectRegisterSet::GetChildMemberWithName(ConstString name, ValueObject *valobj = nullptr; if (m_reg_ctx_sp && m_reg_set) { const RegisterInfo *reg_info = - m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString()); + m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef()); if (reg_info != nullptr) valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info->kinds[eRegisterKindLLDB]); @@ -207,7 +145,7 @@ size_t ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) { if (m_reg_ctx_sp && m_reg_set) { const RegisterInfo *reg_info = - m_reg_ctx_sp->GetRegisterInfoByName(name.AsCString()); + m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef()); if (reg_info != nullptr) return reg_info->kinds[eRegisterKindLLDB]; } @@ -240,13 +178,16 @@ ValueObjectRegister::ValueObjectRegister(ValueObject &parent, ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, uint32_t reg_num) { - return (new ValueObjectRegister(exe_scope, reg_ctx_sp, reg_num))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_num)) + ->GetSP(); } ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, lldb::RegisterContextSP ®_ctx, uint32_t reg_num) - : ValueObject(exe_scope), m_reg_ctx_sp(reg_ctx), m_reg_info(), + : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(), m_reg_value(), m_type_name(), m_compiler_type() { assert(reg_ctx); ConstructObject(reg_num); @@ -278,7 +219,7 @@ CompilerType ValueObjectRegister::GetCompilerTypeImpl() { ConstString ValueObjectRegister::GetTypeName() { if (m_type_name.IsEmpty()) - m_type_name = GetCompilerType().GetConstTypeName(); + m_type_name = GetCompilerType().GetTypeName(); return m_type_name; } @@ -357,7 +298,6 @@ bool ValueObjectRegister::ResolveValue(Scalar &scalar) { } void ValueObjectRegister::GetExpressionPath(Stream &s, - bool qualify_cxx_base_classes, GetExpressionPathFormat epformat) { s.Printf("$%s", m_reg_info.name); } diff --git a/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/lldb/source/Core/ValueObjectSyntheticFilter.cpp index a30be1b08338..32d1e6ab8368 100644 --- a/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectSyntheticFilter.cpp --------------------------*- C++ -*-===// +//===-- ValueObjectSyntheticFilter.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,7 +14,6 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" -#include "lldb/Utility/SharingPtr.h" #include "lldb/Utility/Status.h" #include "llvm/ADT/STLExtras.h" @@ -54,7 +53,9 @@ ValueObjectSynthetic::ValueObjectSynthetic(ValueObject &parent, m_might_have_children(eLazyBoolCalculate), m_provides_value(eLazyBoolCalculate) { SetName(parent.GetName()); - CopyValueData(m_parent); + // Copying the data of an incomplete type won't work as it has no byte size. + if (m_parent->GetCompilerType().IsCompleteType()) + CopyValueData(m_parent); CreateSynthFilter(); } @@ -220,7 +221,9 @@ bool ValueObjectSynthetic::UpdateValue() { GetName().AsCString()); m_provides_value = eLazyBoolNo; - CopyValueData(m_parent); + // Copying the data of an incomplete type won't work as it has no byte size. + if (m_parent->GetCompilerType().IsCompleteType()) + CopyValueData(m_parent); } SetValueIsValid(true); diff --git a/lldb/source/Core/ValueObjectVariable.cpp b/lldb/source/Core/ValueObjectVariable.cpp index 240ebe1fdff3..0d1e7b047a0a 100644 --- a/lldb/source/Core/ValueObjectVariable.cpp +++ b/lldb/source/Core/ValueObjectVariable.cpp @@ -1,4 +1,4 @@ -//===-- ValueObjectVariable.cpp ---------------------------------*- C++ -*-===// +//===-- ValueObjectVariable.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,12 +50,14 @@ using namespace lldb_private; lldb::ValueObjectSP ValueObjectVariable::Create(ExecutionContextScope *exe_scope, const lldb::VariableSP &var_sp) { - return (new ValueObjectVariable(exe_scope, var_sp))->GetSP(); + auto manager_sp = ValueObjectManager::Create(); + return (new ValueObjectVariable(exe_scope, *manager_sp, var_sp))->GetSP(); } ValueObjectVariable::ValueObjectVariable(ExecutionContextScope *exe_scope, + ValueObjectManager &manager, const lldb::VariableSP &var_sp) - : ValueObject(exe_scope), m_variable_sp(var_sp) { + : ValueObject(exe_scope, manager), m_variable_sp(var_sp) { // Do not attempt to construct one of these objects with no variable! assert(m_variable_sp.get() != nullptr); m_name = var_sp->GetName(); @@ -166,6 +168,27 @@ bool ValueObjectVariable::UpdateValue() { Value::ValueType value_type = m_value.GetValueType(); + // The size of the buffer within m_value can be less than the size + // prescribed by its type. E.g. this can happen when an expression only + // partially describes an object (say, because it contains DW_OP_piece). + // + // In this case, grow m_value to the expected size. An alternative way to + // handle this is to teach Value::GetValueAsData() and ValueObjectChild + // not to read past the end of a host buffer, but this gets impractically + // complicated as a Value's host buffer may be shared with a distant + // ancestor or sibling in the ValueObject hierarchy. + // + // FIXME: When we grow m_value, we should represent the added bits as + // undefined somehow instead of as 0's. + if (value_type == Value::eValueTypeHostAddress && + compiler_type.IsValid()) { + if (size_t value_buf_size = m_value.GetBuffer().GetByteSize()) { + size_t value_size = m_value.GetValueByteSize(&m_error, &exe_ctx); + if (m_error.Success() && value_buf_size < value_size) + m_value.ResizeData(value_size); + } + } + Process *process = exe_ctx.GetProcessPtr(); const bool process_is_alive = process && process->IsAlive(); @@ -219,9 +242,64 @@ bool ValueObjectVariable::UpdateValue() { m_resolved_value.SetContext(Value::eContextTypeInvalid, nullptr); } } + return m_error.Success(); } +void ValueObjectVariable::DoUpdateChildrenAddressType(ValueObject &valobj) { + Value::ValueType value_type = valobj.GetValue().GetValueType(); + ExecutionContext exe_ctx(GetExecutionContextRef()); + Process *process = exe_ctx.GetProcessPtr(); + const bool process_is_alive = process && process->IsAlive(); + const uint32_t type_info = valobj.GetCompilerType().GetTypeInfo(); + const bool is_pointer_or_ref = + (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0; + + switch (value_type) { + case Value::eValueTypeFileAddress: + // If this type is a pointer, then its children will be considered load + // addresses if the pointer or reference is dereferenced, but only if + // the process is alive. + // + // There could be global variables like in the following code: + // struct LinkedListNode { Foo* foo; LinkedListNode* next; }; + // Foo g_foo1; + // Foo g_foo2; + // LinkedListNode g_second_node = { &g_foo2, NULL }; + // LinkedListNode g_first_node = { &g_foo1, &g_second_node }; + // + // When we aren't running, we should be able to look at these variables + // using the "target variable" command. Children of the "g_first_node" + // always will be of the same address type as the parent. But children + // of the "next" member of LinkedListNode will become load addresses if + // we have a live process, or remain a file address if it was a file + // address. + if (process_is_alive && is_pointer_or_ref) + valobj.SetAddressTypeOfChildren(eAddressTypeLoad); + else + valobj.SetAddressTypeOfChildren(eAddressTypeFile); + break; + case Value::eValueTypeHostAddress: + // Same as above for load addresses, except children of pointer or refs + // are always load addresses. Host addresses are used to store freeze + // dried variables. If this type is a struct, the entire struct + // contents will be copied into the heap of the + // LLDB process, but we do not currently follow any pointers. + if (is_pointer_or_ref) + valobj.SetAddressTypeOfChildren(eAddressTypeLoad); + else + valobj.SetAddressTypeOfChildren(eAddressTypeHost); + break; + case Value::eValueTypeLoadAddress: + case Value::eValueTypeScalar: + case Value::eValueTypeVector: + valobj.SetAddressTypeOfChildren(eAddressTypeLoad); + break; + } +} + + + bool ValueObjectVariable::IsInScope() { const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef(); if (exe_ctx_ref.HasFrameRef()) { |