diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-03-20 11:40:34 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2022-05-14 11:43:05 +0000 |
commit | 349cc55c9796c4596a5b9904cd3281af295f878f (patch) | |
tree | 410c5a785075730a35f1272ca6a7adf72222ad03 /contrib/llvm-project/lldb/source/Core | |
parent | cb2ae6163174b90e999326ecec3699ee093a5d43 (diff) | |
parent | c0981da47d5696fe36474fcf86b4ce03ae3ff818 (diff) |
Diffstat (limited to 'contrib/llvm-project/lldb/source/Core')
21 files changed, 2104 insertions, 498 deletions
diff --git a/contrib/llvm-project/lldb/source/Core/Address.cpp b/contrib/llvm-project/lldb/source/Core/Address.cpp index f0c7e2b34f99..122bed924b42 100644 --- a/contrib/llvm-project/lldb/source/Core/Address.cpp +++ b/contrib/llvm-project/lldb/source/Core/Address.cpp @@ -389,6 +389,19 @@ bool Address::SetOpcodeLoadAddress(lldb::addr_t load_addr, Target *target, return false; } +bool Address::GetDescription(Stream &s, Target &target, + DescriptionLevel level) const { + assert(level == eDescriptionLevelBrief && + "Non-brief descriptions not implemented"); + LineEntry line_entry; + if (CalculateSymbolContextLineEntry(line_entry)) { + s.Printf(" (%s:%u:%u)", line_entry.file.GetFilename().GetCString(), + line_entry.line, line_entry.column); + return true; + } + return false; +} + bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const { // If the section was nullptr, only load address is going to work unless we diff --git a/contrib/llvm-project/lldb/source/Core/AddressRange.cpp b/contrib/llvm-project/lldb/source/Core/AddressRange.cpp index af6e31a67da3..66dcda574890 100644 --- a/contrib/llvm-project/lldb/source/Core/AddressRange.cpp +++ b/contrib/llvm-project/lldb/source/Core/AddressRange.cpp @@ -59,15 +59,6 @@ bool AddressRange::Contains(const Address &addr) const { return ContainsFileAddress(addr); } -// -// bool -// AddressRange::Contains (const Address *addr) const -//{ -// if (addr) -// return Contains (*addr); -// return false; -//} - bool AddressRange::ContainsFileAddress(const Address &addr) const { if (addr.GetSection() == m_base_addr.GetSection()) return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); @@ -212,11 +203,3 @@ void AddressRange::DumpDebug(Stream *s) const { static_cast<void *>(m_base_addr.GetSection().get()), m_base_addr.GetOffset(), GetByteSize()); } -// -// bool -// lldb::operator== (const AddressRange& lhs, const AddressRange& rhs) -//{ -// if (lhs.GetBaseAddress() == rhs.GetBaseAddress()) -// return lhs.GetByteSize() == rhs.GetByteSize(); -// return false; -//} diff --git a/contrib/llvm-project/lldb/source/Core/Communication.cpp b/contrib/llvm-project/lldb/source/Core/Communication.cpp index 5640e0510cf1..0ad2751f24f0 100644 --- a/contrib/llvm-project/lldb/source/Core/Communication.cpp +++ b/contrib/llvm-project/lldb/source/Core/Communication.cpp @@ -176,8 +176,8 @@ size_t Communication::Write(const void *src, size_t src_len, std::lock_guard<std::mutex> guard(m_write_mutex); LLDB_LOG(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_COMMUNICATION), - "{0} Communication::Write (src = {1}, src_len = %" PRIu64 - ") connection = {2}", + "{0} Communication::Write (src = {1}, src_len = {2}" + ") connection = {3}", this, src, (uint64_t)src_len, connection_sp.get()); if (connection_sp) @@ -189,6 +189,16 @@ size_t Communication::Write(const void *src, size_t src_len, return 0; } +size_t Communication::WriteAll(const void *src, size_t src_len, + ConnectionStatus &status, Status *error_ptr) { + size_t total_written = 0; + do + total_written += Write(static_cast<const char *>(src) + total_written, + src_len - total_written, status, error_ptr); + while (status == eConnectionStatusSuccess && total_written < src_len); + return total_written; +} + bool Communication::StartReadThread(Status *error_ptr) { if (error_ptr) error_ptr->Clear(); diff --git a/contrib/llvm-project/lldb/source/Core/Debugger.cpp b/contrib/llvm-project/lldb/source/Core/Debugger.cpp index 17c3ba426f71..32dcfb1ce17b 100644 --- a/contrib/llvm-project/lldb/source/Core/Debugger.cpp +++ b/contrib/llvm-project/lldb/source/Core/Debugger.cpp @@ -488,7 +488,7 @@ void Debugger::Terminate() { "Debugger::Terminate called without a matching Debugger::Initialize!"); if (g_debugger_list_ptr && g_debugger_list_mutex_ptr) { - // Clear our master list of debugger objects + // Clear our global list of debugger objects { std::lock_guard<std::recursive_mutex> guard(*g_debugger_list_mutex_ptr); for (const auto &debugger : *g_debugger_list_ptr) @@ -723,10 +723,10 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) m_collection_sp->AppendProperty( ConstString("target"), ConstString("Settings specify to debugging targets."), true, - Target::GetGlobalProperties()->GetValueProperties()); + Target::GetGlobalProperties().GetValueProperties()); m_collection_sp->AppendProperty( ConstString("platform"), ConstString("Platform settings."), true, - Platform::GetGlobalPlatformProperties()->GetValueProperties()); + Platform::GetGlobalPlatformProperties().GetValueProperties()); m_collection_sp->AppendProperty( ConstString("symbols"), ConstString("Symbol lookup and cache settings."), true, ModuleList::GetGlobalModuleListProperties().GetValueProperties()); @@ -1243,7 +1243,7 @@ bool Debugger::EnableLog(llvm::StringRef channel, log_stream_sp = pos->second.lock(); if (!log_stream_sp) { File::OpenOptions flags = - File::eOpenOptionWrite | File::eOpenOptionCanCreate; + File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate; if (log_options & LLDB_LOG_OPTION_APPEND) flags |= File::eOpenOptionAppend; else @@ -1423,10 +1423,9 @@ void Debugger::HandleProcessEvent(const EventSP &event_sp) { output_stream_sp->PutCString(content_stream.GetString()); } } else { - error_stream_sp->Printf("Failed to print structured " - "data with plugin %s: %s", - plugin_sp->GetPluginName().AsCString(), - error.AsCString()); + error_stream_sp->Format("Failed to print structured " + "data with plugin {0}: {1}", + plugin_sp->GetPluginName(), error); } } } diff --git a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp index 704b3df4b2ac..00d92053bc4f 100644 --- a/contrib/llvm-project/lldb/source/Core/Disassembler.cpp +++ b/contrib/llvm-project/lldb/source/Core/Disassembler.cpp @@ -64,9 +64,8 @@ DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch, DisassemblerCreateInstance create_callback = nullptr; if (plugin_name) { - ConstString const_plugin_name(plugin_name); - create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName( - const_plugin_name); + create_callback = + PluginManager::GetDisassemblerCreateCallbackForPluginName(plugin_name); if (create_callback) { DisassemblerSP disassembler_sp(create_callback(arch, flavor)); @@ -1123,6 +1122,10 @@ bool PseudoInstruction::HasDelaySlot() { return false; } +bool PseudoInstruction::IsLoad() { return false; } + +bool PseudoInstruction::IsAuthenticated() { return false; } + size_t PseudoInstruction::Decode(const lldb_private::Disassembler &disassembler, const lldb_private::DataExtractor &data, lldb::offset_t data_offset) { diff --git a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp index 10d2b7207018..1c7b9125e4d1 100644 --- a/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp +++ b/contrib/llvm-project/lldb/source/Core/DynamicLoader.cpp @@ -30,13 +30,11 @@ using namespace lldb; using namespace lldb_private; DynamicLoader *DynamicLoader::FindPlugin(Process *process, - const char *plugin_name) { + llvm::StringRef plugin_name) { DynamicLoaderCreateInstance create_callback = nullptr; - if (plugin_name) { - ConstString const_plugin_name(plugin_name); + if (!plugin_name.empty()) { create_callback = - PluginManager::GetDynamicLoaderCreateCallbackForPluginName( - const_plugin_name); + PluginManager::GetDynamicLoaderCreateCallbackForPluginName(plugin_name); if (create_callback) { std::unique_ptr<DynamicLoader> instance_up( create_callback(process, true)); diff --git a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp index 9b9111408209..c352b0129382 100644 --- a/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp +++ b/contrib/llvm-project/lldb/source/Core/EmulateInstruction.cpp @@ -46,10 +46,9 @@ EmulateInstruction::FindPlugin(const ArchSpec &arch, const char *plugin_name) { EmulateInstructionCreateInstance create_callback = nullptr; if (plugin_name) { - ConstString const_plugin_name(plugin_name); create_callback = PluginManager::GetEmulateInstructionCreateCallbackForPluginName( - const_plugin_name); + plugin_name); if (create_callback) { EmulateInstruction *emulate_insn_ptr = create_callback(arch, supported_inst_type); diff --git a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp index c6f05d43a2a7..c35b17990842 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandler.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandler.cpp @@ -251,8 +251,7 @@ IOHandlerEditline::IOHandlerEditline( m_delegate(delegate), m_prompt(), m_continuation_prompt(), m_current_lines_ptr(nullptr), m_base_line_number(line_number_start), m_curr_line_idx(UINT32_MAX), m_multi_line(multi_line), - m_color_prompts(color_prompts), m_interrupt_exits(true), - m_editing(false) { + m_color_prompts(color_prompts), m_interrupt_exits(true) { SetPrompt(prompt); #if LLDB_ENABLE_LIBEDIT @@ -399,7 +398,6 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) { } if (!got_line && in) { - m_editing = true; while (!got_line) { char *r = fgets(buffer, sizeof(buffer), in); #ifdef _WIN32 @@ -425,7 +423,6 @@ bool IOHandlerEditline::GetLine(std::string &line, bool &interrupted) { m_line_buffer += buffer; got_line = SplitLine(m_line_buffer); } - m_editing = false; } if (got_line) { diff --git a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp index 4bed788d4863..9122117ef5ff 100644 --- a/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp +++ b/contrib/llvm-project/lldb/source/Core/IOHandlerCursesGUI.cpp @@ -36,6 +36,7 @@ #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/OptionGroupPlatform.h" #if LLDB_ENABLE_CURSES #include "lldb/Breakpoint/BreakpointLocation.h" @@ -44,6 +45,7 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectRegister.h" #include "lldb/Symbol/Block.h" +#include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/VariableList.h" @@ -83,10 +85,15 @@ using llvm::StringRef; // we may want curses to be disabled for some builds for instance, windows #if LLDB_ENABLE_CURSES +#define KEY_CTRL_A 1 +#define KEY_CTRL_E 5 +#define KEY_CTRL_K 11 #define KEY_RETURN 10 #define KEY_ESCAPE 27 +#define KEY_DELETE 127 #define KEY_SHIFT_TAB (KEY_MAX + 1) +#define KEY_ALT_ENTER (KEY_MAX + 2) namespace curses { class Menu; @@ -342,15 +349,30 @@ protected: // A surface is an abstraction for something than can be drawn on. The surface // have a width, a height, a cursor position, and a multitude of drawing // operations. This type should be sub-classed to get an actually useful ncurses -// object, such as a Window, SubWindow, Pad, or a SubPad. +// object, such as a Window or a Pad. class Surface { public: - Surface() : m_window(nullptr) {} + enum class Type { Window, Pad }; + + Surface(Surface::Type type) : m_type(type), m_window(nullptr) {} WINDOW *get() { return m_window; } operator WINDOW *() { return m_window; } + Surface SubSurface(Rect bounds) { + Surface subSurface(m_type); + if (m_type == Type::Pad) + subSurface.m_window = + ::subpad(m_window, bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + else + subSurface.m_window = + ::derwin(m_window, bounds.size.height, bounds.size.width, + bounds.origin.y, bounds.origin.x); + return subSurface; + } + // Copy a region of the surface to another surface. void CopyToSurface(Surface &target, Point source_origin, Point target_origin, Size size) { @@ -534,41 +556,32 @@ public: } protected: + Type m_type; WINDOW *m_window; }; class Pad : public Surface { public: - Pad(Size size) { m_window = ::newpad(size.height, size.width); } - - ~Pad() { ::delwin(m_window); } -}; - -class SubPad : public Surface { -public: - SubPad(Pad &pad, Rect bounds) { - m_window = ::subpad(pad.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); - } - SubPad(SubPad &subpad, Rect bounds) { - m_window = ::subpad(subpad.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); + Pad(Size size) : Surface(Surface::Type::Pad) { + m_window = ::newpad(size.height, size.width); } - ~SubPad() { ::delwin(m_window); } + ~Pad() { ::delwin(m_window); } }; class Window : public Surface { public: Window(const char *name) - : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(), - m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_panel(nullptr), + m_parent(nullptr), m_subwindows(), m_delegate_sp(), + m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(false), m_needs_update(true), m_can_activate(true), m_is_subwin(false) {} Window(const char *name, WINDOW *w, bool del = true) - : m_name(name), m_panel(nullptr), m_parent(nullptr), m_subwindows(), - m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_panel(nullptr), + m_parent(nullptr), m_subwindows(), m_delegate_sp(), + m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(del), m_needs_update(true), m_can_activate(true), m_is_subwin(false) { if (w) @@ -576,8 +589,8 @@ public: } Window(const char *name, const Rect &bounds) - : m_name(name), m_parent(nullptr), m_subwindows(), m_delegate_sp(), - m_curr_active_window_idx(UINT32_MAX), + : Surface(Surface::Type::Window), m_name(name), m_parent(nullptr), + m_subwindows(), m_delegate_sp(), m_curr_active_window_idx(UINT32_MAX), m_prev_active_window_idx(UINT32_MAX), m_delete(true), m_needs_update(true), m_can_activate(true), m_is_subwin(false) { Reset(::newwin(bounds.size.height, bounds.size.width, bounds.origin.y, @@ -969,20 +982,6 @@ private: const Window &operator=(const Window &) = delete; }; -class DerivedWindow : public Surface { -public: - DerivedWindow(Window &window, Rect bounds) { - m_window = ::derwin(window.get(), bounds.size.height, bounds.size.width, - bounds.origin.y, bounds.origin.x); - } - DerivedWindow(DerivedWindow &derived_window, Rect bounds) { - m_window = ::derwin(derived_window.get(), bounds.size.height, - bounds.size.width, bounds.origin.y, bounds.origin.x); - } - - ~DerivedWindow() { ::delwin(m_window); } -}; - ///////// // Forms ///////// @@ -1024,7 +1023,7 @@ public: // Draw the field in the given subpad surface. The surface have a height that // is equal to the height returned by FieldDelegateGetHeight(). If the field // is selected in the form window, then is_selected will be true. - virtual void FieldDelegateDraw(SubPad &surface, bool is_selected) = 0; + virtual void FieldDelegateDraw(Surface &surface, bool is_selected) = 0; // Handle the key that wasn't handled by the form window or a container field. virtual HandleCharResult FieldDelegateHandleChar(int key) { @@ -1111,11 +1110,12 @@ public: int GetContentLength() { return m_content.length(); } - void DrawContent(SubPad &surface, bool is_selected) { + void DrawContent(Surface &surface, bool is_selected) { + UpdateScrolling(surface.GetWidth()); + surface.MoveCursor(0, 0); const char *text = m_content.c_str() + m_first_visibile_char; surface.PutCString(text, surface.GetWidth()); - m_last_drawn_content_width = surface.GetWidth(); // Highlight the cursor. surface.MoveCursor(GetCursorXPosition(), 0); @@ -1130,17 +1130,17 @@ public: surface.AttributeOff(A_REVERSE); } - void DrawField(SubPad &surface, bool is_selected) { + void DrawField(Surface &surface, bool is_selected) { surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); content_bounds.Inset(1, 1); - SubPad content_surface = SubPad(surface, content_bounds); + Surface content_surface = surface.SubSurface(content_bounds); DrawContent(content_surface, is_selected); } - void DrawError(SubPad &surface) { + void DrawError(Surface &surface) { if (!FieldDelegateHasError()) return; surface.MoveCursor(0, 0); @@ -1151,17 +1151,33 @@ public: surface.AttributeOff(COLOR_PAIR(RedOnBlack)); } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { Rect frame = surface.GetFrame(); Rect field_bounds, error_bounds; frame.HorizontalSplit(GetFieldHeight(), field_bounds, error_bounds); - SubPad field_surface = SubPad(surface, field_bounds); - SubPad error_surface = SubPad(surface, error_bounds); + Surface field_surface = surface.SubSurface(field_bounds); + Surface error_surface = surface.SubSurface(error_bounds); DrawField(field_surface, is_selected); DrawError(error_surface); } + // Get the position of the last visible character. + int GetLastVisibleCharPosition(int width) { + int position = m_first_visibile_char + width - 1; + return std::min(position, GetContentLength()); + } + + void UpdateScrolling(int width) { + if (m_cursor_position < m_first_visibile_char) { + m_first_visibile_char = m_cursor_position; + return; + } + + if (m_cursor_position > GetLastVisibleCharPosition(width)) + m_first_visibile_char = m_cursor_position - (width - 1); + } + // The cursor is allowed to move one character past the string. // m_cursor_position is in range [0, GetContentLength()]. void MoveCursorRight() { @@ -1174,47 +1190,65 @@ public: m_cursor_position--; } - // If the cursor moved past the last visible character, scroll right by one - // character. - void ScrollRightIfNeeded() { - if (m_cursor_position - m_first_visibile_char == m_last_drawn_content_width) - m_first_visibile_char++; - } + void MoveCursorToStart() { m_cursor_position = 0; } + + void MoveCursorToEnd() { m_cursor_position = GetContentLength(); } void ScrollLeft() { if (m_first_visibile_char > 0) m_first_visibile_char--; } - // If the cursor moved past the first visible character, scroll left by one - // character. - void ScrollLeftIfNeeded() { - if (m_cursor_position < m_first_visibile_char) - m_first_visibile_char--; - } - - // Insert a character at the current cursor position, advance the cursor - // position, and make sure to scroll right if needed. + // Insert a character at the current cursor position and advance the cursor + // position. void InsertChar(char character) { m_content.insert(m_cursor_position, 1, character); m_cursor_position++; - ScrollRightIfNeeded(); + ClearError(); } // Remove the character before the cursor position, retreat the cursor - // position, and make sure to scroll left if needed. - void RemoveChar() { + // position, and scroll left. + void RemovePreviousChar() { if (m_cursor_position == 0) return; m_content.erase(m_cursor_position - 1, 1); m_cursor_position--; ScrollLeft(); + ClearError(); + } + + // Remove the character after the cursor position. + void RemoveNextChar() { + if (m_cursor_position == GetContentLength()) + return; + + m_content.erase(m_cursor_position, 1); + ClearError(); + } + + // Clear characters from the current cursor position to the end. + void ClearToEnd() { + m_content.erase(m_cursor_position); + ClearError(); + } + + void Clear() { + m_content.clear(); + m_cursor_position = 0; + ClearError(); } // True if the key represents a char that can be inserted in the field // content, false otherwise. - virtual bool IsAcceptableChar(int key) { return isprint(key); } + virtual bool IsAcceptableChar(int key) { + // The behavior of isprint is undefined when the value is not representable + // as an unsigned char. So explicitly check for non-ascii key codes. + if (key > 127) + return false; + return isprint(key); + } HandleCharResult FieldDelegateHandleChar(int key) override { if (IsAcceptableChar(key)) { @@ -1224,17 +1258,36 @@ public: } switch (key) { + case KEY_HOME: + case KEY_CTRL_A: + MoveCursorToStart(); + return eKeyHandled; + case KEY_END: + case KEY_CTRL_E: + MoveCursorToEnd(); + return eKeyHandled; case KEY_RIGHT: + case KEY_SF: MoveCursorRight(); - ScrollRightIfNeeded(); return eKeyHandled; case KEY_LEFT: + case KEY_SR: MoveCursorLeft(); - ScrollLeftIfNeeded(); return eKeyHandled; case KEY_BACKSPACE: - ClearError(); - RemoveChar(); + case KEY_DELETE: + RemovePreviousChar(); + return eKeyHandled; + case KEY_DC: + RemoveNextChar(); + return eKeyHandled; + case KEY_EOL: + case KEY_CTRL_K: + ClearToEnd(); + return eKeyHandled; + case KEY_DL: + case KEY_CLEAR: + Clear(); return eKeyHandled; default: break; @@ -1259,6 +1312,14 @@ public: const std::string &GetText() { return m_content; } + void SetText(const char *text) { + if (text == nullptr) { + m_content.clear(); + return; + } + m_content = text; + } + protected: std::string m_label; bool m_required; @@ -1269,9 +1330,6 @@ protected: int m_cursor_position; // The index of the first visible character in the content. int m_first_visibile_char; - // The width of the fields content that was last drawn. Width can change, so - // this is used to determine if scrolling is needed dynamically. - int m_last_drawn_content_width; // Optional error message. If empty, field is considered to have no error. std::string m_error; }; @@ -1405,7 +1463,7 @@ public: // Boolean fields are have a single line. int FieldDelegateGetHeight() override { return 1; } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { surface.MoveCursor(0, 0); surface.PutChar('['); if (is_selected) @@ -1485,7 +1543,7 @@ public: return std::min(index, GetNumberOfChoices()) - 1; } - void DrawContent(SubPad &surface, bool is_selected) { + void DrawContent(Surface &surface, bool is_selected) { int choices_to_draw = GetLastVisibleChoice() - m_first_visibile_choice + 1; for (int i = 0; i < choices_to_draw; i++) { surface.MoveCursor(0, i); @@ -1501,14 +1559,14 @@ public: } } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { UpdateScrolling(); surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); content_bounds.Inset(1, 1); - SubPad content_surface = SubPad(surface, content_bounds); + Surface content_surface = surface.SubSurface(content_bounds); DrawContent(content_surface, is_selected); } @@ -1584,8 +1642,10 @@ public: std::vector<std::string> GetPossiblePluginNames() { std::vector<std::string> names; size_t i = 0; - while (auto name = PluginManager::GetPlatformPluginNameAtIndex(i++)) - names.push_back(name); + for (llvm::StringRef name = + PluginManager::GetPlatformPluginNameAtIndex(i++); + !name.empty(); name = PluginManager::GetProcessPluginNameAtIndex(i++)) + names.push_back(name.str()); return names; } @@ -1605,8 +1665,9 @@ public: names.push_back("<default>"); size_t i = 0; - while (auto name = PluginManager::GetProcessPluginNameAtIndex(i++)) - names.push_back(name); + for (llvm::StringRef name = PluginManager::GetProcessPluginNameAtIndex(i++); + !name.empty(); name = PluginManager::GetProcessPluginNameAtIndex(i++)) + names.push_back(name.str()); return names; } @@ -1618,6 +1679,33 @@ public: } }; +class LazyBooleanFieldDelegate : public ChoicesFieldDelegate { +public: + LazyBooleanFieldDelegate(const char *label, const char *calculate_label) + : ChoicesFieldDelegate(label, 3, GetPossibleOptions(calculate_label)) {} + + static constexpr const char *kNo = "No"; + static constexpr const char *kYes = "Yes"; + + std::vector<std::string> GetPossibleOptions(const char *calculate_label) { + std::vector<std::string> options; + options.push_back(calculate_label); + options.push_back(kYes); + options.push_back(kNo); + return options; + } + + LazyBool GetLazyBoolean() { + std::string choice = GetChoiceContent(); + if (choice == kNo) + return eLazyBoolNo; + else if (choice == kYes) + return eLazyBoolYes; + else + return eLazyBoolCalculate; + } +}; + template <class T> class ListFieldDelegate : public FieldDelegate { public: ListFieldDelegate(const char *label, T default_field) @@ -1683,7 +1771,7 @@ public: return context; } - void DrawRemoveButton(SubPad &surface, int highlight) { + void DrawRemoveButton(Surface &surface, int highlight) { surface.MoveCursor(1, surface.GetHeight() / 2); if (highlight) surface.AttributeOn(A_REVERSE); @@ -1692,7 +1780,7 @@ public: surface.AttributeOff(A_REVERSE); } - void DrawFields(SubPad &surface, bool is_selected) { + void DrawFields(Surface &surface, bool is_selected) { int line = 0; int width = surface.GetWidth(); for (int i = 0; i < GetNumberOfFields(); i++) { @@ -1701,8 +1789,8 @@ public: Rect field_bounds, remove_button_bounds; bounds.VerticalSplit(bounds.size.width - sizeof(" [Remove]"), field_bounds, remove_button_bounds); - SubPad field_surface = SubPad(surface, field_bounds); - SubPad remove_button_surface = SubPad(surface, remove_button_bounds); + Surface field_surface = surface.SubSurface(field_bounds); + Surface remove_button_surface = surface.SubSurface(remove_button_bounds); bool is_element_selected = m_selection_index == i && is_selected; bool is_field_selected = @@ -1717,7 +1805,7 @@ public: } } - void DrawNewButton(SubPad &surface, bool is_selected) { + void DrawNewButton(Surface &surface, bool is_selected) { const char *button_text = "[New]"; int x = (surface.GetWidth() - sizeof(button_text) - 1) / 2; surface.MoveCursor(x, 0); @@ -1730,7 +1818,7 @@ public: surface.AttributeOff(A_REVERSE); } - void FieldDelegateDraw(SubPad &surface, bool is_selected) override { + void FieldDelegateDraw(Surface &surface, bool is_selected) override { surface.TitledBox(m_label.c_str()); Rect content_bounds = surface.GetFrame(); @@ -1738,8 +1826,8 @@ public: Rect fields_bounds, new_button_bounds; content_bounds.HorizontalSplit(content_bounds.size.height - 1, fields_bounds, new_button_bounds); - SubPad fields_surface = SubPad(surface, fields_bounds); - SubPad new_button_surface = SubPad(surface, new_button_bounds); + Surface fields_surface = surface.SubSurface(fields_bounds); + Surface new_button_surface = surface.SubSurface(new_button_bounds); DrawFields(fields_surface, is_selected); DrawNewButton(new_button_surface, is_selected); @@ -1822,6 +1910,31 @@ public: return eKeyHandled; } + // If the last element of the field is selected and it didn't handle the key. + // Select the next field or new button if the selected field is the last one. + HandleCharResult SelectNextInList(int key) { + assert(m_selection_type == SelectionType::Field); + + FieldDelegate &field = m_fields[m_selection_index]; + if (field.FieldDelegateHandleChar(key) == eKeyHandled) + return eKeyHandled; + + if (!field.FieldDelegateOnLastOrOnlyElement()) + return eKeyNotHandled; + + field.FieldDelegateExitCallback(); + + if (m_selection_index == GetNumberOfFields() - 1) { + m_selection_type = SelectionType::NewButton; + return eKeyHandled; + } + + m_selection_index++; + FieldDelegate &next_field = m_fields[m_selection_index]; + next_field.FieldDelegateSelectFirstElement(); + return eKeyHandled; + } + HandleCharResult FieldDelegateHandleChar(int key) override { switch (key) { case '\r': @@ -1834,16 +1947,14 @@ public: case SelectionType::RemoveButton: RemoveField(); return eKeyHandled; - default: - break; + case SelectionType::Field: + return SelectNextInList(key); } break; case '\t': - SelectNext(key); - return eKeyHandled; + return SelectNext(key); case KEY_SHIFT_TAB: - SelectPrevious(key); - return eKeyHandled; + return SelectPrevious(key); default: break; } @@ -1908,6 +2019,241 @@ protected: SelectionType m_selection_type; }; +class ArgumentsFieldDelegate : public ListFieldDelegate<TextFieldDelegate> { +public: + ArgumentsFieldDelegate() + : ListFieldDelegate("Arguments", + TextFieldDelegate("Argument", "", false)) {} + + Args GetArguments() { + Args arguments; + for (int i = 0; i < GetNumberOfFields(); i++) { + arguments.AppendArgument(GetField(i).GetText()); + } + return arguments; + } + + void AddArguments(const Args &arguments) { + for (size_t i = 0; i < arguments.GetArgumentCount(); i++) { + AddNewField(); + TextFieldDelegate &field = GetField(GetNumberOfFields() - 1); + field.SetText(arguments.GetArgumentAtIndex(i)); + } + } +}; + +template <class KeyFieldDelegateType, class ValueFieldDelegateType> +class MappingFieldDelegate : public FieldDelegate { +public: + MappingFieldDelegate(KeyFieldDelegateType key_field, + ValueFieldDelegateType value_field) + : m_key_field(key_field), m_value_field(value_field), + m_selection_type(SelectionType::Key) {} + + // Signify which element is selected. The key field or its value field. + enum class SelectionType { Key, Value }; + + // A mapping field is drawn as two text fields with a right arrow in between. + // The first field stores the key of the mapping and the second stores the + // value if the mapping. + // + // __[Key]_____________ __[Value]___________ + // | | > | | + // |__________________| |__________________| + // - Error message if it exists. + + // The mapping field has a height that is equal to the maximum height between + // the key and value fields. + int FieldDelegateGetHeight() override { + return std::max(m_key_field.FieldDelegateGetHeight(), + m_value_field.FieldDelegateGetHeight()); + } + + void DrawArrow(Surface &surface) { + surface.MoveCursor(0, 1); + surface.PutChar(ACS_RARROW); + } + + void FieldDelegateDraw(Surface &surface, bool is_selected) override { + Rect bounds = surface.GetFrame(); + Rect key_field_bounds, arrow_and_value_field_bounds; + bounds.VerticalSplit(bounds.size.width / 2, key_field_bounds, + arrow_and_value_field_bounds); + Rect arrow_bounds, value_field_bounds; + arrow_and_value_field_bounds.VerticalSplit(1, arrow_bounds, + value_field_bounds); + + Surface key_field_surface = surface.SubSurface(key_field_bounds); + Surface arrow_surface = surface.SubSurface(arrow_bounds); + Surface value_field_surface = surface.SubSurface(value_field_bounds); + + bool key_is_selected = + m_selection_type == SelectionType::Key && is_selected; + m_key_field.FieldDelegateDraw(key_field_surface, key_is_selected); + DrawArrow(arrow_surface); + bool value_is_selected = + m_selection_type == SelectionType::Value && is_selected; + m_value_field.FieldDelegateDraw(value_field_surface, value_is_selected); + } + + HandleCharResult SelectNext(int key) { + if (FieldDelegateOnLastOrOnlyElement()) + return eKeyNotHandled; + + if (!m_key_field.FieldDelegateOnLastOrOnlyElement()) { + return m_key_field.FieldDelegateHandleChar(key); + } + + m_key_field.FieldDelegateExitCallback(); + m_selection_type = SelectionType::Value; + m_value_field.FieldDelegateSelectFirstElement(); + return eKeyHandled; + } + + HandleCharResult SelectPrevious(int key) { + if (FieldDelegateOnFirstOrOnlyElement()) + return eKeyNotHandled; + + if (!m_value_field.FieldDelegateOnFirstOrOnlyElement()) { + return m_value_field.FieldDelegateHandleChar(key); + } + + m_value_field.FieldDelegateExitCallback(); + m_selection_type = SelectionType::Key; + m_key_field.FieldDelegateSelectLastElement(); + return eKeyHandled; + } + + // If the value field is selected, pass the key to it. If the key field is + // selected, its last element is selected, and it didn't handle the key, then + // select its corresponding value field. + HandleCharResult SelectNextField(int key) { + if (m_selection_type == SelectionType::Value) { + return m_value_field.FieldDelegateHandleChar(key); + } + + if (m_key_field.FieldDelegateHandleChar(key) == eKeyHandled) + return eKeyHandled; + + if (!m_key_field.FieldDelegateOnLastOrOnlyElement()) + return eKeyNotHandled; + + m_key_field.FieldDelegateExitCallback(); + m_selection_type = SelectionType::Value; + m_value_field.FieldDelegateSelectFirstElement(); + return eKeyHandled; + } + + HandleCharResult FieldDelegateHandleChar(int key) override { + switch (key) { + case KEY_RETURN: + return SelectNextField(key); + case '\t': + return SelectNext(key); + case KEY_SHIFT_TAB: + return SelectPrevious(key); + default: + break; + } + + // If the key wasn't handled, pass the key to the selected field. + if (m_selection_type == SelectionType::Key) + return m_key_field.FieldDelegateHandleChar(key); + else + return m_value_field.FieldDelegateHandleChar(key); + + return eKeyNotHandled; + } + + bool FieldDelegateOnFirstOrOnlyElement() override { + return m_selection_type == SelectionType::Key; + } + + bool FieldDelegateOnLastOrOnlyElement() override { + return m_selection_type == SelectionType::Value; + } + + void FieldDelegateSelectFirstElement() override { + m_selection_type = SelectionType::Key; + } + + void FieldDelegateSelectLastElement() override { + m_selection_type = SelectionType::Value; + } + + bool FieldDelegateHasError() override { + return m_key_field.FieldDelegateHasError() || + m_value_field.FieldDelegateHasError(); + } + + KeyFieldDelegateType &GetKeyField() { return m_key_field; } + + ValueFieldDelegateType &GetValueField() { return m_value_field; } + +protected: + KeyFieldDelegateType m_key_field; + ValueFieldDelegateType m_value_field; + // See SelectionType class enum. + SelectionType m_selection_type; +}; + +class EnvironmentVariableNameFieldDelegate : public TextFieldDelegate { +public: + EnvironmentVariableNameFieldDelegate(const char *content) + : TextFieldDelegate("Name", content, true) {} + + // Environment variable names can't contain an equal sign. + bool IsAcceptableChar(int key) override { + return TextFieldDelegate::IsAcceptableChar(key) && key != '='; + } + + const std::string &GetName() { return m_content; } +}; + +class EnvironmentVariableFieldDelegate + : public MappingFieldDelegate<EnvironmentVariableNameFieldDelegate, + TextFieldDelegate> { +public: + EnvironmentVariableFieldDelegate() + : MappingFieldDelegate( + EnvironmentVariableNameFieldDelegate(""), + TextFieldDelegate("Value", "", /*required=*/false)) {} + + const std::string &GetName() { return GetKeyField().GetName(); } + + const std::string &GetValue() { return GetValueField().GetText(); } + + void SetName(const char *name) { return GetKeyField().SetText(name); } + + void SetValue(const char *value) { return GetValueField().SetText(value); } +}; + +class EnvironmentVariableListFieldDelegate + : public ListFieldDelegate<EnvironmentVariableFieldDelegate> { +public: + EnvironmentVariableListFieldDelegate(const char *label) + : ListFieldDelegate(label, EnvironmentVariableFieldDelegate()) {} + + Environment GetEnvironment() { + Environment environment; + for (int i = 0; i < GetNumberOfFields(); i++) { + environment.insert( + std::make_pair(GetField(i).GetName(), GetField(i).GetValue())); + } + return environment; + } + + void AddEnvironmentVariables(const Environment &environment) { + for (auto &variable : environment) { + AddNewField(); + EnvironmentVariableFieldDelegate &field = + GetField(GetNumberOfFields() - 1); + field.SetName(variable.getKey().str().c_str()); + field.SetValue(variable.getValue().c_str()); + } + } +}; + class FormAction { public: FormAction(const char *label, std::function<void(Window &)> action) @@ -1917,7 +2263,7 @@ public: } // Draw a centered [Label]. - void Draw(SubPad &surface, bool is_selected) { + void Draw(Surface &surface, bool is_selected) { int x = (surface.GetWidth() - m_label.length()) / 2; surface.MoveCursor(x, 0); if (is_selected) @@ -1973,6 +2319,7 @@ public: // action that requires valid fields. bool CheckFieldsValidity() { for (int i = 0; i < GetNumberOfFields(); i++) { + GetField(i)->FieldDelegateExitCallback(); if (GetField(i)->FieldDelegateHasError()) { SetError("Some fields are invalid!"); return false; @@ -2030,6 +2377,14 @@ public: return delegate; } + LazyBooleanFieldDelegate *AddLazyBooleanField(const char *label, + const char *calculate_label) { + LazyBooleanFieldDelegate *delegate = + new LazyBooleanFieldDelegate(label, calculate_label); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + ChoicesFieldDelegate *AddChoicesField(const char *label, int height, std::vector<std::string> choices) { ChoicesFieldDelegate *delegate = @@ -2059,6 +2414,43 @@ public: return delegate; } + ArgumentsFieldDelegate *AddArgumentsField() { + ArgumentsFieldDelegate *delegate = new ArgumentsFieldDelegate(); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + template <class K, class V> + MappingFieldDelegate<K, V> *AddMappingField(K key_field, V value_field) { + MappingFieldDelegate<K, V> *delegate = + new MappingFieldDelegate<K, V>(key_field, value_field); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + EnvironmentVariableNameFieldDelegate * + AddEnvironmentVariableNameField(const char *content) { + EnvironmentVariableNameFieldDelegate *delegate = + new EnvironmentVariableNameFieldDelegate(content); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + EnvironmentVariableFieldDelegate *AddEnvironmentVariableField() { + EnvironmentVariableFieldDelegate *delegate = + new EnvironmentVariableFieldDelegate(); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + + EnvironmentVariableListFieldDelegate * + AddEnvironmentVariableListField(const char *label) { + EnvironmentVariableListFieldDelegate *delegate = + new EnvironmentVariableListFieldDelegate(label); + m_fields.push_back(FieldDelegateUP(delegate)); + return delegate; + } + // Factory methods for adding actions. void AddAction(const char *label, std::function<void(Window &)> action) { @@ -2156,7 +2548,7 @@ public: return context; } - void UpdateScrolling(DerivedWindow &surface) { + void UpdateScrolling(Surface &surface) { ScrollContext context = GetScrollContext(); int content_height = GetContentHeight(); int surface_height = surface.GetHeight(); @@ -2180,7 +2572,7 @@ public: } } - void DrawError(SubPad &surface) { + void DrawError(Surface &surface) { if (!m_delegate_sp->HasError()) return; surface.MoveCursor(0, 0); @@ -2194,7 +2586,7 @@ public: surface.HorizontalLine(surface.GetWidth()); } - void DrawFields(SubPad &surface) { + void DrawFields(Surface &surface) { int line = 0; int width = surface.GetWidth(); bool a_field_is_selected = m_selection_type == SelectionType::Field; @@ -2205,13 +2597,13 @@ public: bool is_field_selected = a_field_is_selected && m_selection_index == i; int height = field->FieldDelegateGetHeight(); Rect bounds = Rect(Point(0, line), Size(width, height)); - SubPad field_surface = SubPad(surface, bounds); + Surface field_surface = surface.SubSurface(bounds); field->FieldDelegateDraw(field_surface, is_field_selected); line += height; } } - void DrawActions(SubPad &surface) { + void DrawActions(Surface &surface) { int number_of_actions = m_delegate_sp->GetNumberOfActions(); int width = surface.GetWidth() / number_of_actions; bool an_action_is_selected = m_selection_type == SelectionType::Action; @@ -2220,19 +2612,19 @@ public: bool is_action_selected = an_action_is_selected && m_selection_index == i; FormAction &action = m_delegate_sp->GetAction(i); Rect bounds = Rect(Point(x, 0), Size(width, 1)); - SubPad action_surface = SubPad(surface, bounds); + Surface action_surface = surface.SubSurface(bounds); action.Draw(action_surface, is_action_selected); x += width; } } - void DrawElements(SubPad &surface) { + void DrawElements(Surface &surface) { Rect frame = surface.GetFrame(); Rect fields_bounds, actions_bounds; frame.HorizontalSplit(surface.GetHeight() - GetActionsHeight(), fields_bounds, actions_bounds); - SubPad fields_surface = SubPad(surface, fields_bounds); - SubPad actions_surface = SubPad(surface, actions_bounds); + Surface fields_surface = surface.SubSurface(fields_bounds); + Surface actions_surface = surface.SubSurface(actions_bounds); DrawFields(fields_surface); DrawActions(actions_surface); @@ -2241,7 +2633,7 @@ public: // Contents are first drawn on a pad. Then a subset of that pad is copied to // the derived window starting at the first visible line. This essentially // provides scrolling functionality. - void DrawContent(DerivedWindow &surface) { + void DrawContent(Surface &surface) { UpdateScrolling(surface); int width = surface.GetWidth(); @@ -2251,8 +2643,8 @@ public: Rect frame = pad.GetFrame(); Rect error_bounds, elements_bounds; frame.HorizontalSplit(GetErrorHeight(), error_bounds, elements_bounds); - SubPad error_surface = SubPad(pad, error_bounds); - SubPad elements_surface = SubPad(pad, elements_bounds); + Surface error_surface = pad.SubSurface(error_bounds); + Surface elements_surface = pad.SubSurface(elements_bounds); DrawError(error_surface); DrawElements(elements_surface); @@ -2262,17 +2654,28 @@ public: Size(width, copy_height)); } + void DrawSubmitHint(Surface &surface, bool is_active) { + surface.MoveCursor(2, surface.GetHeight() - 1); + if (is_active) + surface.AttributeOn(A_BOLD | COLOR_PAIR(BlackOnWhite)); + surface.Printf("[Press Alt+Enter to %s]", + m_delegate_sp->GetAction(0).GetLabel().c_str()); + if (is_active) + surface.AttributeOff(A_BOLD | COLOR_PAIR(BlackOnWhite)); + } + bool WindowDelegateDraw(Window &window, bool force) override { m_delegate_sp->UpdateFieldsVisibility(); window.Erase(); window.DrawTitleBox(m_delegate_sp->GetName().c_str(), - "Press Esc to cancel"); + "Press Esc to Cancel"); + DrawSubmitHint(window, window.IsActive()); Rect content_bounds = window.GetFrame(); content_bounds.Inset(2, 2); - DerivedWindow content_surface = DerivedWindow(window, content_bounds); + Surface content_surface = window.SubSurface(content_bounds); DrawContent(content_surface); return true; @@ -2391,8 +2794,8 @@ public: return eKeyHandled; } - void ExecuteAction(Window &window) { - FormAction &action = m_delegate_sp->GetAction(m_selection_index); + void ExecuteAction(Window &window, int index) { + FormAction &action = m_delegate_sp->GetAction(index); action.Execute(window); if (m_delegate_sp->HasError()) { m_first_visible_line = 0; @@ -2401,20 +2804,27 @@ public: } } + // Always return eKeyHandled to absorb all events since forms are always + // added as pop-ups that should take full control until canceled or submitted. HandleCharResult WindowDelegateHandleChar(Window &window, int key) override { switch (key) { case '\r': case '\n': case KEY_ENTER: if (m_selection_type == SelectionType::Action) { - ExecuteAction(window); + ExecuteAction(window, m_selection_index); return eKeyHandled; } break; + case KEY_ALT_ENTER: + ExecuteAction(window, 0); + return eKeyHandled; case '\t': - return SelectNext(key); + SelectNext(key); + return eKeyHandled; case KEY_SHIFT_TAB: - return SelectPrevious(key); + SelectPrevious(key); + return eKeyHandled; case KEY_ESCAPE: window.GetParent()->RemoveSubWindow(&window); return eKeyHandled; @@ -2426,10 +2836,24 @@ public: // to that field. if (m_selection_type == SelectionType::Field) { FieldDelegate *field = m_delegate_sp->GetField(m_selection_index); - return field->FieldDelegateHandleChar(key); + if (field->FieldDelegateHandleChar(key) == eKeyHandled) + return eKeyHandled; } - return eKeyNotHandled; + // If the key wasn't handled by the possibly selected field, handle some + // extra keys for navigation. + switch (key) { + case KEY_DOWN: + SelectNext(key); + return eKeyHandled; + case KEY_UP: + SelectPrevious(key); + return eKeyHandled; + default: + break; + } + + return eKeyHandled; } protected: @@ -2651,6 +3075,801 @@ protected: ProcessPluginFieldDelegate *m_plugin_field; }; +class TargetCreateFormDelegate : public FormDelegate { +public: + TargetCreateFormDelegate(Debugger &debugger) : m_debugger(debugger) { + m_executable_field = AddFileField("Executable", "", /*need_to_exist=*/true, + /*required=*/true); + m_core_file_field = AddFileField("Core File", "", /*need_to_exist=*/true, + /*required=*/false); + m_symbol_file_field = AddFileField( + "Symbol File", "", /*need_to_exist=*/true, /*required=*/false); + m_show_advanced_field = AddBooleanField("Show advanced settings.", false); + m_remote_file_field = AddFileField( + "Remote File", "", /*need_to_exist=*/false, /*required=*/false); + m_arch_field = AddArchField("Architecture", "", /*required=*/false); + m_platform_field = AddPlatformPluginField(debugger); + m_load_dependent_files_field = + AddChoicesField("Load Dependents", 3, GetLoadDependentFilesChoices()); + + AddAction("Create", [this](Window &window) { CreateTarget(window); }); + } + + std::string GetName() override { return "Create Target"; } + + void UpdateFieldsVisibility() override { + if (m_show_advanced_field->GetBoolean()) { + m_remote_file_field->FieldDelegateShow(); + m_arch_field->FieldDelegateShow(); + m_platform_field->FieldDelegateShow(); + m_load_dependent_files_field->FieldDelegateShow(); + } else { + m_remote_file_field->FieldDelegateHide(); + m_arch_field->FieldDelegateHide(); + m_platform_field->FieldDelegateHide(); + m_load_dependent_files_field->FieldDelegateHide(); + } + } + + static constexpr const char *kLoadDependentFilesNo = "No"; + static constexpr const char *kLoadDependentFilesYes = "Yes"; + static constexpr const char *kLoadDependentFilesExecOnly = "Executable only"; + + std::vector<std::string> GetLoadDependentFilesChoices() { + std::vector<std::string> load_depentents_options; + load_depentents_options.push_back(kLoadDependentFilesExecOnly); + load_depentents_options.push_back(kLoadDependentFilesYes); + load_depentents_options.push_back(kLoadDependentFilesNo); + return load_depentents_options; + } + + LoadDependentFiles GetLoadDependentFiles() { + std::string choice = m_load_dependent_files_field->GetChoiceContent(); + if (choice == kLoadDependentFilesNo) + return eLoadDependentsNo; + if (choice == kLoadDependentFilesYes) + return eLoadDependentsYes; + return eLoadDependentsDefault; + } + + OptionGroupPlatform GetPlatformOptions() { + OptionGroupPlatform platform_options(false); + platform_options.SetPlatformName(m_platform_field->GetPluginName().c_str()); + return platform_options; + } + + TargetSP GetTarget() { + OptionGroupPlatform platform_options = GetPlatformOptions(); + TargetSP target_sp; + Status status = m_debugger.GetTargetList().CreateTarget( + m_debugger, m_executable_field->GetPath(), + m_arch_field->GetArchString(), GetLoadDependentFiles(), + &platform_options, target_sp); + + if (status.Fail()) { + SetError(status.AsCString()); + return nullptr; + } + + m_debugger.GetTargetList().SetSelectedTarget(target_sp); + + return target_sp; + } + + void SetSymbolFile(TargetSP target_sp) { + if (!m_symbol_file_field->IsSpecified()) + return; + + ModuleSP module_sp(target_sp->GetExecutableModule()); + if (!module_sp) + return; + + module_sp->SetSymbolFileFileSpec( + m_symbol_file_field->GetResolvedFileSpec()); + } + + void SetCoreFile(TargetSP target_sp) { + if (!m_core_file_field->IsSpecified()) + return; + + FileSpec core_file_spec = m_core_file_field->GetResolvedFileSpec(); + + FileSpec core_file_directory_spec; + core_file_directory_spec.GetDirectory() = core_file_spec.GetDirectory(); + target_sp->AppendExecutableSearchPaths(core_file_directory_spec); + + ProcessSP process_sp(target_sp->CreateProcess( + m_debugger.GetListener(), llvm::StringRef(), &core_file_spec, false)); + + if (!process_sp) { + SetError("Unable to find process plug-in for core file!"); + return; + } + + Status status = process_sp->LoadCore(); + if (status.Fail()) { + SetError("Can't find plug-in for core file!"); + return; + } + } + + void SetRemoteFile(TargetSP target_sp) { + if (!m_remote_file_field->IsSpecified()) + return; + + ModuleSP module_sp(target_sp->GetExecutableModule()); + if (!module_sp) + return; + + FileSpec remote_file_spec = m_remote_file_field->GetFileSpec(); + module_sp->SetPlatformFileSpec(remote_file_spec); + } + + void RemoveTarget(TargetSP target_sp) { + m_debugger.GetTargetList().DeleteTarget(target_sp); + } + + void CreateTarget(Window &window) { + ClearError(); + + bool all_fields_are_valid = CheckFieldsValidity(); + if (!all_fields_are_valid) + return; + + TargetSP target_sp = GetTarget(); + if (HasError()) + return; + + SetSymbolFile(target_sp); + if (HasError()) { + RemoveTarget(target_sp); + return; + } + + SetCoreFile(target_sp); + if (HasError()) { + RemoveTarget(target_sp); + return; + } + + SetRemoteFile(target_sp); + if (HasError()) { + RemoveTarget(target_sp); + return; + } + + window.GetParent()->RemoveSubWindow(&window); + } + +protected: + Debugger &m_debugger; + + FileFieldDelegate *m_executable_field; + FileFieldDelegate *m_core_file_field; + FileFieldDelegate *m_symbol_file_field; + BooleanFieldDelegate *m_show_advanced_field; + FileFieldDelegate *m_remote_file_field; + ArchFieldDelegate *m_arch_field; + PlatformPluginFieldDelegate *m_platform_field; + ChoicesFieldDelegate *m_load_dependent_files_field; +}; + +class ProcessLaunchFormDelegate : public FormDelegate { +public: + ProcessLaunchFormDelegate(Debugger &debugger, WindowSP main_window_sp) + : m_debugger(debugger), m_main_window_sp(main_window_sp) { + + m_arguments_field = AddArgumentsField(); + SetArgumentsFieldDefaultValue(); + m_target_environment_field = + AddEnvironmentVariableListField("Target Environment Variables"); + SetTargetEnvironmentFieldDefaultValue(); + m_working_directory_field = AddDirectoryField( + "Working Directory", GetDefaultWorkingDirectory().c_str(), true, false); + + m_show_advanced_field = AddBooleanField("Show advanced settings.", false); + + m_stop_at_entry_field = AddBooleanField("Stop at entry point.", false); + m_detach_on_error_field = + AddBooleanField("Detach on error.", GetDefaultDetachOnError()); + m_disable_aslr_field = + AddBooleanField("Disable ASLR", GetDefaultDisableASLR()); + m_plugin_field = AddProcessPluginField(); + m_arch_field = AddArchField("Architecture", "", false); + m_shell_field = AddFileField("Shell", "", true, false); + m_expand_shell_arguments_field = + AddBooleanField("Expand shell arguments.", false); + + m_disable_standard_io_field = + AddBooleanField("Disable Standard IO", GetDefaultDisableStandardIO()); + m_standard_output_field = + AddFileField("Standard Output File", "", /*need_to_exist=*/false, + /*required=*/false); + m_standard_error_field = + AddFileField("Standard Error File", "", /*need_to_exist=*/false, + /*required=*/false); + m_standard_input_field = + AddFileField("Standard Input File", "", /*need_to_exist=*/false, + /*required=*/false); + + m_show_inherited_environment_field = + AddBooleanField("Show inherited environment variables.", false); + m_inherited_environment_field = + AddEnvironmentVariableListField("Inherited Environment Variables"); + SetInheritedEnvironmentFieldDefaultValue(); + + AddAction("Launch", [this](Window &window) { Launch(window); }); + } + + std::string GetName() override { return "Launch Process"; } + + void UpdateFieldsVisibility() override { + if (m_show_advanced_field->GetBoolean()) { + m_stop_at_entry_field->FieldDelegateShow(); + m_detach_on_error_field->FieldDelegateShow(); + m_disable_aslr_field->FieldDelegateShow(); + m_plugin_field->FieldDelegateShow(); + m_arch_field->FieldDelegateShow(); + m_shell_field->FieldDelegateShow(); + m_expand_shell_arguments_field->FieldDelegateShow(); + m_disable_standard_io_field->FieldDelegateShow(); + if (m_disable_standard_io_field->GetBoolean()) { + m_standard_input_field->FieldDelegateHide(); + m_standard_output_field->FieldDelegateHide(); + m_standard_error_field->FieldDelegateHide(); + } else { + m_standard_input_field->FieldDelegateShow(); + m_standard_output_field->FieldDelegateShow(); + m_standard_error_field->FieldDelegateShow(); + } + m_show_inherited_environment_field->FieldDelegateShow(); + if (m_show_inherited_environment_field->GetBoolean()) + m_inherited_environment_field->FieldDelegateShow(); + else + m_inherited_environment_field->FieldDelegateHide(); + } else { + m_stop_at_entry_field->FieldDelegateHide(); + m_detach_on_error_field->FieldDelegateHide(); + m_disable_aslr_field->FieldDelegateHide(); + m_plugin_field->FieldDelegateHide(); + m_arch_field->FieldDelegateHide(); + m_shell_field->FieldDelegateHide(); + m_expand_shell_arguments_field->FieldDelegateHide(); + m_disable_standard_io_field->FieldDelegateHide(); + m_standard_input_field->FieldDelegateHide(); + m_standard_output_field->FieldDelegateHide(); + m_standard_error_field->FieldDelegateHide(); + m_show_inherited_environment_field->FieldDelegateHide(); + m_inherited_environment_field->FieldDelegateHide(); + } + } + + // Methods for setting the default value of the fields. + + void SetArgumentsFieldDefaultValue() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return; + + const Args &target_arguments = + target->GetProcessLaunchInfo().GetArguments(); + m_arguments_field->AddArguments(target_arguments); + } + + void SetTargetEnvironmentFieldDefaultValue() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return; + + const Environment &target_environment = target->GetTargetEnvironment(); + m_target_environment_field->AddEnvironmentVariables(target_environment); + } + + void SetInheritedEnvironmentFieldDefaultValue() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return; + + const Environment &inherited_environment = + target->GetInheritedEnvironment(); + m_inherited_environment_field->AddEnvironmentVariables( + inherited_environment); + } + + std::string GetDefaultWorkingDirectory() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return ""; + + PlatformSP platform = target->GetPlatform(); + return platform->GetWorkingDirectory().GetPath(); + } + + bool GetDefaultDisableASLR() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return false; + + return target->GetDisableASLR(); + } + + bool GetDefaultDisableStandardIO() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return true; + + return target->GetDisableSTDIO(); + } + + bool GetDefaultDetachOnError() { + TargetSP target = m_debugger.GetSelectedTarget(); + if (target == nullptr) + return true; + + return target->GetDetachOnError(); + } + + // Methods for getting the necessary information and setting them to the + // ProcessLaunchInfo. + + void GetExecutableSettings(ProcessLaunchInfo &launch_info) { + TargetSP target = m_debugger.GetSelectedTarget(); + ModuleSP executable_module = target->GetExecutableModule(); + llvm::StringRef target_settings_argv0 = target->GetArg0(); + + if (!target_settings_argv0.empty()) { + launch_info.GetArguments().AppendArgument(target_settings_argv0); + launch_info.SetExecutableFile(executable_module->GetPlatformFileSpec(), + false); + return; + } + + launch_info.SetExecutableFile(executable_module->GetPlatformFileSpec(), + true); + } + + void GetArguments(ProcessLaunchInfo &launch_info) { + TargetSP target = m_debugger.GetSelectedTarget(); + Args arguments = m_arguments_field->GetArguments(); + launch_info.GetArguments().AppendArguments(arguments); + } + + void GetEnvironment(ProcessLaunchInfo &launch_info) { + Environment target_environment = + m_target_environment_field->GetEnvironment(); + Environment inherited_environment = + m_inherited_environment_field->GetEnvironment(); + launch_info.GetEnvironment().insert(target_environment.begin(), + target_environment.end()); + launch_info.GetEnvironment().insert(inherited_environment.begin(), + inherited_environment.end()); + } + + void GetWorkingDirectory(ProcessLaunchInfo &launch_info) { + if (m_working_directory_field->IsSpecified()) + launch_info.SetWorkingDirectory( + m_working_directory_field->GetResolvedFileSpec()); + } + + void GetStopAtEntry(ProcessLaunchInfo &launch_info) { + if (m_stop_at_entry_field->GetBoolean()) + launch_info.GetFlags().Set(eLaunchFlagStopAtEntry); + else + launch_info.GetFlags().Clear(eLaunchFlagStopAtEntry); + } + + void GetDetachOnError(ProcessLaunchInfo &launch_info) { + if (m_detach_on_error_field->GetBoolean()) + launch_info.GetFlags().Set(eLaunchFlagDetachOnError); + else + launch_info.GetFlags().Clear(eLaunchFlagDetachOnError); + } + + void GetDisableASLR(ProcessLaunchInfo &launch_info) { + if (m_disable_aslr_field->GetBoolean()) + launch_info.GetFlags().Set(eLaunchFlagDisableASLR); + else + launch_info.GetFlags().Clear(eLaunchFlagDisableASLR); + } + + void GetPlugin(ProcessLaunchInfo &launch_info) { + launch_info.SetProcessPluginName(m_plugin_field->GetPluginName()); + } + + void GetArch(ProcessLaunchInfo &launch_info) { + if (!m_arch_field->IsSpecified()) + return; + + TargetSP target_sp = m_debugger.GetSelectedTarget(); + PlatformSP platform_sp = + target_sp ? target_sp->GetPlatform() : PlatformSP(); + launch_info.GetArchitecture() = Platform::GetAugmentedArchSpec( + platform_sp.get(), m_arch_field->GetArchString()); + } + + void GetShell(ProcessLaunchInfo &launch_info) { + if (!m_shell_field->IsSpecified()) + return; + + launch_info.SetShell(m_shell_field->GetResolvedFileSpec()); + launch_info.SetShellExpandArguments( + m_expand_shell_arguments_field->GetBoolean()); + } + + void GetStandardIO(ProcessLaunchInfo &launch_info) { + if (m_disable_standard_io_field->GetBoolean()) { + launch_info.GetFlags().Set(eLaunchFlagDisableSTDIO); + return; + } + + FileAction action; + if (m_standard_input_field->IsSpecified()) { + action.Open(STDIN_FILENO, m_standard_input_field->GetFileSpec(), true, + false); + launch_info.AppendFileAction(action); + } + if (m_standard_output_field->IsSpecified()) { + action.Open(STDOUT_FILENO, m_standard_output_field->GetFileSpec(), false, + true); + launch_info.AppendFileAction(action); + } + if (m_standard_error_field->IsSpecified()) { + action.Open(STDERR_FILENO, m_standard_error_field->GetFileSpec(), false, + true); + launch_info.AppendFileAction(action); + } + } + + void GetInheritTCC(ProcessLaunchInfo &launch_info) { + if (m_debugger.GetSelectedTarget()->GetInheritTCC()) + launch_info.GetFlags().Set(eLaunchFlagInheritTCCFromParent); + } + + ProcessLaunchInfo GetLaunchInfo() { + ProcessLaunchInfo launch_info; + + GetExecutableSettings(launch_info); + GetArguments(launch_info); + GetEnvironment(launch_info); + GetWorkingDirectory(launch_info); + GetStopAtEntry(launch_info); + GetDetachOnError(launch_info); + GetDisableASLR(launch_info); + GetPlugin(launch_info); + GetArch(launch_info); + GetShell(launch_info); + GetStandardIO(launch_info); + GetInheritTCC(launch_info); + + return launch_info; + } + + bool StopRunningProcess() { + ExecutionContext exe_ctx = + m_debugger.GetCommandInterpreter().GetExecutionContext(); + + if (!exe_ctx.HasProcessScope()) + return false; + + Process *process = exe_ctx.GetProcessPtr(); + if (!(process && process->IsAlive())) + return false; + + FormDelegateSP form_delegate_sp = + FormDelegateSP(new DetachOrKillProcessFormDelegate(process)); + Rect bounds = m_main_window_sp->GetCenteredRect(85, 8); + WindowSP form_window_sp = m_main_window_sp->CreateSubWindow( + form_delegate_sp->GetName().c_str(), bounds, true); + WindowDelegateSP window_delegate_sp = + WindowDelegateSP(new FormWindowDelegate(form_delegate_sp)); + form_window_sp->SetDelegate(window_delegate_sp); + + return true; + } + + Target *GetTarget() { + Target *target = m_debugger.GetSelectedTarget().get(); + + if (target == nullptr) { + SetError("No target exists!"); + return nullptr; + } + + ModuleSP exe_module_sp = target->GetExecutableModule(); + + if (exe_module_sp == nullptr) { + SetError("No executable in target!"); + return nullptr; + } + + return target; + } + + void Launch(Window &window) { + ClearError(); + + bool all_fields_are_valid = CheckFieldsValidity(); + if (!all_fields_are_valid) + return; + + bool process_is_running = StopRunningProcess(); + if (process_is_running) + return; + + Target *target = GetTarget(); + if (HasError()) + return; + + StreamString stream; + ProcessLaunchInfo launch_info = GetLaunchInfo(); + Status status = target->Launch(launch_info, &stream); + + if (status.Fail()) { + SetError(status.AsCString()); + return; + } + + ProcessSP process_sp(target->GetProcessSP()); + if (!process_sp) { + SetError("Launched successfully but target has no process!"); + return; + } + + window.GetParent()->RemoveSubWindow(&window); + } + +protected: + Debugger &m_debugger; + WindowSP m_main_window_sp; + + ArgumentsFieldDelegate *m_arguments_field; + EnvironmentVariableListFieldDelegate *m_target_environment_field; + DirectoryFieldDelegate *m_working_directory_field; + + BooleanFieldDelegate *m_show_advanced_field; + + BooleanFieldDelegate *m_stop_at_entry_field; + BooleanFieldDelegate *m_detach_on_error_field; + BooleanFieldDelegate *m_disable_aslr_field; + ProcessPluginFieldDelegate *m_plugin_field; + ArchFieldDelegate *m_arch_field; + FileFieldDelegate *m_shell_field; + BooleanFieldDelegate *m_expand_shell_arguments_field; + BooleanFieldDelegate *m_disable_standard_io_field; + FileFieldDelegate *m_standard_input_field; + FileFieldDelegate *m_standard_output_field; + FileFieldDelegate *m_standard_error_field; + + BooleanFieldDelegate *m_show_inherited_environment_field; + EnvironmentVariableListFieldDelegate *m_inherited_environment_field; +}; + +//////////// +// Searchers +//////////// + +class SearcherDelegate { +public: + SearcherDelegate() {} + + virtual ~SearcherDelegate() = default; + + virtual int GetNumberOfMatches() = 0; + + // Get the string that will be displayed for the match at the input index. + virtual const std::string &GetMatchTextAtIndex(int index) = 0; + + // Update the matches of the search. This is executed every time the text + // field handles an event. + virtual void UpdateMatches(const std::string &text) = 0; + + // Execute the user callback given the index of some match. This is executed + // once the user selects a match. + virtual void ExecuteCallback(int match_index) = 0; +}; + +typedef std::shared_ptr<SearcherDelegate> SearcherDelegateSP; + +class SearcherWindowDelegate : public WindowDelegate { +public: + SearcherWindowDelegate(SearcherDelegateSP &delegate_sp) + : m_delegate_sp(delegate_sp), m_text_field("Search", "", false), + m_selected_match(0), m_first_visible_match(0) { + ; + } + + // A completion window is padded by one character from all sides. A text field + // is first drawn for inputting the searcher request, then a list of matches + // are displayed in a scrollable list. + // + // ___<Searcher Window Name>____________________________ + // | | + // | __[Search]_______________________________________ | + // | | | | + // | |_______________________________________________| | + // | - Match 1. | + // | - Match 2. | + // | - ... | + // | | + // |____________________________[Press Esc to Cancel]__| + // + + // Get the index of the last visible match. Assuming at least one match + // exists. + int GetLastVisibleMatch(int height) { + int index = m_first_visible_match + height; + return std::min(index, m_delegate_sp->GetNumberOfMatches()) - 1; + } + + int GetNumberOfVisibleMatches(int height) { + return GetLastVisibleMatch(height) - m_first_visible_match + 1; + } + + void UpdateScrolling(Surface &surface) { + if (m_selected_match < m_first_visible_match) { + m_first_visible_match = m_selected_match; + return; + } + + int height = surface.GetHeight(); + int last_visible_match = GetLastVisibleMatch(height); + if (m_selected_match > last_visible_match) { + m_first_visible_match = m_selected_match - height + 1; + } + } + + void DrawMatches(Surface &surface) { + if (m_delegate_sp->GetNumberOfMatches() == 0) + return; + + UpdateScrolling(surface); + + int count = GetNumberOfVisibleMatches(surface.GetHeight()); + for (int i = 0; i < count; i++) { + surface.MoveCursor(1, i); + int current_match = m_first_visible_match + i; + if (current_match == m_selected_match) + surface.AttributeOn(A_REVERSE); + surface.PutCString( + m_delegate_sp->GetMatchTextAtIndex(current_match).c_str()); + if (current_match == m_selected_match) + surface.AttributeOff(A_REVERSE); + } + } + + void DrawContent(Surface &surface) { + Rect content_bounds = surface.GetFrame(); + Rect text_field_bounds, matchs_bounds; + content_bounds.HorizontalSplit(m_text_field.FieldDelegateGetHeight(), + text_field_bounds, matchs_bounds); + Surface text_field_surface = surface.SubSurface(text_field_bounds); + Surface matches_surface = surface.SubSurface(matchs_bounds); + + m_text_field.FieldDelegateDraw(text_field_surface, true); + DrawMatches(matches_surface); + } + + bool WindowDelegateDraw(Window &window, bool force) override { + window.Erase(); + + window.DrawTitleBox(window.GetName(), "Press Esc to Cancel"); + + Rect content_bounds = window.GetFrame(); + content_bounds.Inset(2, 2); + Surface content_surface = window.SubSurface(content_bounds); + + DrawContent(content_surface); + return true; + } + + void SelectNext() { + if (m_selected_match != m_delegate_sp->GetNumberOfMatches() - 1) + m_selected_match++; + return; + } + + void SelectPrevious() { + if (m_selected_match != 0) + m_selected_match--; + return; + } + + void ExecuteCallback(Window &window) { + m_delegate_sp->ExecuteCallback(m_selected_match); + window.GetParent()->RemoveSubWindow(&window); + } + + void UpdateMatches() { + m_delegate_sp->UpdateMatches(m_text_field.GetText()); + m_selected_match = 0; + } + + HandleCharResult WindowDelegateHandleChar(Window &window, int key) override { + switch (key) { + case '\r': + case '\n': + case KEY_ENTER: + ExecuteCallback(window); + return eKeyHandled; + case '\t': + case KEY_DOWN: + SelectNext(); + return eKeyHandled; + case KEY_SHIFT_TAB: + case KEY_UP: + SelectPrevious(); + return eKeyHandled; + case KEY_ESCAPE: + window.GetParent()->RemoveSubWindow(&window); + return eKeyHandled; + default: + break; + } + + if (m_text_field.FieldDelegateHandleChar(key) == eKeyHandled) + UpdateMatches(); + + return eKeyHandled; + } + +protected: + SearcherDelegateSP m_delegate_sp; + TextFieldDelegate m_text_field; + // The index of the currently selected match. + int m_selected_match; + // The index of the first visible match. + int m_first_visible_match; +}; + +////////////////////////////// +// Searcher Delegate Instances +////////////////////////////// + +// This is a searcher delegate wrapper around CommandCompletions common +// callbacks. The callbacks are only given the match string. The completion_mask +// can be a combination of CommonCompletionTypes. +class CommonCompletionSearcherDelegate : public SearcherDelegate { +public: + typedef std::function<void(const std::string &)> CallbackType; + + CommonCompletionSearcherDelegate(Debugger &debugger, uint32_t completion_mask, + CallbackType callback) + : m_debugger(debugger), m_completion_mask(completion_mask), + m_callback(callback) {} + + int GetNumberOfMatches() override { return m_matches.GetSize(); } + + const std::string &GetMatchTextAtIndex(int index) override { + return m_matches[index]; + } + + void UpdateMatches(const std::string &text) override { + CompletionResult result; + CompletionRequest request(text.c_str(), text.size(), result); + CommandCompletions::InvokeCommonCompletionCallbacks( + m_debugger.GetCommandInterpreter(), m_completion_mask, request, + nullptr); + result.GetMatches(m_matches); + } + + void ExecuteCallback(int match_index) override { + m_callback(m_matches[match_index]); + } + +protected: + Debugger &m_debugger; + // A compound mask from CommonCompletionTypes. + uint32_t m_completion_mask; + // A callback to execute once the user selects a match. The match is passed to + // the callback as a string. + CallbackType m_callback; + StringList m_matches; +}; + +//////// +// Menus +//////// + class MenuDelegate { public: virtual ~MenuDelegate() = default; @@ -3078,15 +4297,15 @@ public: bool done = false; int delay_in_tenths_of_a_second = 1; - // Alas the threading model in curses is a bit lame so we need to resort to - // polling every 0.5 seconds. We could poll for stdin ourselves and then - // pass the keys down but then we need to translate all of the escape + // Alas the threading model in curses is a bit lame so we need to resort + // to polling every 0.5 seconds. We could poll for stdin ourselves and + // then pass the keys down but then we need to translate all of the escape // sequences ourselves. So we resort to polling for input because we need // to receive async process events while in this loop. - halfdelay(delay_in_tenths_of_a_second); // Poll using some number of tenths - // of seconds seconds when calling - // Window::GetChar() + halfdelay(delay_in_tenths_of_a_second); // Poll using some number of + // tenths of seconds seconds when + // calling Window::GetChar() ListenerSP listener_sp( Listener::MakeListener("lldb.IOHandler.curses.Application")); @@ -3392,9 +4611,14 @@ public: TreeItem *&selected_item) { return; } - virtual bool TreeDelegateItemSelected( - TreeItem &item) = 0; // Return true if we need to update views + // This is invoked when a tree item is selected. If true is returned, the + // views are updated. + virtual bool TreeDelegateItemSelected(TreeItem &item) = 0; virtual bool TreeDelegateExpandRootByDefault() { return false; } + // This is mostly useful for root tree delegates. If false is returned, + // drawing will be skipped completely. This is needed, for instance, in + // skipping drawing of the threads tree if there is no running process. + virtual bool TreeDelegateShouldDraw() { return true; } }; typedef std::shared_ptr<TreeDelegate> TreeDelegateSP; @@ -3584,6 +4808,16 @@ public: void SetIdentifier(uint64_t identifier) { m_identifier = identifier; } + const std::string &GetText() const { return m_text; } + + void SetText(const char *text) { + if (text == nullptr) { + m_text.clear(); + return; + } + m_text = text; + } + void SetMightHaveChildren(bool b) { m_might_have_children = b; } protected: @@ -3591,6 +4825,7 @@ protected: TreeDelegate &m_delegate; void *m_user_data; uint64_t m_identifier; + std::string m_text; int m_row_idx; // Zero based visible row index, -1 if not visible or for the // root item std::vector<TreeItem> m_children; @@ -3609,21 +4844,6 @@ public: int NumVisibleRows() const { return m_max_y - m_min_y; } bool WindowDelegateDraw(Window &window, bool force) override { - ExecutionContext exe_ctx( - m_debugger.GetCommandInterpreter().GetExecutionContext()); - Process *process = exe_ctx.GetProcessPtr(); - - bool display_content = false; - if (process) { - StateType state = process->GetState(); - if (StateIsStoppedState(state, true)) { - // We are stopped, so it is ok to - display_content = true; - } else if (StateIsRunningState(state)) { - return true; // Don't do any updating when we are running - } - } - m_min_x = 2; m_min_y = 1; m_max_x = window.GetWidth() - 1; @@ -3632,35 +4852,36 @@ public: window.Erase(); window.DrawTitleBox(window.GetName()); - if (display_content) { - const int num_visible_rows = NumVisibleRows(); - m_num_rows = 0; - m_root.CalculateRowIndexes(m_num_rows); - m_delegate_sp->TreeDelegateUpdateSelection(m_root, m_selected_row_idx, - m_selected_item); - - // If we unexpanded while having something selected our total number of - // rows is less than the num visible rows, then make sure we show all the - // rows by setting the first visible row accordingly. - if (m_first_visible_row > 0 && m_num_rows < num_visible_rows) - m_first_visible_row = 0; - - // Make sure the selected row is always visible - if (m_selected_row_idx < m_first_visible_row) - m_first_visible_row = m_selected_row_idx; - else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx) - m_first_visible_row = m_selected_row_idx - num_visible_rows + 1; - - int row_idx = 0; - int num_rows_left = num_visible_rows; - m_root.Draw(window, m_first_visible_row, m_selected_row_idx, row_idx, - num_rows_left); - // Get the selected row - m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx); - } else { + if (!m_delegate_sp->TreeDelegateShouldDraw()) { m_selected_item = nullptr; + return true; } + const int num_visible_rows = NumVisibleRows(); + m_num_rows = 0; + m_root.CalculateRowIndexes(m_num_rows); + m_delegate_sp->TreeDelegateUpdateSelection(m_root, m_selected_row_idx, + m_selected_item); + + // If we unexpanded while having something selected our total number of + // rows is less than the num visible rows, then make sure we show all the + // rows by setting the first visible row accordingly. + if (m_first_visible_row > 0 && m_num_rows < num_visible_rows) + m_first_visible_row = 0; + + // Make sure the selected row is always visible + if (m_selected_row_idx < m_first_visible_row) + m_first_visible_row = m_selected_row_idx; + else if (m_first_visible_row + num_visible_rows <= m_selected_row_idx) + m_first_visible_row = m_selected_row_idx - num_visible_rows + 1; + + int row_idx = 0; + int num_rows_left = num_visible_rows; + m_root.Draw(window, m_first_visible_row, m_selected_row_idx, row_idx, + num_rows_left); + // Get the selected row + m_selected_item = m_root.GetItemForRowIndex(m_selected_row_idx); + return true; // Drawing handled } @@ -3788,6 +5009,23 @@ protected: int m_max_y; }; +// A tree delegate that just draws the text member of the tree item, it doesn't +// have any children or actions. +class TextTreeDelegate : public TreeDelegate { +public: + TextTreeDelegate() : TreeDelegate() {} + + ~TextTreeDelegate() override = default; + + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { + window.PutCStringTruncated(1, item.GetText().c_str()); + } + + void TreeDelegateGenerateChildren(TreeItem &item) override {} + + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } +}; + class FrameTreeDelegate : public TreeDelegate { public: FrameTreeDelegate() : TreeDelegate() { @@ -3952,6 +5190,17 @@ public: .GetProcessSP(); } + bool TreeDelegateShouldDraw() override { + ProcessSP process = GetProcess(); + if (!process) + return false; + + if (StateIsRunningState(process->GetState())) + return false; + + return true; + } + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { ProcessSP process_sp = GetProcess(); if (process_sp && process_sp->IsAlive()) { @@ -4043,6 +5292,240 @@ protected: FormatEntity::Entry m_format; }; +class BreakpointLocationTreeDelegate : public TreeDelegate { +public: + BreakpointLocationTreeDelegate(Debugger &debugger) + : TreeDelegate(), m_debugger(debugger) {} + + ~BreakpointLocationTreeDelegate() override = default; + + Process *GetProcess() { + ExecutionContext exe_ctx( + m_debugger.GetCommandInterpreter().GetExecutionContext()); + return exe_ctx.GetProcessPtr(); + } + + BreakpointLocationSP GetBreakpointLocation(const TreeItem &item) { + Breakpoint *breakpoint = (Breakpoint *)item.GetUserData(); + return breakpoint->GetLocationAtIndex(item.GetIdentifier()); + } + + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { + BreakpointLocationSP breakpoint_location = GetBreakpointLocation(item); + Process *process = GetProcess(); + StreamString stream; + stream.Printf("%i.%i: ", breakpoint_location->GetBreakpoint().GetID(), + breakpoint_location->GetID()); + Address address = breakpoint_location->GetAddress(); + address.Dump(&stream, process, Address::DumpStyleResolvedDescription, + Address::DumpStyleInvalid); + window.PutCStringTruncated(1, stream.GetString().str().c_str()); + } + + StringList ComputeDetailsList(BreakpointLocationSP breakpoint_location) { + StringList details; + + Address address = breakpoint_location->GetAddress(); + SymbolContext symbol_context; + address.CalculateSymbolContext(&symbol_context); + + if (symbol_context.module_sp) { + StreamString module_stream; + module_stream.PutCString("module = "); + symbol_context.module_sp->GetFileSpec().Dump( + module_stream.AsRawOstream()); + details.AppendString(module_stream.GetString()); + } + + if (symbol_context.comp_unit != nullptr) { + StreamString compile_unit_stream; + compile_unit_stream.PutCString("compile unit = "); + symbol_context.comp_unit->GetPrimaryFile().GetFilename().Dump( + &compile_unit_stream); + details.AppendString(compile_unit_stream.GetString()); + + if (symbol_context.function != nullptr) { + StreamString function_stream; + function_stream.PutCString("function = "); + function_stream.PutCString( + symbol_context.function->GetName().AsCString("<unknown>")); + details.AppendString(function_stream.GetString()); + } + + if (symbol_context.line_entry.line > 0) { + StreamString location_stream; + location_stream.PutCString("location = "); + symbol_context.line_entry.DumpStopContext(&location_stream, true); + details.AppendString(location_stream.GetString()); + } + + } else { + if (symbol_context.symbol) { + StreamString symbol_stream; + if (breakpoint_location->IsReExported()) + symbol_stream.PutCString("re-exported target = "); + else + symbol_stream.PutCString("symbol = "); + symbol_stream.PutCString( + symbol_context.symbol->GetName().AsCString("<unknown>")); + details.AppendString(symbol_stream.GetString()); + } + } + + Process *process = GetProcess(); + + StreamString address_stream; + address.Dump(&address_stream, process, Address::DumpStyleLoadAddress, + Address::DumpStyleModuleWithFileAddress); + details.AppendString(address_stream.GetString()); + + BreakpointSiteSP breakpoint_site = breakpoint_location->GetBreakpointSite(); + if (breakpoint_location->IsIndirect() && breakpoint_site) { + Address resolved_address; + resolved_address.SetLoadAddress(breakpoint_site->GetLoadAddress(), + &breakpoint_location->GetTarget()); + Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol(); + if (resolved_symbol) { + StreamString indirect_target_stream; + indirect_target_stream.PutCString("indirect target = "); + indirect_target_stream.PutCString( + resolved_symbol->GetName().GetCString()); + details.AppendString(indirect_target_stream.GetString()); + } + } + + bool is_resolved = breakpoint_location->IsResolved(); + StreamString resolved_stream; + resolved_stream.Printf("resolved = %s", is_resolved ? "true" : "false"); + details.AppendString(resolved_stream.GetString()); + + bool is_hardware = is_resolved && breakpoint_site->IsHardware(); + StreamString hardware_stream; + hardware_stream.Printf("hardware = %s", is_hardware ? "true" : "false"); + details.AppendString(hardware_stream.GetString()); + + StreamString hit_count_stream; + hit_count_stream.Printf("hit count = %-4u", + breakpoint_location->GetHitCount()); + details.AppendString(hit_count_stream.GetString()); + + return details; + } + + void TreeDelegateGenerateChildren(TreeItem &item) override { + BreakpointLocationSP breakpoint_location = GetBreakpointLocation(item); + StringList details = ComputeDetailsList(breakpoint_location); + + if (!m_string_delegate_sp) + m_string_delegate_sp = std::make_shared<TextTreeDelegate>(); + TreeItem details_tree_item(&item, *m_string_delegate_sp, false); + + item.Resize(details.GetSize(), details_tree_item); + for (size_t i = 0; i < details.GetSize(); i++) { + item[i].SetText(details.GetStringAtIndex(i)); + } + } + + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } + +protected: + Debugger &m_debugger; + std::shared_ptr<TextTreeDelegate> m_string_delegate_sp; +}; + +class BreakpointTreeDelegate : public TreeDelegate { +public: + BreakpointTreeDelegate(Debugger &debugger) + : TreeDelegate(), m_debugger(debugger), + m_breakpoint_location_delegate_sp() {} + + ~BreakpointTreeDelegate() override = default; + + BreakpointSP GetBreakpoint(const TreeItem &item) { + TargetSP target = m_debugger.GetSelectedTarget(); + BreakpointList &breakpoints = target->GetBreakpointList(false); + return breakpoints.GetBreakpointAtIndex(item.GetIdentifier()); + } + + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { + BreakpointSP breakpoint = GetBreakpoint(item); + StreamString stream; + stream.Format("{0}: ", breakpoint->GetID()); + breakpoint->GetResolverDescription(&stream); + breakpoint->GetFilterDescription(&stream); + window.PutCStringTruncated(1, stream.GetString().str().c_str()); + } + + void TreeDelegateGenerateChildren(TreeItem &item) override { + BreakpointSP breakpoint = GetBreakpoint(item); + + if (!m_breakpoint_location_delegate_sp) + m_breakpoint_location_delegate_sp = + std::make_shared<BreakpointLocationTreeDelegate>(m_debugger); + TreeItem breakpoint_location_tree_item( + &item, *m_breakpoint_location_delegate_sp, true); + + item.Resize(breakpoint->GetNumLocations(), breakpoint_location_tree_item); + for (size_t i = 0; i < breakpoint->GetNumLocations(); i++) { + item[i].SetIdentifier(i); + item[i].SetUserData(breakpoint.get()); + } + } + + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } + +protected: + Debugger &m_debugger; + std::shared_ptr<BreakpointLocationTreeDelegate> + m_breakpoint_location_delegate_sp; +}; + +class BreakpointsTreeDelegate : public TreeDelegate { +public: + BreakpointsTreeDelegate(Debugger &debugger) + : TreeDelegate(), m_debugger(debugger), m_breakpoint_delegate_sp() {} + + ~BreakpointsTreeDelegate() override = default; + + bool TreeDelegateShouldDraw() override { + TargetSP target = m_debugger.GetSelectedTarget(); + if (!target) + return false; + + return true; + } + + void TreeDelegateDrawTreeItem(TreeItem &item, Window &window) override { + window.PutCString("Breakpoints"); + } + + void TreeDelegateGenerateChildren(TreeItem &item) override { + TargetSP target = m_debugger.GetSelectedTarget(); + + BreakpointList &breakpoints = target->GetBreakpointList(false); + std::unique_lock<std::recursive_mutex> lock; + breakpoints.GetListMutex(lock); + + if (!m_breakpoint_delegate_sp) + m_breakpoint_delegate_sp = + std::make_shared<BreakpointTreeDelegate>(m_debugger); + TreeItem breakpoint_tree_item(&item, *m_breakpoint_delegate_sp, true); + + item.Resize(breakpoints.GetSize(), breakpoint_tree_item); + for (size_t i = 0; i < breakpoints.GetSize(); i++) { + item[i].SetIdentifier(i); + } + } + + bool TreeDelegateItemSelected(TreeItem &item) override { return false; } + + bool TreeDelegateExpandRootByDefault() override { return true; } + +protected: + Debugger &m_debugger; + std::shared_ptr<BreakpointTreeDelegate> m_breakpoint_delegate_sp; +}; + class ValueObjectListDelegate : public WindowDelegate { public: ValueObjectListDelegate() : m_rows() {} @@ -4844,6 +6327,7 @@ public: eMenuID_ViewRegisters, eMenuID_ViewSource, eMenuID_ViewVariables, + eMenuID_ViewBreakpoints, eMenuID_Help, eMenuID_HelpGUIHelp @@ -4908,6 +6392,18 @@ public: MenuActionResult MenuDelegateAction(Menu &menu) override { switch (menu.GetIdentifier()) { + case eMenuID_TargetCreate: { + WindowSP main_window_sp = m_app.GetMainWindow(); + FormDelegateSP form_delegate_sp = + FormDelegateSP(new TargetCreateFormDelegate(m_debugger)); + Rect bounds = main_window_sp->GetCenteredRect(80, 19); + WindowSP form_window_sp = main_window_sp->CreateSubWindow( + form_delegate_sp->GetName().c_str(), bounds, true); + WindowDelegateSP window_delegate_sp = + WindowDelegateSP(new FormWindowDelegate(form_delegate_sp)); + form_window_sp->SetDelegate(window_delegate_sp); + return MenuActionResult::Handled; + } case eMenuID_ThreadStepIn: { ExecutionContext exe_ctx = m_debugger.GetCommandInterpreter().GetExecutionContext(); @@ -4956,6 +6452,18 @@ public: form_window_sp->SetDelegate(window_delegate_sp); return MenuActionResult::Handled; } + case eMenuID_ProcessLaunch: { + WindowSP main_window_sp = m_app.GetMainWindow(); + FormDelegateSP form_delegate_sp = FormDelegateSP( + new ProcessLaunchFormDelegate(m_debugger, main_window_sp)); + Rect bounds = main_window_sp->GetCenteredRect(80, 22); + WindowSP form_window_sp = main_window_sp->CreateSubWindow( + form_delegate_sp->GetName().c_str(), bounds, true); + WindowDelegateSP window_delegate_sp = + WindowDelegateSP(new FormWindowDelegate(form_delegate_sp)); + form_window_sp->SetDelegate(window_delegate_sp); + return MenuActionResult::Handled; + } case eMenuID_ProcessContinue: { ExecutionContext exe_ctx = @@ -5046,8 +6554,8 @@ public: // previously added submenus.erase(submenus.begin() + 7, submenus.end()); } - // Since we are adding and removing items we need to recalculate the name - // lengths + // Since we are adding and removing items we need to recalculate the + // name lengths menu.RecalculateNameLengths(); } return MenuActionResult::Handled; @@ -5155,6 +6663,39 @@ public: } return MenuActionResult::Handled; + case eMenuID_ViewBreakpoints: { + WindowSP main_window_sp = m_app.GetMainWindow(); + WindowSP threads_window_sp = main_window_sp->FindSubWindow("Threads"); + WindowSP breakpoints_window_sp = + main_window_sp->FindSubWindow("Breakpoints"); + const Rect threads_bounds = threads_window_sp->GetBounds(); + + // If a breakpoints window already exists, remove it and give the area + // it used to occupy to the threads window. If it doesn't exist, split + // the threads window horizontally into two windows where the top window + // is the threads window and the bottom window is a newly added + // breakpoints window. + if (breakpoints_window_sp) { + threads_window_sp->Resize(threads_bounds.size.width, + threads_bounds.size.height + + breakpoints_window_sp->GetHeight()); + main_window_sp->RemoveSubWindow(breakpoints_window_sp.get()); + } else { + Rect new_threads_bounds, breakpoints_bounds; + threads_bounds.HorizontalSplitPercentage(0.70, new_threads_bounds, + breakpoints_bounds); + threads_window_sp->SetBounds(new_threads_bounds); + breakpoints_window_sp = main_window_sp->CreateSubWindow( + "Breakpoints", breakpoints_bounds, false); + TreeDelegateSP breakpoints_delegate_sp( + new BreakpointsTreeDelegate(m_debugger)); + breakpoints_window_sp->SetDelegate(WindowDelegateSP( + new TreeWindowDelegate(m_debugger, breakpoints_delegate_sp))); + } + touchwin(stdscr); + return MenuActionResult::Handled; + } + case eMenuID_HelpGUIHelp: m_app.GetMainWindow()->CreateHelpSubwindow(); return MenuActionResult::Handled; @@ -5347,8 +6888,8 @@ public: m_selected_line = m_pc_line; if (m_file_sp && m_file_sp->GetFileSpec() == m_sc.line_entry.file) { - // Same file, nothing to do, we should either have the lines or not - // (source file missing) + // Same file, nothing to do, we should either have the lines or + // not (source file missing) if (m_selected_line >= static_cast<size_t>(m_first_visible_line)) { if (m_selected_line >= m_first_visible_line + num_visible_lines) m_first_visible_line = m_selected_line - 10; @@ -5470,8 +7011,8 @@ public: window.MoveCursor(1, line_y); const bool is_pc_line = curr_line == m_pc_line; const bool line_is_selected = m_selected_line == curr_line; - // Highlight the line as the PC line first, then if the selected line - // isn't the same as the PC line, highlight it differently + // Highlight the line as the PC line first, then if the selected + // line isn't the same as the PC line, highlight it differently attr_t highlight_attr = 0; attr_t bp_attr = 0; if (is_pc_line) @@ -5610,8 +7151,8 @@ public: window.MoveCursor(1, line_y); const bool is_pc_line = frame_sp && inst_idx == pc_idx; const bool line_is_selected = m_selected_line == inst_idx; - // Highlight the line as the PC line first, then if the selected line - // isn't the same as the PC line, highlight it differently + // Highlight the line as the PC line first, then if the selected + // line isn't the same as the PC line, highlight it differently attr_t highlight_attr = 0; attr_t bp_attr = 0; if (is_pc_line) @@ -6075,7 +7616,7 @@ void IOHandlerCursesGUI::Activate() { MenuSP view_menu_sp( new Menu("View", "F5", KEY_F(5), ApplicationDelegate::eMenuID_View)); view_menu_sp->AddSubmenu( - MenuSP(new Menu("Backtrace", nullptr, 'b', + MenuSP(new Menu("Backtrace", nullptr, 't', ApplicationDelegate::eMenuID_ViewBacktrace))); view_menu_sp->AddSubmenu( MenuSP(new Menu("Registers", nullptr, 'r', @@ -6085,6 +7626,9 @@ void IOHandlerCursesGUI::Activate() { view_menu_sp->AddSubmenu( MenuSP(new Menu("Variables", nullptr, 'v', ApplicationDelegate::eMenuID_ViewVariables))); + view_menu_sp->AddSubmenu( + MenuSP(new Menu("Breakpoints", nullptr, 'b', + ApplicationDelegate::eMenuID_ViewBreakpoints))); MenuSP help_menu_sp( new Menu("Help", "F6", KEY_F(6), ApplicationDelegate::eMenuID_Help)); @@ -6145,7 +7689,8 @@ void IOHandlerCursesGUI::Activate() { status_window_sp->SetDelegate( WindowDelegateSP(new StatusBarWindowDelegate(m_debugger))); - // Show the main help window once the first time the curses GUI is launched + // Show the main help window once the first time the curses GUI is + // launched static bool g_showed_help = false; if (!g_showed_help) { g_showed_help = true; @@ -6176,6 +7721,7 @@ void IOHandlerCursesGUI::Activate() { static_assert(LastColorPairIndex == 18, "Color indexes do not match."); define_key("\033[Z", KEY_SHIFT_TAB); + define_key("\033\015", KEY_ALT_ENTER); } } diff --git a/contrib/llvm-project/lldb/source/Core/Mangled.cpp b/contrib/llvm-project/lldb/source/Core/Mangled.cpp index fbaf9ff7151a..20f4dbdb419f 100644 --- a/contrib/llvm-project/lldb/source/Core/Mangled.cpp +++ b/contrib/llvm-project/lldb/source/Core/Mangled.cpp @@ -9,6 +9,7 @@ #include "lldb/Core/Mangled.h" #include "lldb/Core/RichManglingContext.h" +#include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" @@ -16,8 +17,6 @@ #include "lldb/Utility/Stream.h" #include "lldb/lldb-enumerations.h" -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" - #include "llvm/ADT/StringRef.h" #include "llvm/Demangle/Demangle.h" #include "llvm/Support/Compiler.h" @@ -34,35 +33,6 @@ static inline bool cstring_is_mangled(llvm::StringRef s) { return Mangled::GetManglingScheme(s) != Mangled::eManglingSchemeNone; } -static ConstString GetDemangledNameWithoutArguments(ConstString mangled, - ConstString demangled) { - const char *mangled_name_cstr = mangled.GetCString(); - - if (demangled && mangled_name_cstr && mangled_name_cstr[0]) { - if (mangled_name_cstr[0] == '_' && mangled_name_cstr[1] == 'Z' && - (mangled_name_cstr[2] != 'T' && // avoid virtual table, VTT structure, - // typeinfo structure, and typeinfo - // mangled_name - mangled_name_cstr[2] != 'G' && // avoid guard variables - mangled_name_cstr[2] != 'Z')) // named local entities (if we eventually - // handle eSymbolTypeData, we will want - // this back) - { - CPlusPlusLanguage::MethodName cxx_method(demangled); - if (!cxx_method.GetBasename().empty()) { - std::string shortname; - if (!cxx_method.GetContext().empty()) - shortname = cxx_method.GetContext().str() + "::"; - shortname += cxx_method.GetBasename().str(); - return ConstString(shortname); - } - } - } - if (demangled) - return demangled; - return mangled; -} - #pragma mark Mangled Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) { @@ -75,6 +45,9 @@ Mangled::ManglingScheme Mangled::GetManglingScheme(llvm::StringRef const name) { if (name.startswith("_R")) return Mangled::eManglingSchemeRustV0; + if (name.startswith("_D")) + return Mangled::eManglingSchemeD; + if (name.startswith("_Z")) return Mangled::eManglingSchemeItanium; @@ -161,9 +134,9 @@ void Mangled::SetValue(ConstString name) { static char *GetMSVCDemangledStr(const char *M) { char *demangled_cstr = llvm::microsoftDemangle( M, nullptr, nullptr, nullptr, nullptr, - llvm::MSDemangleFlags(llvm::MSDF_NoAccessSpecifier | - llvm::MSDF_NoCallingConvention | - llvm::MSDF_NoMemberType)); + llvm::MSDemangleFlags( + llvm::MSDF_NoAccessSpecifier | llvm::MSDF_NoCallingConvention | + llvm::MSDF_NoMemberType | llvm::MSDF_NoVariableType)); if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { if (demangled_cstr && demangled_cstr[0]) @@ -215,6 +188,19 @@ static char *GetRustV0DemangledStr(const char *M) { return demangled_cstr; } +static char *GetDLangDemangledStr(const char *M) { + char *demangled_cstr = llvm::dlangDemangle(M); + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (demangled_cstr && demangled_cstr[0]) + LLDB_LOG(log, "demangled dlang: {0} -> \"{1}\"", M, demangled_cstr); + else + LLDB_LOG(log, "demangled dlang: {0} -> error: failed to demangle", M); + } + + return demangled_cstr; +} + // Explicit demangling for scheduled requests during batch processing. This // makes use of ItaniumPartialDemangler's rich demangle info bool Mangled::DemangleWithRichManglingInfo( @@ -274,7 +260,8 @@ bool Mangled::DemangleWithRichManglingInfo( } case eManglingSchemeRustV0: - // Rich demangling scheme is not supported for Rust + case eManglingSchemeD: + // Rich demangling scheme is not supported return false; } llvm_unreachable("Fully covered switch above!"); @@ -290,7 +277,8 @@ ConstString Mangled::GetDemangledName() const { if (m_mangled && m_demangled.IsNull()) { // Don't bother running anything that isn't mangled const char *mangled_name = m_mangled.GetCString(); - ManglingScheme mangling_scheme = GetManglingScheme(m_mangled.GetStringRef()); + ManglingScheme mangling_scheme = + GetManglingScheme(m_mangled.GetStringRef()); if (mangling_scheme != eManglingSchemeNone && !m_mangled.GetMangledCounterpart(m_demangled)) { // We didn't already mangle this name, demangle it and if all goes well @@ -307,6 +295,9 @@ ConstString Mangled::GetDemangledName() const { case eManglingSchemeRustV0: demangled_name = GetRustV0DemangledStr(mangled_name); break; + case eManglingSchemeD: + demangled_name = GetDLangDemangledStr(mangled_name); + break; case eManglingSchemeNone: llvm_unreachable("eManglingSchemeNone was handled already"); } @@ -326,8 +317,7 @@ ConstString Mangled::GetDemangledName() const { return m_demangled; } -ConstString -Mangled::GetDisplayDemangledName() const { +ConstString Mangled::GetDisplayDemangledName() const { return GetDemangledName(); } @@ -344,14 +334,16 @@ ConstString Mangled::GetName(Mangled::NamePreference preference) const { if (preference == ePreferMangled && m_mangled) return m_mangled; + // Call the accessor to make sure we get a demangled name in case it hasn't + // been demangled yet... ConstString demangled = GetDemangledName(); if (preference == ePreferDemangledWithoutArguments) { - return GetDemangledNameWithoutArguments(m_mangled, demangled); + if (Language *lang = Language::FindPlugin(GuessLanguage())) { + return lang->GetDemangledFunctionNameWithoutArguments(*this); + } } if (preference == ePreferDemangled) { - // Call the accessor to make sure we get a demangled name in case it hasn't - // been demangled yet... if (demangled) return demangled; return m_mangled; diff --git a/contrib/llvm-project/lldb/source/Core/Module.cpp b/contrib/llvm-project/lldb/source/Core/Module.cpp index 19c97be15066..bd0a667171a5 100644 --- a/contrib/llvm-project/lldb/source/Core/Module.cpp +++ b/contrib/llvm-project/lldb/source/Core/Module.cpp @@ -796,7 +796,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, void Module::FindFunctions(ConstString name, const CompilerDeclContext &parent_decl_ctx, FunctionNameType name_type_mask, - bool include_symbols, bool include_inlines, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) { const size_t old_size = sc_list.GetSize(); @@ -808,12 +808,12 @@ void Module::FindFunctions(ConstString name, if (symbols) { symbols->FindFunctions(lookup_info.GetLookupName(), parent_decl_ctx, - lookup_info.GetNameTypeMask(), include_inlines, - sc_list); + lookup_info.GetNameTypeMask(), + options.include_inlines, sc_list); // Now check our symbol table for symbols that are code symbols if // requested - if (include_symbols) { + if (options.include_symbols) { Symtab *symtab = symbols->GetSymtab(); if (symtab) symtab->FindFunctionSymbols(lookup_info.GetLookupName(), @@ -828,11 +828,11 @@ void Module::FindFunctions(ConstString name, } else { if (symbols) { symbols->FindFunctions(name, parent_decl_ctx, name_type_mask, - include_inlines, sc_list); + options.include_inlines, sc_list); // Now check our symbol table for symbols that are code symbols if // requested - if (include_symbols) { + if (options.include_symbols) { Symtab *symtab = symbols->GetSymtab(); if (symtab) symtab->FindFunctionSymbols(name, name_type_mask, sc_list); @@ -841,17 +841,17 @@ void Module::FindFunctions(ConstString name, } } -void Module::FindFunctions(const RegularExpression ®ex, bool include_symbols, - bool include_inlines, +void Module::FindFunctions(const RegularExpression ®ex, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) { const size_t start_size = sc_list.GetSize(); if (SymbolFile *symbols = GetSymbolFile()) { - symbols->FindFunctions(regex, include_inlines, sc_list); + symbols->FindFunctions(regex, options.include_inlines, sc_list); // Now check our symbol table for symbols that are code symbols if // requested - if (include_symbols) { + if (options.include_symbols) { Symtab *symtab = symbols->GetSymtab(); if (symtab) { std::vector<uint32_t> symbol_indexes; @@ -1614,24 +1614,23 @@ llvm::Optional<std::string> Module::RemapSourceFile(llvm::StringRef path) const void Module::RegisterXcodeSDK(llvm::StringRef sdk_name, llvm::StringRef sysroot) { XcodeSDK sdk(sdk_name.str()); - ConstString sdk_path(HostInfo::GetXcodeSDKPath(sdk)); - if (!sdk_path) + llvm::StringRef sdk_path(HostInfo::GetXcodeSDKPath(sdk)); + if (sdk_path.empty()) 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)) + if (!m_source_mappings.Replace(sysroot, sdk_path, true)) // In the general case, however, append it to the list. - m_source_mappings.Append(sysroot_cs, sdk_path, false); + m_source_mappings.Append(sysroot, sdk_path, false); } bool Module::MergeArchitecture(const ArchSpec &arch_spec) { if (!arch_spec.IsValid()) return false; - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES), - "module has arch %s, merging/replacing with arch %s", - m_arch.GetTriple().getTriple().c_str(), - arch_spec.GetTriple().getTriple().c_str()); + LLDB_LOGF(GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT | LIBLLDB_LOG_MODULES), + "module has arch %s, merging/replacing with arch %s", + m_arch.GetTriple().getTriple().c_str(), + arch_spec.GetTriple().getTriple().c_str()); if (!m_arch.IsCompatibleMatch(arch_spec)) { // The new architecture is different, we just need to replace it. return SetArchitecture(arch_spec); diff --git a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp index 56bc4c72d8e9..9176c9dbb357 100644 --- a/contrib/llvm-project/lldb/source/Core/ModuleList.cpp +++ b/contrib/llvm-project/lldb/source/Core/ModuleList.cpp @@ -122,8 +122,7 @@ void ModuleListProperties::UpdateSymlinkMappings() { FileSpec resolved; Status status = FileSystem::Instance().Readlink(symlink, resolved); if (status.Success()) - m_symlink_paths.Append(ConstString(symlink.GetPath()), - ConstString(resolved.GetPath()), notify); + m_symlink_paths.Append(symlink.GetPath(), resolved.GetPath(), notify); } } @@ -200,16 +199,15 @@ void ModuleList::ReplaceEquivalent( } } -bool ModuleList::AppendIfNeeded(const ModuleSP &module_sp, bool notify) { - if (module_sp) { +bool ModuleList::AppendIfNeeded(const ModuleSP &new_module, bool notify) { + if (new_module) { std::lock_guard<std::recursive_mutex> guard(m_modules_mutex); - collection::iterator pos, end = m_modules.end(); - for (pos = m_modules.begin(); pos != end; ++pos) { - if (pos->get() == module_sp.get()) + for (const ModuleSP &module_sp : m_modules) { + if (module_sp.get() == new_module.get()) return false; // Already in the list } // Only push module_sp on the list if it wasn't already in there. - Append(module_sp, notify); + Append(new_module, notify); return true; } return false; @@ -364,7 +362,7 @@ ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const { void ModuleList::FindFunctions(ConstString name, FunctionNameType name_type_mask, - bool include_symbols, bool include_inlines, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) const { const size_t old_size = sc_list.GetSize(); @@ -372,11 +370,10 @@ void ModuleList::FindFunctions(ConstString name, Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown); 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(), CompilerDeclContext(), - lookup_info.GetNameTypeMask(), include_symbols, - include_inlines, sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindFunctions(lookup_info.GetLookupName(), + CompilerDeclContext(), + lookup_info.GetNameTypeMask(), options, sc_list); } const size_t new_size = sc_list.GetSize(); @@ -385,10 +382,9 @@ void ModuleList::FindFunctions(ConstString name, lookup_info.Prune(sc_list, old_size); } else { 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, CompilerDeclContext(), name_type_mask, - include_symbols, include_inlines, sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindFunctions(name, CompilerDeclContext(), name_type_mask, + options, sc_list); } } } @@ -402,10 +398,9 @@ void ModuleList::FindFunctionSymbols(ConstString name, Module::LookupInfo lookup_info(name, name_type_mask, eLanguageTypeUnknown); 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)->FindFunctionSymbols(lookup_info.GetLookupName(), - lookup_info.GetNameTypeMask(), sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindFunctionSymbols(lookup_info.GetLookupName(), + lookup_info.GetNameTypeMask(), sc_list); } const size_t new_size = sc_list.GetSize(); @@ -414,39 +409,33 @@ void ModuleList::FindFunctionSymbols(ConstString name, lookup_info.Prune(sc_list, old_size); } else { 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)->FindFunctionSymbols(name, name_type_mask, sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindFunctionSymbols(name, name_type_mask, sc_list); } } } void ModuleList::FindFunctions(const RegularExpression &name, - bool include_symbols, bool include_inlines, + const ModuleFunctionSearchOptions &options, SymbolContextList &sc_list) { 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, include_symbols, include_inlines, sc_list); - } + for (const ModuleSP &module_sp : m_modules) + module_sp->FindFunctions(name, options, sc_list); } void ModuleList::FindCompileUnits(const FileSpec &path, SymbolContextList &sc_list) const { 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)->FindCompileUnits(path, sc_list); - } + for (const ModuleSP &module_sp : m_modules) + module_sp->FindCompileUnits(path, sc_list); } void ModuleList::FindGlobalVariables(ConstString name, size_t max_matches, VariableList &variable_list) const { 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, CompilerDeclContext(), max_matches, - variable_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindGlobalVariables(name, CompilerDeclContext(), max_matches, + variable_list); } } @@ -454,36 +443,30 @@ void ModuleList::FindGlobalVariables(const RegularExpression ®ex, size_t max_matches, VariableList &variable_list) const { 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(regex, max_matches, variable_list); - } + for (const ModuleSP &module_sp : m_modules) + module_sp->FindGlobalVariables(regex, max_matches, variable_list); } void ModuleList::FindSymbolsWithNameAndType(ConstString name, SymbolType symbol_type, SymbolContextList &sc_list) const { 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)->FindSymbolsWithNameAndType(name, symbol_type, sc_list); + for (const ModuleSP &module_sp : m_modules) + module_sp->FindSymbolsWithNameAndType(name, symbol_type, sc_list); } void ModuleList::FindSymbolsMatchingRegExAndType( const RegularExpression ®ex, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const { 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)->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list); + for (const ModuleSP &module_sp : m_modules) + module_sp->FindSymbolsMatchingRegExAndType(regex, symbol_type, sc_list); } void ModuleList::FindModules(const ModuleSpec &module_spec, ModuleList &matching_module_list) const { 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) { - ModuleSP module_sp(*pos); + for (const ModuleSP &module_sp : m_modules) { if (module_sp->MatchesModuleSpec(module_spec)) matching_module_list.Append(module_sp); } @@ -559,9 +542,8 @@ void ModuleList::FindTypes(Module *search_first, ConstString name, bool ModuleList::FindSourceFile(const FileSpec &orig_spec, FileSpec &new_spec) const { 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) { - if ((*pos)->FindSourceFile(orig_spec, new_spec)) + for (const ModuleSP &module_sp : m_modules) { + if (module_sp->FindSourceFile(orig_spec, new_spec)) return true; } return false; @@ -573,10 +555,9 @@ void ModuleList::FindAddressesForLine(const lldb::TargetSP target_sp, std::vector<Address> &output_local, std::vector<Address> &output_extern) { 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)->FindAddressesForLine(target_sp, file, line, function, output_local, - output_extern); + for (const ModuleSP &module_sp : m_modules) { + module_sp->FindAddressesForLine(target_sp, file, line, function, + output_local, output_extern); } } @@ -603,10 +584,8 @@ size_t ModuleList::GetSize() const { void ModuleList::Dump(Stream *s) const { 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)->Dump(s); - } + for (const ModuleSP &module_sp : m_modules) + module_sp->Dump(s); } void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) { @@ -629,9 +608,8 @@ void ModuleList::LogUUIDAndPaths(Log *log, const char *prefix_cstr) { bool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) const { 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) { - if ((*pos)->ResolveFileAddress(vm_addr, so_addr)) + for (const ModuleSP &module_sp : m_modules) { + if (module_sp->ResolveFileAddress(vm_addr, so_addr)) return true; } @@ -674,10 +652,9 @@ uint32_t ModuleList::ResolveSymbolContextsForFileSpec( const FileSpec &file_spec, uint32_t line, bool check_inlines, SymbolContextItem resolve_scope, SymbolContextList &sc_list) const { 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)->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, - resolve_scope, sc_list); + for (const ModuleSP &module_sp : m_modules) { + module_sp->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, + resolve_scope, sc_list); } return sc_list.GetSize(); diff --git a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp index fcaa868b083e..801591129244 100644 --- a/contrib/llvm-project/lldb/source/Core/PluginManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/PluginManager.cpp @@ -12,6 +12,7 @@ #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/OptionValueProperties.h" +#include "lldb/Target/Process.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" @@ -184,15 +185,14 @@ template <typename Callback> struct PluginInstance { typedef Callback CallbackType; PluginInstance() = default; - PluginInstance(ConstString name, std::string description, - Callback create_callback = nullptr, + PluginInstance(llvm::StringRef name, llvm::StringRef description, + Callback create_callback, DebuggerInitializeCallback debugger_init_callback = nullptr) - : name(name), description(std::move(description)), - create_callback(create_callback), + : name(name), description(description), create_callback(create_callback), debugger_init_callback(debugger_init_callback) {} - ConstString name; - std::string description; + llvm::StringRef name; + llvm::StringRef description; Callback create_callback; DebuggerInitializeCallback debugger_init_callback; }; @@ -200,12 +200,12 @@ template <typename Callback> struct PluginInstance { template <typename Instance> class PluginInstances { public: template <typename... Args> - bool RegisterPlugin(ConstString name, const char *description, + bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, typename Instance::CallbackType callback, - Args &&... args) { + Args &&...args) { if (!callback) return false; - assert((bool)name); + assert(!name.empty()); Instance instance = Instance(name, description, callback, std::forward<Args>(args)...); m_instances.push_back(instance); @@ -232,20 +232,20 @@ public: return nullptr; } - const char *GetDescriptionAtIndex(uint32_t idx) { + llvm::StringRef GetDescriptionAtIndex(uint32_t idx) { if (Instance *instance = GetInstanceAtIndex(idx)) - return instance->description.c_str(); - return nullptr; + return instance->description; + return ""; } - const char *GetNameAtIndex(uint32_t idx) { + llvm::StringRef GetNameAtIndex(uint32_t idx) { if (Instance *instance = GetInstanceAtIndex(idx)) - return instance->name.GetCString(); - return nullptr; + return instance->name; + return ""; } - typename Instance::CallbackType GetCallbackForName(ConstString name) { - if (!name) + typename Instance::CallbackType GetCallbackForName(llvm::StringRef name) { + if (name.empty()) return nullptr; for (auto &instance : m_instances) { if (name == instance.name) @@ -284,7 +284,8 @@ static ABIInstances &GetABIInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, + llvm::StringRef description, ABICreateInstance create_callback) { return GetABIInstances().RegisterPlugin(name, description, create_callback); } @@ -307,11 +308,10 @@ static ArchitectureInstances &GetArchitectureInstances() { return g_instances; } -void PluginManager::RegisterPlugin(ConstString name, +void PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ArchitectureCreateInstance create_callback) { - GetArchitectureInstances().push_back( - {name, std::string(description), create_callback}); + GetArchitectureInstances().push_back({name, description, create_callback}); } void PluginManager::UnregisterPlugin( @@ -346,7 +346,8 @@ static DisassemblerInstances &GetDisassemblerInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, + llvm::StringRef description, DisassemblerCreateInstance create_callback) { return GetDisassemblerInstances().RegisterPlugin(name, description, create_callback); @@ -363,7 +364,8 @@ PluginManager::GetDisassemblerCreateCallbackAtIndex(uint32_t idx) { } DisassemblerCreateInstance -PluginManager::GetDisassemblerCreateCallbackForPluginName(ConstString name) { +PluginManager::GetDisassemblerCreateCallbackForPluginName( + llvm::StringRef name) { return GetDisassemblerInstances().GetCallbackForName(name); } @@ -378,7 +380,7 @@ static DynamicLoaderInstances &GetDynamicLoaderInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, DynamicLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetDynamicLoaderInstances().RegisterPlugin( @@ -396,7 +398,8 @@ PluginManager::GetDynamicLoaderCreateCallbackAtIndex(uint32_t idx) { } DynamicLoaderCreateInstance -PluginManager::GetDynamicLoaderCreateCallbackForPluginName(ConstString name) { +PluginManager::GetDynamicLoaderCreateCallbackForPluginName( + llvm::StringRef name) { return GetDynamicLoaderInstances().GetCallbackForName(name); } @@ -411,7 +414,7 @@ static JITLoaderInstances &GetJITLoaderInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, JITLoaderCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetJITLoaderInstances().RegisterPlugin( @@ -439,7 +442,7 @@ static EmulateInstructionInstances &GetEmulateInstructionInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, EmulateInstructionCreateInstance create_callback) { return GetEmulateInstructionInstances().RegisterPlugin(name, description, create_callback); @@ -457,7 +460,7 @@ PluginManager::GetEmulateInstructionCreateCallbackAtIndex(uint32_t idx) { EmulateInstructionCreateInstance PluginManager::GetEmulateInstructionCreateCallbackForPluginName( - ConstString name) { + llvm::StringRef name) { return GetEmulateInstructionInstances().GetCallbackForName(name); } @@ -472,7 +475,7 @@ static OperatingSystemInstances &GetOperatingSystemInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, OperatingSystemCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetOperatingSystemInstances().RegisterPlugin( @@ -490,7 +493,8 @@ PluginManager::GetOperatingSystemCreateCallbackAtIndex(uint32_t idx) { } OperatingSystemCreateInstance -PluginManager::GetOperatingSystemCreateCallbackForPluginName(ConstString name) { +PluginManager::GetOperatingSystemCreateCallbackForPluginName( + llvm::StringRef name) { return GetOperatingSystemInstances().GetCallbackForName(name); } @@ -504,7 +508,8 @@ static LanguageInstances &GetLanguageInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, + llvm::StringRef description, LanguageCreateInstance create_callback) { return GetLanguageInstances().RegisterPlugin(name, description, create_callback); @@ -524,13 +529,13 @@ PluginManager::GetLanguageCreateCallbackAtIndex(uint32_t idx) { struct LanguageRuntimeInstance : public PluginInstance<LanguageRuntimeCreateInstance> { LanguageRuntimeInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef 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), + name, description, create_callback, debugger_init_callback), command_callback(command_callback), precondition_callback(precondition_callback) {} @@ -546,7 +551,7 @@ static LanguageRuntimeInstances &GetLanguageRuntimeInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, LanguageRuntimeCreateInstance create_callback, LanguageRuntimeGetCommandObject command_callback, LanguageRuntimeGetExceptionPrecondition precondition_callback) { @@ -592,7 +597,7 @@ static SystemRuntimeInstances &GetSystemRuntimeInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, SystemRuntimeCreateInstance create_callback) { return GetSystemRuntimeInstances().RegisterPlugin(name, description, create_callback); @@ -612,11 +617,12 @@ PluginManager::GetSystemRuntimeCreateCallbackAtIndex(uint32_t idx) { struct ObjectFileInstance : public PluginInstance<ObjectFileCreateInstance> { ObjectFileInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, ObjectFileSaveCore save_core) - : PluginInstance<ObjectFileCreateInstance>(name, std::move(description), + : PluginInstance<ObjectFileCreateInstance>(name, description, create_callback), create_memory_callback(create_memory_callback), get_module_specifications(get_module_specifications), @@ -634,7 +640,7 @@ static ObjectFileInstances &GetObjectFileInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, ObjectFileCreateInstance create_callback, ObjectFileCreateMemoryInstance create_memory_callback, ObjectFileGetModuleSpecifications get_module_specifications, @@ -672,9 +678,7 @@ PluginManager::GetObjectFileGetModuleSpecificationsCallbackAtIndex( ObjectFileCreateMemoryInstance PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( - ConstString name) { - if (!name) - return nullptr; + llvm::StringRef name) { const auto &instances = GetObjectFileInstances().GetInstances(); for (auto &instance : instances) { if (instance.name == name) @@ -685,13 +689,26 @@ PluginManager::GetObjectFileCreateMemoryCallbackForPluginName( Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, const FileSpec &outfile, - lldb::SaveCoreStyle &core_style) { + lldb::SaveCoreStyle &core_style, + llvm::StringRef plugin_name) { + if (plugin_name.empty()) { + // Try saving core directly from the process plugin first. + llvm::Expected<bool> ret = process_sp->SaveCore(outfile.GetPath()); + if (!ret) + return Status(ret.takeError()); + if (ret.get()) + return Status(); + } + + // Fall back to object plugins. Status error; auto &instances = GetObjectFileInstances().GetInstances(); for (auto &instance : instances) { - if (instance.save_core && - instance.save_core(process_sp, outfile, core_style, error)) - return error; + if (plugin_name.empty() || instance.name == plugin_name) { + if (instance.save_core && + instance.save_core(process_sp, outfile, core_style, error)) + return error; + } } error.SetErrorString( "no ObjectFile plugins were able to save a core for this process"); @@ -703,10 +720,11 @@ Status PluginManager::SaveCore(const lldb::ProcessSP &process_sp, struct ObjectContainerInstance : public PluginInstance<ObjectContainerCreateInstance> { ObjectContainerInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, ObjectFileGetModuleSpecifications get_module_specifications) - : PluginInstance<ObjectContainerCreateInstance>( - name, std::move(description), create_callback), + : PluginInstance<ObjectContainerCreateInstance>(name, description, + create_callback), get_module_specifications(get_module_specifications) {} ObjectFileGetModuleSpecifications get_module_specifications; @@ -719,7 +737,7 @@ static ObjectContainerInstances &GetObjectContainerInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, ObjectContainerCreateInstance create_callback, ObjectFileGetModuleSpecifications get_module_specifications) { return GetObjectContainerInstances().RegisterPlugin( @@ -756,7 +774,7 @@ static PlatformInstances &GetPlatformInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, PlatformCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetPlatformInstances().RegisterPlugin( @@ -767,11 +785,12 @@ bool PluginManager::UnregisterPlugin(PlatformCreateInstance create_callback) { return GetPlatformInstances().UnregisterPlugin(create_callback); } -const char *PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { +llvm::StringRef PluginManager::GetPlatformPluginNameAtIndex(uint32_t idx) { return GetPlatformInstances().GetNameAtIndex(idx); } -const char *PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { +llvm::StringRef +PluginManager::GetPlatformPluginDescriptionAtIndex(uint32_t idx) { return GetPlatformInstances().GetDescriptionAtIndex(idx); } @@ -781,15 +800,15 @@ PluginManager::GetPlatformCreateCallbackAtIndex(uint32_t idx) { } PlatformCreateInstance -PluginManager::GetPlatformCreateCallbackForPluginName(ConstString name) { +PluginManager::GetPlatformCreateCallbackForPluginName(llvm::StringRef name) { return GetPlatformInstances().GetCallbackForName(name); } void PluginManager::AutoCompletePlatformName(llvm::StringRef name, CompletionRequest &request) { for (const auto &instance : GetPlatformInstances().GetInstances()) { - if (instance.name.GetStringRef().startswith(name)) - request.AddCompletion(instance.name.GetCString()); + if (instance.name.startswith(name)) + request.AddCompletion(instance.name); } } @@ -804,7 +823,7 @@ static ProcessInstances &GetProcessInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, ProcessCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetProcessInstances().RegisterPlugin( @@ -815,11 +834,11 @@ bool PluginManager::UnregisterPlugin(ProcessCreateInstance create_callback) { return GetProcessInstances().UnregisterPlugin(create_callback); } -const char *PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { +llvm::StringRef PluginManager::GetProcessPluginNameAtIndex(uint32_t idx) { return GetProcessInstances().GetNameAtIndex(idx); } -const char *PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { +llvm::StringRef PluginManager::GetProcessPluginDescriptionAtIndex(uint32_t idx) { return GetProcessInstances().GetDescriptionAtIndex(idx); } @@ -829,15 +848,15 @@ PluginManager::GetProcessCreateCallbackAtIndex(uint32_t idx) { } ProcessCreateInstance -PluginManager::GetProcessCreateCallbackForPluginName(ConstString name) { +PluginManager::GetProcessCreateCallbackForPluginName(llvm::StringRef name) { 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); + if (instance.name.startswith(name)) + request.AddCompletion(instance.name, instance.description); } } @@ -845,11 +864,11 @@ void PluginManager::AutoCompleteProcessName(llvm::StringRef name, struct ScriptInterpreterInstance : public PluginInstance<ScriptInterpreterCreateInstance> { - ScriptInterpreterInstance(ConstString name, std::string description, + ScriptInterpreterInstance(llvm::StringRef name, llvm::StringRef description, CallbackType create_callback, lldb::ScriptLanguage language) - : PluginInstance<ScriptInterpreterCreateInstance>( - name, std::move(description), create_callback), + : PluginInstance<ScriptInterpreterCreateInstance>(name, description, + create_callback), language(language) {} lldb::ScriptLanguage language = lldb::eScriptLanguageNone; @@ -863,7 +882,7 @@ static ScriptInterpreterInstances &GetScriptInterpreterInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, lldb::ScriptLanguage script_language, ScriptInterpreterCreateInstance create_callback) { return GetScriptInterpreterInstances().RegisterPlugin( @@ -903,12 +922,12 @@ PluginManager::GetScriptInterpreterForLanguage(lldb::ScriptLanguage script_lang, struct StructuredDataPluginInstance : public PluginInstance<StructuredDataPluginCreateInstance> { StructuredDataPluginInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, DebuggerInitializeCallback debugger_init_callback, StructuredDataFilterLaunchInfo filter_callback) : PluginInstance<StructuredDataPluginCreateInstance>( - name, std::move(description), create_callback, - debugger_init_callback), + name, description, create_callback, debugger_init_callback), filter_callback(filter_callback) {} StructuredDataFilterLaunchInfo filter_callback = nullptr; @@ -923,7 +942,7 @@ static StructuredDataPluginInstances &GetStructuredDataPluginInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, StructuredDataPluginCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback, StructuredDataFilterLaunchInfo filter_callback) { @@ -966,7 +985,7 @@ static SymbolFileInstances &GetSymbolFileInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, SymbolFileCreateInstance create_callback, DebuggerInitializeCallback debugger_init_callback) { return GetSymbolFileInstances().RegisterPlugin( @@ -992,7 +1011,8 @@ static SymbolVendorInstances &GetSymbolVendorInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, + llvm::StringRef description, SymbolVendorCreateInstance create_callback) { return GetSymbolVendorInstances().RegisterPlugin(name, description, create_callback); @@ -1013,12 +1033,12 @@ PluginManager::GetSymbolVendorCreateCallbackAtIndex(uint32_t idx) { struct TraceInstance : public PluginInstance<TraceCreateInstanceForSessionFile> { TraceInstance( - ConstString name, std::string description, + llvm::StringRef name, llvm::StringRef description, CallbackType create_callback_for_session_file, TraceCreateInstanceForLiveProcess create_callback_for_live_process, llvm::StringRef schema) : PluginInstance<TraceCreateInstanceForSessionFile>( - name, std::move(description), create_callback_for_session_file), + name, description, create_callback_for_session_file), schema(schema), create_callback_for_live_process(create_callback_for_live_process) {} @@ -1034,7 +1054,7 @@ static TraceInstances &GetTracePluginInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, TraceCreateInstanceForSessionFile create_callback_for_session_file, TraceCreateInstanceForLiveProcess create_callback_for_live_process, llvm::StringRef schema) { @@ -1050,19 +1070,19 @@ bool PluginManager::UnregisterPlugin( } TraceCreateInstanceForSessionFile -PluginManager::GetTraceCreateCallback(ConstString plugin_name) { +PluginManager::GetTraceCreateCallback(llvm::StringRef plugin_name) { return GetTracePluginInstances().GetCallbackForName(plugin_name); } TraceCreateInstanceForLiveProcess -PluginManager::GetTraceCreateCallbackForLiveProcess(ConstString plugin_name) { +PluginManager::GetTraceCreateCallbackForLiveProcess(llvm::StringRef plugin_name) { for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) if (instance.name == plugin_name) return instance.create_callback_for_live_process; return nullptr; } -llvm::StringRef PluginManager::GetTraceSchema(ConstString plugin_name) { +llvm::StringRef PluginManager::GetTraceSchema(llvm::StringRef plugin_name) { for (const TraceInstance &instance : GetTracePluginInstances().GetInstances()) if (instance.name == plugin_name) return instance.schema; @@ -1081,11 +1101,11 @@ llvm::StringRef PluginManager::GetTraceSchema(size_t index) { struct TraceExporterInstance : public PluginInstance<TraceExporterCreateInstance> { TraceExporterInstance( - ConstString name, std::string description, + llvm::StringRef name, llvm::StringRef description, TraceExporterCreateInstance create_instance, ThreadTraceExportCommandCreator create_thread_trace_export_command) - : PluginInstance<TraceExporterCreateInstance>( - name, std::move(description), create_instance), + : PluginInstance<TraceExporterCreateInstance>(name, description, + create_instance), create_thread_trace_export_command(create_thread_trace_export_command) { } @@ -1100,7 +1120,7 @@ static TraceExporterInstances &GetTraceExporterInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, TraceExporterCreateInstance create_callback, ThreadTraceExportCommandCreator create_thread_trace_export_command) { return GetTraceExporterInstances().RegisterPlugin( @@ -1108,7 +1128,7 @@ bool PluginManager::RegisterPlugin( } TraceExporterCreateInstance -PluginManager::GetTraceExporterCreateCallback(ConstString plugin_name) { +PluginManager::GetTraceExporterCreateCallback(llvm::StringRef plugin_name) { return GetTraceExporterInstances().GetCallbackForName(plugin_name); } @@ -1125,7 +1145,8 @@ PluginManager::GetThreadTraceExportCommandCreatorAtIndex(uint32_t index) { return nullptr; } -const char *PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { +llvm::StringRef +PluginManager::GetTraceExporterPluginNameAtIndex(uint32_t index) { return GetTraceExporterInstances().GetNameAtIndex(index); } @@ -1140,7 +1161,7 @@ static UnwindAssemblyInstances &GetUnwindAssemblyInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, UnwindAssemblyCreateInstance create_callback) { return GetUnwindAssemblyInstances().RegisterPlugin(name, description, create_callback); @@ -1167,7 +1188,7 @@ static MemoryHistoryInstances &GetMemoryHistoryInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, MemoryHistoryCreateInstance create_callback) { return GetMemoryHistoryInstances().RegisterPlugin(name, description, create_callback); @@ -1188,10 +1209,11 @@ PluginManager::GetMemoryHistoryCreateCallbackAtIndex(uint32_t idx) { struct InstrumentationRuntimeInstance : public PluginInstance<InstrumentationRuntimeCreateInstance> { InstrumentationRuntimeInstance( - ConstString name, std::string description, CallbackType create_callback, + llvm::StringRef name, llvm::StringRef description, + CallbackType create_callback, InstrumentationRuntimeGetType get_type_callback) - : PluginInstance<InstrumentationRuntimeCreateInstance>( - name, std::move(description), create_callback), + : PluginInstance<InstrumentationRuntimeCreateInstance>(name, description, + create_callback), get_type_callback(get_type_callback) {} InstrumentationRuntimeGetType get_type_callback = nullptr; @@ -1206,7 +1228,7 @@ static InstrumentationRuntimeInstances &GetInstrumentationRuntimeInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, InstrumentationRuntimeCreateInstance create_callback, InstrumentationRuntimeGetType get_type_callback) { return GetInstrumentationRuntimeInstances().RegisterPlugin( @@ -1234,11 +1256,11 @@ PluginManager::GetInstrumentationRuntimeCreateCallbackAtIndex(uint32_t idx) { #pragma mark TypeSystem struct TypeSystemInstance : public PluginInstance<TypeSystemCreateInstance> { - TypeSystemInstance(ConstString name, std::string description, + TypeSystemInstance(llvm::StringRef name, llvm::StringRef description, CallbackType create_callback, LanguageSet supported_languages_for_types, LanguageSet supported_languages_for_expressions) - : PluginInstance<TypeSystemCreateInstance>(name, std::move(description), + : PluginInstance<TypeSystemCreateInstance>(name, description, create_callback), supported_languages_for_types(supported_languages_for_types), supported_languages_for_expressions( @@ -1256,7 +1278,7 @@ static TypeSystemInstances &GetTypeSystemInstances() { } bool PluginManager::RegisterPlugin( - ConstString name, const char *description, + llvm::StringRef name, llvm::StringRef description, TypeSystemCreateInstance create_callback, LanguageSet supported_languages_for_types, LanguageSet supported_languages_for_expressions) { @@ -1293,10 +1315,9 @@ LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { #pragma mark REPL struct REPLInstance : public PluginInstance<REPLCreateInstance> { - REPLInstance(ConstString name, std::string description, + REPLInstance(llvm::StringRef name, llvm::StringRef description, CallbackType create_callback, LanguageSet supported_languages) - : PluginInstance<REPLCreateInstance>(name, std::move(description), - create_callback), + : PluginInstance<REPLCreateInstance>(name, description, create_callback), supported_languages(supported_languages) {} LanguageSet supported_languages; @@ -1309,7 +1330,7 @@ static REPLInstances &GetREPLInstances() { return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, const char *description, +bool PluginManager::RegisterPlugin(llvm::StringRef name, llvm::StringRef description, REPLCreateInstance create_callback, LanguageSet supported_languages) { return GetREPLInstances().RegisterPlugin(name, description, create_callback, @@ -1421,8 +1442,9 @@ namespace { typedef lldb::OptionValuePropertiesSP GetDebuggerPropertyForPluginsPtr(Debugger &, ConstString, ConstString, bool can_create); +} -lldb::OptionValuePropertiesSP +static lldb::OptionValuePropertiesSP GetSettingForPlugin(Debugger &debugger, ConstString setting_name, ConstString plugin_type_name, GetDebuggerPropertyForPluginsPtr get_debugger_property = @@ -1438,13 +1460,13 @@ GetSettingForPlugin(Debugger &debugger, ConstString setting_name, return properties_sp; } -bool CreateSettingForPlugin( - Debugger &debugger, ConstString plugin_type_name, - ConstString plugin_type_desc, - const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, - bool is_global_property, - GetDebuggerPropertyForPluginsPtr get_debugger_property = - GetDebuggerPropertyForPlugins) { +static bool +CreateSettingForPlugin(Debugger &debugger, ConstString plugin_type_name, + ConstString plugin_type_desc, + const lldb::OptionValuePropertiesSP &properties_sp, + ConstString description, bool is_global_property, + GetDebuggerPropertyForPluginsPtr get_debugger_property = + GetDebuggerPropertyForPlugins) { if (properties_sp) { lldb::OptionValuePropertiesSP plugin_type_properties_sp( get_debugger_property(debugger, plugin_type_name, plugin_type_desc, @@ -1459,14 +1481,12 @@ bool CreateSettingForPlugin( return false; } -const char *kDynamicLoaderPluginName("dynamic-loader"); -const char *kPlatformPluginName("platform"); -const char *kProcessPluginName("process"); -const char *kSymbolFilePluginName("symbol-file"); -const char *kJITLoaderPluginName("jit-loader"); -const char *kStructuredDataPluginName("structured-data"); - -} // anonymous namespace +static const char *kDynamicLoaderPluginName("dynamic-loader"); +static const char *kPlatformPluginName("platform"); +static const char *kProcessPluginName("process"); +static const char *kSymbolFilePluginName("symbol-file"); +static const char *kJITLoaderPluginName("jit-loader"); +static const char *kStructuredDataPluginName("structured-data"); lldb::OptionValuePropertiesSP PluginManager::GetSettingForDynamicLoaderPlugin(Debugger &debugger, diff --git a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp index 2dcb1407e6c7..63170feb6231 100644 --- a/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp +++ b/contrib/llvm-project/lldb/source/Core/RichManglingContext.cpp @@ -83,19 +83,6 @@ bool RichManglingContext::IsCtorOrDtor() const { llvm_unreachable("Fully covered switch above!"); } -bool RichManglingContext::IsFunction() const { - assert(m_provider != None && "Initialize a provider first"); - switch (m_provider) { - case ItaniumPartialDemangler: - return m_ipd.isFunction(); - case PluginCxxLanguage: - return get<CPlusPlusLanguage::MethodName>(m_cxx_method_parser)->IsValid(); - case None: - return false; - } - llvm_unreachable("Fully covered switch above!"); -} - void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) { // Error case: Clear the buffer. if (LLVM_UNLIKELY(ipd_res == nullptr)) { diff --git a/contrib/llvm-project/lldb/source/Core/Section.cpp b/contrib/llvm-project/lldb/source/Core/Section.cpp index a5a10141aa64..1660e3c92f2c 100644 --- a/contrib/llvm-project/lldb/source/Core/Section.cpp +++ b/contrib/llvm-project/lldb/source/Core/Section.cpp @@ -396,6 +396,76 @@ lldb::offset_t Section::GetSectionData(DataExtractor §ion_data) { return 0; } +bool Section::ContainsOnlyDebugInfo() const { + switch (m_type) { + case eSectionTypeInvalid: + case eSectionTypeCode: + case eSectionTypeContainer: + case eSectionTypeData: + case eSectionTypeDataCString: + case eSectionTypeDataCStringPointers: + case eSectionTypeDataSymbolAddress: + case eSectionTypeData4: + case eSectionTypeData8: + case eSectionTypeData16: + case eSectionTypeDataPointers: + case eSectionTypeZeroFill: + case eSectionTypeDataObjCMessageRefs: + case eSectionTypeDataObjCCFStrings: + case eSectionTypeELFSymbolTable: + case eSectionTypeELFDynamicSymbols: + case eSectionTypeELFRelocationEntries: + case eSectionTypeELFDynamicLinkInfo: + case eSectionTypeEHFrame: + case eSectionTypeARMexidx: + case eSectionTypeARMextab: + case eSectionTypeCompactUnwind: + case eSectionTypeGoSymtab: + case eSectionTypeAbsoluteAddress: + case eSectionTypeOther: + return false; + + case eSectionTypeDebug: + case eSectionTypeDWARFDebugAbbrev: + case eSectionTypeDWARFDebugAbbrevDwo: + case eSectionTypeDWARFDebugAddr: + case eSectionTypeDWARFDebugAranges: + case eSectionTypeDWARFDebugCuIndex: + case eSectionTypeDWARFDebugTuIndex: + case eSectionTypeDWARFDebugFrame: + case eSectionTypeDWARFDebugInfo: + case eSectionTypeDWARFDebugInfoDwo: + case eSectionTypeDWARFDebugLine: + case eSectionTypeDWARFDebugLineStr: + case eSectionTypeDWARFDebugLoc: + case eSectionTypeDWARFDebugLocDwo: + case eSectionTypeDWARFDebugLocLists: + case eSectionTypeDWARFDebugLocListsDwo: + case eSectionTypeDWARFDebugMacInfo: + case eSectionTypeDWARFDebugMacro: + case eSectionTypeDWARFDebugPubNames: + case eSectionTypeDWARFDebugPubTypes: + case eSectionTypeDWARFDebugRanges: + case eSectionTypeDWARFDebugRngLists: + case eSectionTypeDWARFDebugRngListsDwo: + case eSectionTypeDWARFDebugStr: + case eSectionTypeDWARFDebugStrDwo: + case eSectionTypeDWARFDebugStrOffsets: + case eSectionTypeDWARFDebugStrOffsetsDwo: + case eSectionTypeDWARFDebugTypes: + case eSectionTypeDWARFDebugTypesDwo: + case eSectionTypeDWARFDebugNames: + case eSectionTypeDWARFAppleNames: + case eSectionTypeDWARFAppleTypes: + case eSectionTypeDWARFAppleNamespaces: + case eSectionTypeDWARFAppleObjC: + case eSectionTypeDWARFGNUDebugAltLink: + return true; + } + return false; +} + + #pragma mark SectionList SectionList &SectionList::operator=(const SectionList &rhs) { @@ -599,3 +669,15 @@ size_t SectionList::Slide(addr_t slide_amount, bool slide_children) { } return count; } + +uint64_t SectionList::GetDebugInfoSize() const { + uint64_t debug_info_size = 0; + for (const auto §ion : m_sections) { + const SectionList &sub_sections = section->GetChildren(); + if (sub_sections.GetSize() > 0) + debug_info_size += sub_sections.GetDebugInfoSize(); + else if (section->ContainsOnlyDebugInfo()) + debug_info_size += section->GetFileSize(); + } + return debug_info_size; +} diff --git a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp index 9c1112979c54..effba485f026 100644 --- a/contrib/llvm-project/lldb/source/Core/SourceManager.cpp +++ b/contrib/llvm-project/lldb/source/Core/SourceManager.cpp @@ -339,11 +339,14 @@ bool SourceManager::GetDefaultFileAndLine(FileSpec &file_spec, uint32_t &line) { if (executable_ptr) { SymbolContextList sc_list; ConstString main_name("main"); - bool symbols_okay = false; // Force it to be a debug symbol. - bool inlines_okay = true; + + ModuleFunctionSearchOptions function_options; + function_options.include_symbols = + false; // Force it to be a debug symbol. + function_options.include_inlines = true; executable_ptr->FindFunctions(main_name, CompilerDeclContext(), - lldb::eFunctionNameTypeBase, inlines_okay, - symbols_okay, sc_list); + lldb::eFunctionNameTypeBase, + function_options, sc_list); size_t num_matches = sc_list.GetSize(); for (size_t idx = 0; idx < num_matches; idx++) { SymbolContext sc; diff --git a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp index 2f922fe11440..7753397ae0f1 100644 --- a/contrib/llvm-project/lldb/source/Core/StreamFile.cpp +++ b/contrib/llvm-project/lldb/source/Core/StreamFile.cpp @@ -21,8 +21,8 @@ StreamFile::StreamFile(uint32_t flags, uint32_t addr_size, ByteOrder byte_order) } StreamFile::StreamFile(int fd, bool transfer_ownership) : Stream() { - m_file_sp = - std::make_shared<NativeFile>(fd, File::eOpenOptionWrite, transfer_ownership); + m_file_sp = std::make_shared<NativeFile>(fd, File::eOpenOptionWriteOnly, + transfer_ownership); } StreamFile::StreamFile(FILE *fh, bool transfer_ownership) : Stream() { diff --git a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp index 9c1ba99da1d0..6794d0c7331d 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObject.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObject.cpp @@ -849,8 +849,10 @@ bool ValueObject::SetData(DataExtractor &data, Status &error) { static bool CopyStringDataToBufferSP(const StreamString &source, lldb::DataBufferSP &destination) { - destination = std::make_shared<DataBufferHeap>(source.GetSize() + 1, 0); - memcpy(destination->GetBytes(), source.GetString().data(), source.GetSize()); + llvm::StringRef src = source.GetString(); + src.consume_back(llvm::StringRef("\0", 1)); + destination = std::make_shared<DataBufferHeap>(src.size(), 0); + memcpy(destination->GetBytes(), src.data(), src.size()); return true; } @@ -912,8 +914,8 @@ ValueObject::ReadPointedString(lldb::DataBufferSP &buffer_sp, Status &error, CopyStringDataToBufferSP(s, buffer_sp); return {0, was_capped}; } - buffer_sp = std::make_shared<DataBufferHeap>(cstr_len, 0); - memcpy(buffer_sp->GetBytes(), cstr, cstr_len); + s << llvm::StringRef(cstr, cstr_len); + CopyStringDataToBufferSP(s, buffer_sp); return {cstr_len, was_capped}; } else { s << "<invalid address>"; @@ -1196,6 +1198,7 @@ bool ValueObject::DumpPrintableRepresentation( options.SetQuote('"'); options.SetSourceSize(buffer_sp->GetByteSize()); options.SetIsTruncated(read_string.second); + options.SetBinaryZeroIsTerminator(custom_format != eFormatVectorOfChar); formatters::StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::ASCII>( options); diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp index 980cea049f6f..fee1da138bbc 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -34,7 +34,7 @@ using namespace lldb_private; ValueObjectConstResultImpl::ValueObjectConstResultImpl( ValueObject *valobj, lldb::addr_t live_address) : m_impl_backend(valobj), m_live_address(live_address), - m_live_address_type(eAddressTypeLoad), m_load_addr_backend(), + m_live_address_type(eAddressTypeLoad), m_address_of_backend() {} lldb::ValueObjectSP ValueObjectConstResultImpl::Dereference(Status &error) { diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp index d77509496509..bf087f33c0e9 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -36,10 +36,6 @@ ValueObjectDynamicValue::ValueObjectDynamicValue( SetName(parent.GetName()); } -ValueObjectDynamicValue::~ValueObjectDynamicValue() { - m_owning_valobj_sp.reset(); -} - CompilerType ValueObjectDynamicValue::GetCompilerTypeImpl() { const bool success = UpdateValueIfNeeded(false); if (success) { diff --git a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp index 089fd7667080..743083a2d1ed 100644 --- a/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp +++ b/contrib/llvm-project/lldb/source/Core/ValueObjectRegister.cpp @@ -118,8 +118,9 @@ ValueObject *ValueObjectRegisterSet::CreateChildAtIndex( if (m_reg_ctx_sp && m_reg_set) { const size_t num_children = GetNumChildren(); if (idx < num_children) - valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, - m_reg_set->registers[idx]); + valobj = new ValueObjectRegister( + *this, m_reg_ctx_sp, + m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[idx])); } return valobj; } @@ -132,8 +133,7 @@ ValueObjectRegisterSet::GetChildMemberWithName(ConstString name, const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name.GetStringRef()); if (reg_info != nullptr) - valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, - reg_info->kinds[eRegisterKindLLDB]); + valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info); } if (valobj) return valobj->GetSP(); @@ -155,8 +155,7 @@ ValueObjectRegisterSet::GetIndexOfChildWithName(ConstString name) { #pragma mark - #pragma mark ValueObjectRegister -void ValueObjectRegister::ConstructObject(uint32_t reg_num) { - const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoAtIndex(reg_num); +void ValueObjectRegister::ConstructObject(const RegisterInfo *reg_info) { if (reg_info) { m_reg_info = *reg_info; if (reg_info->name) @@ -168,29 +167,29 @@ void ValueObjectRegister::ConstructObject(uint32_t reg_num) { ValueObjectRegister::ValueObjectRegister(ValueObject &parent, lldb::RegisterContextSP ®_ctx_sp, - uint32_t reg_num) + const RegisterInfo *reg_info) : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(), m_reg_value(), m_type_name(), m_compiler_type() { assert(reg_ctx_sp.get()); - ConstructObject(reg_num); + ConstructObject(reg_info); } ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope, lldb::RegisterContextSP ®_ctx_sp, - uint32_t reg_num) { + const RegisterInfo *reg_info) { auto manager_sp = ValueObjectManager::Create(); - return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_num)) + return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_info)) ->GetSP(); } ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope, ValueObjectManager &manager, lldb::RegisterContextSP ®_ctx, - uint32_t reg_num) + const RegisterInfo *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); + ConstructObject(reg_info); } ValueObjectRegister::~ValueObjectRegister() = default; |