diff --git a/contrib/llvm/tools/lldb/FREEBSD-Xlist b/contrib/llvm/tools/lldb/FREEBSD-Xlist index 1eb1e39bf042..9fa6fa48738c 100644 --- a/contrib/llvm/tools/lldb/FREEBSD-Xlist +++ b/contrib/llvm/tools/lldb/FREEBSD-Xlist @@ -5,7 +5,6 @@ CMakeLists.txt CODE_OWNERS.txt INSTALL.txt -Makefile cmake/ docs/CMakeLists.txt docs/building-with-debug-llvm.txt @@ -16,196 +15,166 @@ docs/doxygen.header docs/doxygen.intro docs/lldb-for-gdb-users.txt docs/lldb-gdb-remote.txt +docs/lldb-platform-packets.txt +docs/structured_data/ docs/testsuite/ examples/ -gtest/ -include/Makefile +include/lldb/Host/Config.h include/lldb/Host/android/ include/lldb/Host/linux/ include/lldb/Host/macosx/ -include/lldb/Host/mingw/ -include/lldb/Host/msvc/ include/lldb/Host/windows/ -include/lldb/Makefile -lib/ lit/ lldb.xcodeproj/ lldb.xcworkspace/ +packages/ resources/ scripts/ source/API/CMakeLists.txt -source/API/Makefile source/Breakpoint/CMakeLists.txt -source/Breakpoint/Makefile source/CMakeLists.txt source/Commands/CMakeLists.txt -source/Commands/Makefile source/Core/CMakeLists.txt -source/Core/Makefile source/DataFormatters/CMakeLists.txt -source/DataFormatters/Makefile source/Expression/CMakeLists.txt -source/Expression/Makefile source/Host/CMakeLists.txt -source/Host/Makefile source/Host/android/ source/Host/linux/ source/Host/macosx/ source/Host/windows/ source/Initialization/CMakeLists.txt -source/Initialization/Makefile source/Interpreter/CMakeLists.txt -source/Interpreter/Makefile -source/Makefile source/Plugins/ABI/CMakeLists.txt source/Plugins/ABI/MacOSX-arm/CMakeLists.txt -source/Plugins/ABI/MacOSX-arm/Makefile source/Plugins/ABI/MacOSX-arm64/CMakeLists.txt -source/Plugins/ABI/MacOSX-arm64/Makefile source/Plugins/ABI/MacOSX-i386/CMakeLists.txt -source/Plugins/ABI/MacOSX-i386/Makefile source/Plugins/ABI/SysV-arm/CMakeLists.txt -source/Plugins/ABI/SysV-arm/Makefile source/Plugins/ABI/SysV-arm64/CMakeLists.txt -source/Plugins/ABI/SysV-arm64/Makefile source/Plugins/ABI/SysV-hexagon/CMakeLists.txt -source/Plugins/ABI/SysV-hexagon/Makefile source/Plugins/ABI/SysV-i386/CMakeLists.txt -source/Plugins/ABI/SysV-i386/Makefile source/Plugins/ABI/SysV-mips/CMakeLists.txt -source/Plugins/ABI/SysV-mips/Makefile source/Plugins/ABI/SysV-mips64/CMakeLists.txt -source/Plugins/ABI/SysV-mips64/Makefile source/Plugins/ABI/SysV-ppc/CMakeLists.txt -source/Plugins/ABI/SysV-ppc/Makefile source/Plugins/ABI/SysV-ppc64/CMakeLists.txt -source/Plugins/ABI/SysV-ppc64/Makefile +source/Plugins/ABI/SysV-s390x/CMakeLists.txt source/Plugins/ABI/SysV-x86_64/CMakeLists.txt -source/Plugins/ABI/SysV-x86_64/Makefile +source/Plugins/Architecture/Arm/CMakeLists.txt +source/Plugins/Architecture/CMakeLists.txt +source/Plugins/Architecture/Mips/CMakeLists.txt +source/Plugins/Architecture/PPC64/CMakeLists.txt source/Plugins/CMakeLists.txt source/Plugins/Disassembler/CMakeLists.txt source/Plugins/Disassembler/llvm/CMakeLists.txt -source/Plugins/Disassembler/llvm/Makefile source/Plugins/DynamicLoader/CMakeLists.txt source/Plugins/DynamicLoader/Darwin-Kernel/ source/Plugins/DynamicLoader/Hexagon-DYLD/CMakeLists.txt -source/Plugins/DynamicLoader/Hexagon-DYLD/Makefile source/Plugins/DynamicLoader/MacOSX-DYLD/ source/Plugins/DynamicLoader/POSIX-DYLD/CMakeLists.txt -source/Plugins/DynamicLoader/POSIX-DYLD/Makefile source/Plugins/DynamicLoader/Static/CMakeLists.txt -source/Plugins/DynamicLoader/Static/Makefile source/Plugins/DynamicLoader/Windows-DYLD/CMakeLists.txt -source/Plugins/DynamicLoader/Windows-DYLD/Makefile +source/Plugins/ExpressionParser/CMakeLists.txt +source/Plugins/ExpressionParser/Clang/CMakeLists.txt source/Plugins/Instruction/ARM/CMakeLists.txt -source/Plugins/Instruction/ARM/Makefile source/Plugins/Instruction/ARM64/CMakeLists.txt -source/Plugins/Instruction/ARM64/Makefile source/Plugins/Instruction/CMakeLists.txt source/Plugins/Instruction/MIPS/CMakeLists.txt -source/Plugins/Instruction/MIPS/Makefile source/Plugins/Instruction/MIPS64/CMakeLists.txt -source/Plugins/Instruction/MIPS64/Makefile -source/Plugins/InstrumentationRuntime/AddressSanitizer/CMakeLists.txt -source/Plugins/InstrumentationRuntime/AddressSanitizer/Makefile +source/Plugins/Instruction/PPC64/CMakeLists.txt +source/Plugins/InstrumentationRuntime/ASan/CMakeLists.txt source/Plugins/InstrumentationRuntime/CMakeLists.txt +source/Plugins/InstrumentationRuntime/MainThreadChecker/CMakeLists.txt +source/Plugins/InstrumentationRuntime/TSan/CMakeLists.txt +source/Plugins/InstrumentationRuntime/UBSan/CMakeLists.txt source/Plugins/JITLoader/CMakeLists.txt source/Plugins/JITLoader/GDB/CMakeLists.txt -source/Plugins/JITLoader/GDB/Makefile +source/Plugins/Language/CMakeLists.txt +source/Plugins/Language/CPlusPlus/CMakeLists.txt +source/Plugins/Language/ClangCommon/CMakeLists.txt +source/Plugins/Language/ObjC/CMakeLists.txt +source/Plugins/Language/ObjCPlusPlus/CMakeLists.txt source/Plugins/LanguageRuntime/CMakeLists.txt source/Plugins/LanguageRuntime/CPlusPlus/CMakeLists.txt source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/CMakeLists.txt -source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/Makefile -source/Plugins/LanguageRuntime/ObjC/ +source/Plugins/LanguageRuntime/Go/CMakeLists.txt +source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/CMakeLists.txt +source/Plugins/LanguageRuntime/ObjC/CMakeLists.txt source/Plugins/LanguageRuntime/RenderScript/CMakeLists.txt source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/CMakeLists.txt -source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/Makefile -source/Plugins/Makefile source/Plugins/MemoryHistory/CMakeLists.txt source/Plugins/MemoryHistory/asan/CMakeLists.txt -source/Plugins/MemoryHistory/asan/Makefile source/Plugins/ObjectContainer/BSD-Archive/CMakeLists.txt -source/Plugins/ObjectContainer/BSD-Archive/Makefile source/Plugins/ObjectContainer/CMakeLists.txt source/Plugins/ObjectContainer/Universal-Mach-O/ +source/Plugins/ObjectFile/Breakpad/CMakeLists.txt source/Plugins/ObjectFile/CMakeLists.txt source/Plugins/ObjectFile/ELF/CMakeLists.txt -source/Plugins/ObjectFile/ELF/Makefile source/Plugins/ObjectFile/JIT/CMakeLists.txt -source/Plugins/ObjectFile/JIT/Makefile source/Plugins/ObjectFile/Mach-O/ source/Plugins/ObjectFile/PECOFF/ source/Plugins/OperatingSystem/CMakeLists.txt source/Plugins/OperatingSystem/Python/CMakeLists.txt -source/Plugins/OperatingSystem/Python/Makefile source/Plugins/Platform/Android/ source/Plugins/Platform/CMakeLists.txt source/Plugins/Platform/FreeBSD/CMakeLists.txt -source/Plugins/Platform/FreeBSD/Makefile source/Plugins/Platform/Kalimba/ source/Plugins/Platform/Linux/ source/Plugins/Platform/MacOSX/ -source/Plugins/Platform/Makefile +source/Plugins/Platform/NetBSD/CMakeLists.txt +source/Plugins/Platform/OpenBSD/CMakeLists.txt source/Plugins/Platform/POSIX/CMakeLists.txt -source/Plugins/Platform/POSIX/Makefile source/Plugins/Platform/Windows/ source/Plugins/Platform/gdb-server/CMakeLists.txt -source/Plugins/Platform/gdb-server/Makefile source/Plugins/Process/CMakeLists.txt source/Plugins/Process/FreeBSD/CMakeLists.txt -source/Plugins/Process/FreeBSD/Makefile source/Plugins/Process/Linux/ source/Plugins/Process/MacOSX-Kernel/ +source/Plugins/Process/NetBSD/CMakeLists.txt source/Plugins/Process/POSIX/CMakeLists.txt -source/Plugins/Process/POSIX/Makefile source/Plugins/Process/Utility/CMakeLists.txt -source/Plugins/Process/Utility/Makefile source/Plugins/Process/Windows/ source/Plugins/Process/elf-core/CMakeLists.txt -source/Plugins/Process/elf-core/Makefile source/Plugins/Process/gdb-remote/CMakeLists.txt -source/Plugins/Process/gdb-remote/Makefile source/Plugins/Process/mach-core/ +source/Plugins/Process/minidump/CMakeLists.txt +source/Plugins/ScriptInterpreter/CMakeLists.txt +source/Plugins/ScriptInterpreter/None/CMakeLists.txt +source/Plugins/ScriptInterpreter/Python/CMakeLists.txt +source/Plugins/StructuredData/CMakeLists.txt +source/Plugins/StructuredData/DarwinLog/CMakeLists.txt +source/Plugins/SymbolFile/Breakpad/CMakeLists.txt source/Plugins/SymbolFile/CMakeLists.txt source/Plugins/SymbolFile/DWARF/CMakeLists.txt -source/Plugins/SymbolFile/DWARF/Makefile +source/Plugins/SymbolFile/NativePDB/CMakeLists.txt +source/Plugins/SymbolFile/PDB/CMakeLists.txt source/Plugins/SymbolFile/Symtab/CMakeLists.txt -source/Plugins/SymbolFile/Symtab/Makefile source/Plugins/SymbolVendor/CMakeLists.txt source/Plugins/SymbolVendor/ELF/CMakeLists.txt -source/Plugins/SymbolVendor/ELF/Makefile source/Plugins/SymbolVendor/MacOSX/ source/Plugins/SystemRuntime/ source/Plugins/UnwindAssembly/CMakeLists.txt source/Plugins/UnwindAssembly/InstEmulation/CMakeLists.txt -source/Plugins/UnwindAssembly/InstEmulation/Makefile source/Plugins/UnwindAssembly/x86/CMakeLists.txt -source/Plugins/UnwindAssembly/x86/Makefile source/Symbol/CMakeLists.txt -source/Symbol/Makefile source/Target/CMakeLists.txt -source/Target/Makefile source/Utility/CMakeLists.txt -source/Utility/Makefile test/ +third_party/ tools/CMakeLists.txt -tools/Makefile tools/argdumper/CMakeLists.txt tools/darwin-debug/ tools/darwin-threads/ tools/debugserver/ tools/driver/CMakeLists.txt -tools/driver/Makefile tools/driver/lldb-Info.plist tools/install-headers/ -tools/lldb-gdbserver/ +tools/intel-features/ tools/lldb-mi/CMakeLists.txt -tools/lldb-mi/Makefile tools/lldb-mi/lldb-Info.plist tools/lldb-perf/ -tools/lldb-platform/ tools/lldb-server/CMakeLists.txt -tools/lldb-server/Makefile +tools/lldb-test/ +tools/lldb-vscode/ unittests/ +use_lldb_suite_root.py utils/ www/ diff --git a/contrib/llvm/tools/lldb/include/lldb/API/LLDB.h b/contrib/llvm/tools/lldb/include/lldb/API/LLDB.h index c51ced893d7a..2b3dd96aef0e 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/LLDB.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/LLDB.h @@ -10,10 +10,6 @@ #ifndef LLDB_LLDB_h_ #define LLDB_LLDB_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/API/SBAddress.h" #include "lldb/API/SBAttachInfo.h" #include "lldb/API/SBBlock.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBAddress.h b/contrib/llvm/tools/lldb/include/lldb/API/SBAddress.h index 02e847b97aa1..891324254cd6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBAddress.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBAddress.h @@ -82,6 +82,7 @@ public: protected: friend class SBBlock; + friend class SBBreakpoint; friend class SBBreakpointLocation; friend class SBFrame; friend class SBFunction; diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBBreakpoint.h b/contrib/llvm/tools/lldb/include/lldb/API/SBBreakpoint.h index 216d675b9d22..2c93bf103e3e 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBBreakpoint.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBBreakpoint.h @@ -23,6 +23,8 @@ public: SBBreakpoint(const lldb::SBBreakpoint &rhs); + SBBreakpoint(const lldb::BreakpointSP &bp_sp); + ~SBBreakpoint(); const lldb::SBBreakpoint &operator=(const lldb::SBBreakpoint &rhs); @@ -127,14 +129,18 @@ public: static uint32_t GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event_sp); + bool IsHardware() const; + + // Can only be called from a ScriptedBreakpointResolver... + SBError + AddLocation(SBAddress &address); + private: friend class SBBreakpointList; friend class SBBreakpointLocation; friend class SBBreakpointName; friend class SBTarget; - SBBreakpoint(const lldb::BreakpointSP &bp_sp); - lldb::BreakpointSP GetSP() const; lldb::BreakpointWP m_opaque_wp; diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBCommandInterpreter.h b/contrib/llvm/tools/lldb/include/lldb/API/SBCommandInterpreter.h index 8b9f06599366..f98894478811 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBCommandInterpreter.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBCommandInterpreter.h @@ -10,12 +10,8 @@ #ifndef LLDB_SBCommandInterpreter_h_ #define LLDB_SBCommandInterpreter_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/API/SBDebugger.h" #include "lldb/API/SBDefines.h" @@ -45,6 +41,10 @@ public: void SetEchoCommands(bool); + bool GetEchoCommentCommands() const; + + void SetEchoCommentCommands(bool echo); + bool GetPrintResults() const; void SetPrintResults(bool); @@ -162,6 +162,20 @@ public: int match_start_point, int max_return_elements, lldb::SBStringList &matches); + // Same as HandleCompletion, but also fills out `descriptions` with + // descriptions for each match. + int HandleCompletionWithDescriptions( + const char *current_line, const char *cursor, const char *last_char, + int match_start_point, int max_return_elements, + lldb::SBStringList &matches, lldb::SBStringList &descriptions); + + int HandleCompletionWithDescriptions(const char *current_line, + uint32_t cursor_pos, + int match_start_point, + int max_return_elements, + lldb::SBStringList &matches, + lldb::SBStringList &descriptions); + bool WasInterrupted() const; // Catch commands before they execute by registering a callback that will get diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBCommandReturnObject.h b/contrib/llvm/tools/lldb/include/lldb/API/SBCommandReturnObject.h index a372ea2ad9ee..798aa92a7ef2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBCommandReturnObject.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBCommandReturnObject.h @@ -10,14 +10,10 @@ #ifndef LLDB_SBCommandReturnObject_h_ #define LLDB_SBCommandReturnObject_h_ -// C Includes #include -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/API/SBDefines.h" namespace lldb { diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBDebugger.h b/contrib/llvm/tools/lldb/include/lldb/API/SBDebugger.h index a416b460f318..3f31bf16da8d 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBDebugger.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBDebugger.h @@ -13,6 +13,7 @@ #include #include "lldb/API/SBDefines.h" +#include "lldb/API/SBInitializerOptions.h" #include "lldb/API/SBPlatform.h" namespace lldb { @@ -45,6 +46,7 @@ public: lldb::SBDebugger &operator=(const lldb::SBDebugger &rhs); static void Initialize(); + static lldb::SBError Initialize(SBInitializerOptions &options); static void Terminate(); @@ -109,7 +111,7 @@ public: const char *archname); lldb::SBTarget CreateTarget(const char *filename); - + lldb::SBTarget GetDummyTarget(); // Return true if target is deleted from the target list of the debugger. @@ -226,6 +228,8 @@ public: void SetPrompt(const char *prompt); + const char *GetReproducerPath() const; + lldb::ScriptLanguage GetScriptLanguage() const; void SetScriptLanguage(lldb::ScriptLanguage script_lang); diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBDefines.h b/contrib/llvm/tools/lldb/include/lldb/API/SBDefines.h index ec92c9196737..c5c9851272f2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBDefines.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBDefines.h @@ -10,10 +10,6 @@ #ifndef LLDB_SBDefines_h_ #define LLDB_SBDefines_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" @@ -55,6 +51,7 @@ class LLDB_API SBFileSpecList; class LLDB_API SBFrame; class LLDB_API SBFunction; class LLDB_API SBHostOS; +class LLDB_API SBInitializerOptions; class LLDB_API SBInstruction; class LLDB_API SBInstructionList; class LLDB_API SBLanguageRuntime; diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBExpressionOptions.h b/contrib/llvm/tools/lldb/include/lldb/API/SBExpressionOptions.h index 1459ba6fee2a..b861436caf98 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBExpressionOptions.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBExpressionOptions.h @@ -90,6 +90,12 @@ public: bool GetTopLevel(); void SetTopLevel(bool b = true); + + // Gets whether we will JIT an expression if it cannot be interpreted + bool GetAllowJIT(); + + // Sets whether we will JIT an expression if it cannot be interpreted + void SetAllowJIT(bool allow); protected: SBExpressionOptions( diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBFileSpec.h b/contrib/llvm/tools/lldb/include/lldb/API/SBFileSpec.h index 33e48f5c7c41..9ad1a5df0cfa 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBFileSpec.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBFileSpec.h @@ -59,6 +59,7 @@ private: friend class SBDeclaration; friend class SBFileSpecList; friend class SBHostOS; + friend class SBInitializerOptions; friend class SBLaunchInfo; friend class SBLineEntry; friend class SBModule; @@ -67,8 +68,8 @@ private: friend class SBProcess; friend class SBProcessInfo; friend class SBSourceManager; - friend class SBThread; friend class SBTarget; + friend class SBThread; SBFileSpec(const lldb_private::FileSpec &fspec); diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBFrame.h b/contrib/llvm/tools/lldb/include/lldb/API/SBFrame.h index b8953dd13236..1123dade5de2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBFrame.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBFrame.h @@ -90,6 +90,10 @@ public: bool IsInlined() const; + bool IsArtificial(); + + bool IsArtificial() const; + /// The version that doesn't supply a 'use_dynamic' value will use the /// target's default. lldb::SBValue EvaluateExpression(const char *expr); diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBInitializerOptions.h b/contrib/llvm/tools/lldb/include/lldb/API/SBInitializerOptions.h new file mode 100644 index 000000000000..184c82df4f86 --- /dev/null +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBInitializerOptions.h @@ -0,0 +1,43 @@ +//===-- SBInitializerOptions.h ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBInitializerOptuions_h_ +#define LLDB_SBInitializerOptuions_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBFileSpec.h" + +namespace lldb_private { +struct InitializerOptions; +} + +namespace lldb { + +class LLDB_API SBInitializerOptions { +public: + SBInitializerOptions(); + SBInitializerOptions(const lldb::SBInitializerOptions &rhs); + ~SBInitializerOptions(); + const SBInitializerOptions &operator=(const lldb::SBInitializerOptions &rhs); + + void SetCaptureReproducer(bool b); + void SetReplayReproducer(bool b); + void SetReproducerPath(const char *path); + + lldb_private::InitializerOptions &ref() const; + +private: + friend class SBDebugger; + + std::unique_ptr m_opaque_up; +}; + +} // namespace lldb + +#endif // LLDB_SBInitializerOptuions_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfo.h b/contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfo.h index 297f877a6341..5675d93b8eaf 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfo.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfo.h @@ -102,6 +102,7 @@ private: const lldb_private::MemoryRegionInfo &ref() const; + // Unused. SBMemoryRegionInfo(const lldb_private::MemoryRegionInfo *lldb_object_ptr); lldb::MemoryRegionInfoUP m_opaque_ap; diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfoList.h b/contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfoList.h index 883a2224c92d..1e67997cdaf1 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfoList.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfoList.h @@ -42,6 +42,12 @@ protected: const MemoryRegionInfoListImpl &operator*() const; private: + friend class SBProcess; + + lldb_private::MemoryRegionInfos &ref(); + + const lldb_private::MemoryRegionInfos &ref() const; + std::unique_ptr m_opaque_ap; }; diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBModule.h b/contrib/llvm/tools/lldb/include/lldb/API/SBModule.h index d73267f8af50..7a10e9fc96b3 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBModule.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBModule.h @@ -309,6 +309,7 @@ public: lldb::SBFileSpec GetSymbolFileSpec() const; lldb::SBAddress GetObjectFileHeaderAddress() const; + lldb::SBAddress GetObjectFileEntryPointAddress() const; private: friend class SBAddress; diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBProcess.h b/contrib/llvm/tools/lldb/include/lldb/API/SBProcess.h index 4ad24f63f076..69cf8b4ce854 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBProcess.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBProcess.h @@ -318,11 +318,11 @@ public: /// library name and a list of paths, searching along the list of /// paths till you find a matching library. /// - /// @param[in] local_spec + /// @param[in] image_spec /// The name of the shared library that you want to load. - /// If local_spec is a relative path, the relative path will be + /// If image_spec is a relative path, the relative path will be /// appended to the search paths. - /// If the local_spec is an absolute path, just the basename is used. + /// If the image_spec is an absolute path, just the basename is used. /// /// @param[in] paths /// A list of paths to search for the library whose basename is diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBStructuredData.h b/contrib/llvm/tools/lldb/include/lldb/API/SBStructuredData.h index ca8229a574df..629d4f3e35ee 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBStructuredData.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBStructuredData.h @@ -22,6 +22,8 @@ public: SBStructuredData(const lldb::SBStructuredData &rhs); SBStructuredData(const lldb::EventSP &event_sp); + + SBStructuredData(lldb_private::StructuredDataImpl *impl); ~SBStructuredData(); @@ -41,7 +43,7 @@ public: /// Return the type of data in this data structure //------------------------------------------------------------------ lldb::StructuredDataType GetType() const; - + //------------------------------------------------------------------ /// Return the size (i.e. number of elements) in this data structure /// if it is an array or dictionary type. For other types, 0 will be @@ -49,6 +51,12 @@ public: //------------------------------------------------------------------ size_t GetSize() const; + //------------------------------------------------------------------ + /// Fill keys with the keys in this object and return true if this data + /// structure is a dictionary. Returns false otherwise. + //------------------------------------------------------------------ + bool GetKeys(lldb::SBStringList &keys) const; + //------------------------------------------------------------------ /// Return the value corresponding to a key if this data structure /// is a dictionary type. diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBSymbolContext.h b/contrib/llvm/tools/lldb/include/lldb/API/SBSymbolContext.h index 04ee15e8ecb1..9078b5b789e0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBSymbolContext.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBSymbolContext.h @@ -26,6 +26,8 @@ public: SBSymbolContext(const lldb::SBSymbolContext &rhs); + SBSymbolContext(const lldb_private::SymbolContext *sc_ptr); + ~SBSymbolContext(); bool IsValid() const; @@ -69,8 +71,6 @@ protected: lldb_private::SymbolContext *get() const; - SBSymbolContext(const lldb_private::SymbolContext *sc_ptr); - void SetSymbolContext(const lldb_private::SymbolContext *sc_ptr); private: diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBTarget.h b/contrib/llvm/tools/lldb/include/lldb/API/SBTarget.h index 8d99545902fe..18de267fee00 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBTarget.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBTarget.h @@ -10,10 +10,6 @@ #ifndef LLDB_SBTarget_h_ #define LLDB_SBTarget_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/API/SBAddress.h" #include "lldb/API/SBAttachInfo.h" #include "lldb/API/SBBreakpoint.h" @@ -75,6 +71,31 @@ public: lldb::SBProcess GetProcess(); + //------------------------------------------------------------------ + /// Sets whether we should collect statistics on lldb or not. + /// + /// @param[in] v + /// A boolean to control the collection. + /// @return + /// void + //------------------------------------------------------------------ + void SetCollectingStats(bool v); + + //------------------------------------------------------------------ + /// Returns whether statistics collection are enabled. + /// + /// @return + /// true if statistics are currently being collected, false + /// otherwise. + //------------------------------------------------------------------ + bool GetCollectingStats(); + + //------------------------------------------------------------------ + /// Returns a dump of the collected statistics. + /// + /// @return + /// A SBStructuredData with the statistics collected. + //------------------------------------------------------------------ lldb::SBStructuredData GetStatistics(); //------------------------------------------------------------------ @@ -272,6 +293,10 @@ public: lldb::SBFileSpec GetExecutable(); + // Append the path mapping (from -> to) to the target's paths mapping list. + void AppendImageSearchPath(const char *from, const char *to, + lldb::SBError &error); + bool AddModule(lldb::SBModule &module); lldb::SBModule AddModule(const char *path, const char *triple, @@ -576,6 +601,11 @@ public: BreakpointCreateByLocation(const lldb::SBFileSpec &file_spec, uint32_t line, lldb::addr_t offset, SBFileSpecList &module_list); + lldb::SBBreakpoint + BreakpointCreateByLocation(const lldb::SBFileSpec &file_spec, uint32_t line, + uint32_t column, lldb::addr_t offset, + SBFileSpecList &module_list); + lldb::SBBreakpoint BreakpointCreateByName(const char *symbol_name, const char *module_name = nullptr); @@ -653,6 +683,37 @@ public: lldb::SBBreakpoint BreakpointCreateByAddress(addr_t address); lldb::SBBreakpoint BreakpointCreateBySBAddress(SBAddress &address); + + //------------------------------------------------------------------ + /// Create a breakpoint using a scripted resolver. + /// + /// @param[in] class_name + /// This is the name of the class that implements a scripted resolver. + /// + /// @param[in] extra_args + /// This is an SBStructuredData object that will get passed to the + /// constructor of the class in class_name. You can use this to + /// reuse the same class, parametrizing with entries from this + /// dictionary. + /// + /// @param module_list + /// If this is non-empty, this will be used as the module filter in the + /// SearchFilter created for this breakpoint. + /// + /// @param file_list + /// If this is non-empty, this will be used as the comp unit filter in the + /// SearchFilter created for this breakpoint. + /// + /// @return + /// An SBBreakpoint that will set locations based on the logic in the + /// resolver's search callback. + //------------------------------------------------------------------ + lldb::SBBreakpoint BreakpointCreateFromScript( + const char *class_name, + SBStructuredData &extra_args, + const SBFileSpecList &module_list, + const SBFileSpecList &file_list, + bool request_hardware = false); //------------------------------------------------------------------ /// Read breakpoints from source_file and return the newly created @@ -842,6 +903,7 @@ protected: friend class SBSourceManager; friend class SBSymbol; friend class SBValue; + friend class SBVariablesOptions; //------------------------------------------------------------------ // Constructors are private, use static Target::Create function to create an diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBThread.h b/contrib/llvm/tools/lldb/include/lldb/API/SBThread.h index afc05d2c61ad..63816eef51b7 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBThread.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBThread.h @@ -198,6 +198,10 @@ public: uint32_t GetExtendedBacktraceOriginatingIndexID(); + SBValue GetCurrentException(); + + SBThread GetCurrentExceptionBacktrace(); + bool SafeToCallFunctions(); #ifndef SWIG diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBThreadPlan.h b/contrib/llvm/tools/lldb/include/lldb/API/SBThreadPlan.h index abc14bf8fe4a..5084a427e1b8 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBThreadPlan.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBThreadPlan.h @@ -79,14 +79,28 @@ public: // plans... SBThreadPlan QueueThreadPlanForStepOverRange(SBAddress &start_address, lldb::addr_t range_size); + SBThreadPlan QueueThreadPlanForStepOverRange(SBAddress &start_address, + lldb::addr_t range_size, + SBError &error); SBThreadPlan QueueThreadPlanForStepInRange(SBAddress &start_address, lldb::addr_t range_size); + SBThreadPlan QueueThreadPlanForStepInRange(SBAddress &start_address, + lldb::addr_t range_size, + SBError &error); SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn = false); + SBThreadPlan QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, + bool first_insn, SBError &error); SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address); + SBThreadPlan QueueThreadPlanForRunToAddress(SBAddress address, + SBError &error); + + SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name); + SBThreadPlan QueueThreadPlanForStepScripted(const char *script_class_name, + SBError &error); #ifndef SWIG lldb_private::ThreadPlan *get(); diff --git a/contrib/llvm/tools/lldb/include/lldb/API/SBVariablesOptions.h b/contrib/llvm/tools/lldb/include/lldb/API/SBVariablesOptions.h index 756da6439e3b..0059a41129c5 100644 --- a/contrib/llvm/tools/lldb/include/lldb/API/SBVariablesOptions.h +++ b/contrib/llvm/tools/lldb/include/lldb/API/SBVariablesOptions.h @@ -33,6 +33,10 @@ public: void SetIncludeArguments(bool); + bool GetIncludeRecognizedArguments(const lldb::SBTarget &) const; + + void SetIncludeRecognizedArguments(bool); + bool GetIncludeLocals() const; void SetIncludeLocals(bool); diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Breakpoint.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Breakpoint.h index ec4bc946280f..5861a3be36e1 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Breakpoint.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Breakpoint.h @@ -10,23 +10,19 @@ #ifndef liblldb_Breakpoint_h_ #define liblldb_Breakpoint_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" #include "lldb/Breakpoint/BreakpointLocationList.h" #include "lldb/Breakpoint/BreakpointName.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Breakpoint/Stoppoint.h" -#include "lldb/Core/Event.h" #include "lldb/Core/SearchFilter.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/StringList.h" #include "lldb/Utility/StructuredData.h" @@ -502,6 +498,14 @@ public: //------------------------------------------------------------------ size_t GetNumResolvedLocations() const; + //------------------------------------------------------------------ + /// Return whether this breakpoint has any resolved locations. + /// + /// @return + /// True if GetNumResolvedLocations > 0 + //------------------------------------------------------------------ + bool HasResolvedLocations() const; + //------------------------------------------------------------------ /// Return the number of breakpoint locations. /// diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointID.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointID.h index bbad45ca2d8b..5acb942ed2ad 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointID.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointID.h @@ -10,10 +10,6 @@ #ifndef liblldb_BreakpointID_h_ #define liblldb_BreakpointID_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointIDList.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointIDList.h index ec305583e8d9..2820b9fdcaa5 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointIDList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointIDList.h @@ -10,13 +10,9 @@ #ifndef liblldb_BreakpointIDList_h_ #define liblldb_BreakpointIDList_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/Breakpoint/BreakpointID.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointList.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointList.h index f4c013d41cc2..c4fc650a29f0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointList.h @@ -10,13 +10,9 @@ #ifndef liblldb_BreakpointList_h_ #define liblldb_BreakpointList_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/Breakpoint.h" namespace lldb_private { @@ -53,18 +49,6 @@ public: //------------------------------------------------------------------ void Dump(Stream *s) const; - //------------------------------------------------------------------ - /// Returns a shared pointer to the breakpoint with id \a breakID. - /// - /// @param[in] breakID - /// The breakpoint ID to seek for. - /// - /// @result - /// A shared pointer to the breakpoint. May contain a NULL pointer if the - /// breakpoint doesn't exist. - //------------------------------------------------------------------ - lldb::BreakpointSP FindBreakpointByID(lldb::break_id_t breakID); - //------------------------------------------------------------------ /// Returns a shared pointer to the breakpoint with id \a breakID. Const /// version. @@ -76,7 +60,7 @@ public: /// A shared pointer to the breakpoint. May contain a NULL pointer if the /// breakpoint doesn't exist. //------------------------------------------------------------------ - const lldb::BreakpointSP FindBreakpointByID(lldb::break_id_t breakID) const; + lldb::BreakpointSP FindBreakpointByID(lldb::break_id_t breakID) const; //------------------------------------------------------------------ /// Returns a shared pointer to the breakpoint with index \a i. @@ -88,20 +72,7 @@ public: /// A shared pointer to the breakpoint. May contain a NULL pointer if the /// breakpoint doesn't exist. //------------------------------------------------------------------ - lldb::BreakpointSP GetBreakpointAtIndex(size_t i); - - //------------------------------------------------------------------ - /// Returns a shared pointer to the breakpoint with index \a i, const - /// version - /// - /// @param[in] i - /// The breakpoint index to seek for. - /// - /// @result - /// A shared pointer to the breakpoint. May contain a NULL pointer if the - /// breakpoint doesn't exist. - //------------------------------------------------------------------ - const lldb::BreakpointSP GetBreakpointAtIndex(size_t i) const; + lldb::BreakpointSP GetBreakpointAtIndex(size_t i) const; //------------------------------------------------------------------ /// Find all the breakpoints with a given name @@ -201,7 +172,7 @@ public: void GetListMutex(std::unique_lock &lock); protected: - typedef std::list bp_collection; + typedef std::vector bp_collection; bp_collection::iterator GetBreakpointIDIterator(lldb::break_id_t breakID); @@ -211,7 +182,7 @@ protected: std::recursive_mutex &GetMutex() const { return m_mutex; } mutable std::recursive_mutex m_mutex; - bp_collection m_breakpoints; // The breakpoint list, currently a list. + bp_collection m_breakpoints; lldb::break_id_t m_next_break_id; bool m_is_internal; diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocation.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocation.h index c5911085e61b..6448cb16e927 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocation.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocation.h @@ -10,13 +10,9 @@ #ifndef liblldb_BreakpointLocation_h_ #define liblldb_BreakpointLocation_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Core/Address.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h index 579d468647f3..5a188539622b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -10,13 +10,9 @@ #ifndef liblldb_BreakpointLocationCollection_h_ #define liblldb_BreakpointLocationCollection_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Iterable.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocationList.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocationList.h index 4e61abb2838e..01ee5b5dcce9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocationList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointLocationList.h @@ -10,14 +10,10 @@ #ifndef liblldb_BreakpointLocationList_h_ #define liblldb_BreakpointLocationList_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/Address.h" #include "lldb/Utility/Iterable.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointName.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointName.h index 292a0de4f48b..5e5a04fe9117 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointName.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointName.h @@ -10,22 +10,18 @@ #ifndef liblldb_Breakpoint_Name_h_ #define liblldb_Breakpoint_Name_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" #include "lldb/Breakpoint/BreakpointLocationList.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Breakpoint/Stoppoint.h" -#include "lldb/Core/Event.h" #include "lldb/Core/SearchFilter.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/StringList.h" #include "lldb/Utility/StructuredData.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointOptions.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointOptions.h index 84821817f980..e91df20ed305 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointOptions.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointOptions.h @@ -10,13 +10,9 @@ #ifndef liblldb_BreakpointOptions_h_ #define liblldb_BreakpointOptions_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Baton.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/StringList.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolver.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolver.h index 944741308da6..32008f3dd96f 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolver.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolver.h @@ -10,10 +10,6 @@ #ifndef liblldb_BreakpointResolver_h_ #define liblldb_BreakpointResolver_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Core/Address.h" #include "lldb/Core/SearchFilter.h" @@ -158,6 +154,7 @@ public: AddressResolver, // This is an instance of BreakpointResolverAddress NameResolver, // This is an instance of BreakpointResolverName FileRegexResolver, + PythonResolver, ExceptionResolver, LastKnownResolverType = ExceptionResolver, UnknownResolver @@ -200,17 +197,23 @@ protected: Inlines, LanguageName, LineNumber, + Column, ModuleName, NameMaskArray, Offset, + PythonClassName, RegexString, + ScriptArgs, SectionName, + SearchDepth, SkipPrologue, SymbolNameArray, LastOptionName }; static const char *g_option_names[static_cast(OptionNames::LastOptionName)]; + + virtual void NotifyBreakpointSet() {}; public: static const char *GetKey(OptionNames enum_value) { @@ -224,8 +227,11 @@ protected: /// number that matches, and then filter down the matching addresses to /// unique entries, and skip the prologue if asked to do so, and then set /// breakpoint locations in this breakpoint for all the resultant addresses. + /// When \p column is nonzero the \p line and \p column args are used to + /// filter the results to find the first breakpoint >= (line, column). void SetSCMatchesByLine(SearchFilter &filter, SymbolContextList &sc_list, - bool skip_prologue, llvm::StringRef log_ident); + bool skip_prologue, llvm::StringRef log_ident, + uint32_t line = 0, uint32_t column = 0); void SetSCMatchesByLine(SearchFilter &, SymbolContextList &, bool, const char *) = delete; @@ -237,6 +243,10 @@ protected: // breakpoints we set. private: + /// Helper for \p SetSCMatchesByLine. + void AddLocation(SearchFilter &filter, const SymbolContext &sc, + bool skip_prologue, llvm::StringRef log_ident); + // Subclass identifier (for llvm isa/dyn_cast) const unsigned char SubclassID; DISALLOW_COPY_AND_ASSIGN(BreakpointResolver); diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h index 5845fe7cabed..5d8c0b6b7530 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverAddress.h @@ -10,10 +10,6 @@ #ifndef liblldb_BreakpointResolverAddress_h_ #define liblldb_BreakpointResolverAddress_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Core/ModuleSpec.h" @@ -51,7 +47,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; void GetDescription(Stream *s) override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h index 3464f8ea80d8..8671cd2e5562 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -10,10 +10,6 @@ #ifndef liblldb_BreakpointResolverFileLine_h_ #define liblldb_BreakpointResolverFileLine_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointResolver.h" namespace lldb_private { @@ -28,9 +24,9 @@ namespace lldb_private { class BreakpointResolverFileLine : public BreakpointResolver { public: BreakpointResolverFileLine(Breakpoint *bkpt, const FileSpec &resolver, - uint32_t line_no, lldb::addr_t m_offset, - bool check_inlines, bool skip_prologue, - bool exact_match); + uint32_t line_no, uint32_t column, + lldb::addr_t m_offset, bool check_inlines, + bool skip_prologue, bool exact_match); static BreakpointResolver * CreateFromStructuredData(Breakpoint *bkpt, @@ -45,7 +41,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; void GetDescription(Stream *s) override; @@ -65,10 +61,11 @@ protected: void FilterContexts(SymbolContextList &sc_list, bool is_relative); friend class Breakpoint; - FileSpec m_file_spec; // This is the file spec we are looking for. - uint32_t m_line_number; // This is the line number that we are looking for. - bool m_inlines; // This determines whether the resolver looks for inlined - // functions or not. + FileSpec m_file_spec; ///< This is the file spec we are looking for. + uint32_t m_line_number; ///< This is the line number that we are looking for. + uint32_t m_column; ///< This is the column that we are looking for. + bool m_inlines; ///< This determines whether the resolver looks for inlined + ///< functions or not. bool m_skip_prologue; bool m_exact_match; diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h index c1a7a15566a5..db4f67cf3951 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverFileRegex.h @@ -11,11 +11,7 @@ #ifndef liblldb_BreakpointResolverFileRegex_h_ #define liblldb_BreakpointResolverFileRegex_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Utility/ConstString.h" @@ -47,7 +43,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; void GetDescription(Stream *s) override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverName.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverName.h index 794ea67bb721..416e1aa301b1 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverName.h @@ -10,13 +10,9 @@ #ifndef liblldb_BreakpointResolverName_h_ #define liblldb_BreakpointResolverName_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Core/Module.h" @@ -31,20 +27,23 @@ namespace lldb_private { class BreakpointResolverName : public BreakpointResolver { public: BreakpointResolverName(Breakpoint *bkpt, const char *name, - uint32_t name_type_mask, lldb::LanguageType language, + lldb::FunctionNameType name_type_mask, + lldb::LanguageType language, Breakpoint::MatchType type, lldb::addr_t offset, bool skip_prologue); // This one takes an array of names. It is always MatchType = Exact. BreakpointResolverName(Breakpoint *bkpt, const char *names[], - size_t num_names, uint32_t name_type_mask, + size_t num_names, + lldb::FunctionNameType name_type_mask, lldb::LanguageType language, lldb::addr_t offset, bool skip_prologue); // This one takes a C++ array of names. It is always MatchType = Exact. BreakpointResolverName(Breakpoint *bkpt, std::vector names, - uint32_t name_type_mask, lldb::LanguageType language, - lldb::addr_t offset, bool skip_prologue); + lldb::FunctionNameType name_type_mask, + lldb::LanguageType language, lldb::addr_t offset, + bool skip_prologue); // Creates a function breakpoint by regular expression. Takes over control // of the lifespan of func_regex. @@ -65,7 +64,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; void GetDescription(Stream *s) override; @@ -89,7 +88,8 @@ protected: lldb::LanguageType m_language; bool m_skip_prologue; - void AddNameLookup(const ConstString &name, uint32_t name_type_mask); + void AddNameLookup(const ConstString &name, + lldb::FunctionNameType name_type_mask); }; } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h new file mode 100644 index 000000000000..aaa9cbe4d354 --- /dev/null +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointResolverScripted.h @@ -0,0 +1,81 @@ +//===-- BreakpointResolverScripted.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_BreakpointResolverScripted_h_ +#define liblldb_BreakpointResolverScripted_h_ + +#include "lldb/lldb-forward.h" +#include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/ModuleSpec.h" + + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class BreakpointResolverScripted BreakpointResolverScripted.h +/// "lldb/Breakpoint/BreakpointResolverScripted.h" This class sets breakpoints +/// on a given Address. This breakpoint only takes once, and then it won't +/// attempt to reset itself. +//---------------------------------------------------------------------- + +class BreakpointResolverScripted : public BreakpointResolver { +public: + BreakpointResolverScripted(Breakpoint *bkpt, + const llvm::StringRef class_name, + lldb::SearchDepth depth, + StructuredDataImpl *args_data, + ScriptInterpreter &script_interp); + + ~BreakpointResolverScripted() override; + + static BreakpointResolver * + CreateFromStructuredData(Breakpoint *bkpt, + const StructuredData::Dictionary &options_dict, + Status &error); + + StructuredData::ObjectSP SerializeToStructuredData() override; + + Searcher::CallbackReturn SearchCallback(SearchFilter &filter, + SymbolContext &context, Address *addr, + bool containing) override; + + lldb::SearchDepth GetDepth() override; + + void GetDescription(Stream *s) override; + + void Dump(Stream *s) const override; + + /// Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const BreakpointResolverScripted *) { return true; } + static inline bool classof(const BreakpointResolver *V) { + return V->getResolverID() == BreakpointResolver::PythonResolver; + } + + lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override; + +protected: + void NotifyBreakpointSet() override; +private: + void CreateImplementationIfNeeded(); + ScriptInterpreter *GetScriptInterpreter(); + + std::string m_class_name; + lldb::SearchDepth m_depth; + StructuredDataImpl *m_args_ptr; // We own this, but the implementation + // has to manage the UP (since that is + // how it gets stored in the + // SBStructuredData). + StructuredData::GenericSP m_implementation_sp; + + DISALLOW_COPY_AND_ASSIGN(BreakpointResolverScripted); +}; + +} // namespace lldb_private + +#endif // liblldb_BreakpointResolverScripted_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointSite.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointSite.h index c9bd883ca738..8d1d69076b1c 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointSite.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointSite.h @@ -10,15 +10,11 @@ #ifndef liblldb_BreakpointSite_h_ #define liblldb_BreakpointSite_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocationCollection.h" #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Utility/UserID.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointSiteList.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointSiteList.h index d6530c170430..2f2e31cd3126 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointSiteList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/BreakpointSiteList.h @@ -10,14 +10,10 @@ #ifndef liblldb_BreakpointSiteList_h_ #define liblldb_BreakpointSiteList_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointSite.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Stoppoint.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Stoppoint.h index 3195ef942d9e..78baa6ce6cbb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Stoppoint.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Stoppoint.h @@ -10,10 +10,6 @@ #ifndef liblldb_Stoppoint_h_ #define liblldb_Stoppoint_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/StoppointLocation.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/StoppointLocation.h index 5c717bbc3b0f..5c78d2e3d659 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/StoppointLocation.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/StoppointLocation.h @@ -10,10 +10,6 @@ #ifndef liblldb_StoppointLocation_h_ #define liblldb_StoppointLocation_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" // #include "lldb/Breakpoint/BreakpointOptions.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Watchpoint.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Watchpoint.h index 10df18a5c266..2aaae37eb095 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Watchpoint.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/Watchpoint.h @@ -10,13 +10,9 @@ #ifndef liblldb_Watchpoint_h_ #define liblldb_Watchpoint_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Breakpoint/WatchpointOptions.h" #include "lldb/Symbol/CompilerType.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/WatchpointList.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/WatchpointList.h index d5e0da444afb..9bfa817456bc 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/WatchpointList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/WatchpointList.h @@ -10,14 +10,10 @@ #ifndef liblldb_WatchpointList_h_ #define liblldb_WatchpointList_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/Address.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/WatchpointOptions.h b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/WatchpointOptions.h index 8cb3b97f3a62..0f4f399b5e4d 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Breakpoint/WatchpointOptions.h +++ b/contrib/llvm/tools/lldb/include/lldb/Breakpoint/WatchpointOptions.h @@ -10,13 +10,9 @@ #ifndef liblldb_WatchpointOptions_h_ #define liblldb_WatchpointOptions_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Baton.h" #include "lldb/Utility/StringList.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Address.h b/contrib/llvm/tools/lldb/include/lldb/Core/Address.h index 617aaefe91c9..a02a0d45a082 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Address.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Address.h @@ -10,13 +10,13 @@ #ifndef liblldb_Address_h_ #define liblldb_Address_h_ -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-forward.h" // for SectionWP, SectionSP, ModuleSP -#include "lldb/lldb-private-enumerations.h" // for AddressClass -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" -#include // for size_t -#include // for uint32_t, UINT32_MAX, int64_t +#include +#include namespace lldb_private { class Block; @@ -508,9 +508,9 @@ public: /// /// @see SymbolContextScope::CalculateSymbolContext(SymbolContext*) //------------------------------------------------------------------ - uint32_t CalculateSymbolContext( - SymbolContext *sc, - uint32_t resolve_scope = lldb::eSymbolContextEverything) const; + uint32_t CalculateSymbolContext(SymbolContext *sc, + lldb::SymbolContextItem resolve_scope = + lldb::eSymbolContextEverything) const; lldb::ModuleSP CalculateSymbolContextModule() const; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/AddressRange.h b/contrib/llvm/tools/lldb/include/lldb/Core/AddressRange.h index 9f69c87ee354..e3c820782aaf 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/AddressRange.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/AddressRange.h @@ -11,10 +11,10 @@ #define liblldb_AddressRange_h_ #include "lldb/Core/Address.h" -#include "lldb/lldb-forward.h" // for SectionSP -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" -#include // for size_t +#include namespace lldb_private { class SectionList; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolver.h b/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolver.h index cfd103e0be01..32751d64d6b4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolver.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolver.h @@ -12,9 +12,9 @@ #include "lldb/Core/AddressRange.h" #include "lldb/Core/SearchFilter.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN +#include "lldb/lldb-defines.h" -#include // for size_t +#include #include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolverFileLine.h b/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolverFileLine.h index e434a62e0319..bee72245ee6b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolverFileLine.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolverFileLine.h @@ -11,11 +11,11 @@ #define liblldb_AddressResolverFileLine_h_ #include "lldb/Core/AddressResolver.h" -#include "lldb/Core/SearchFilter.h" // for Searcher, Searcher::CallbackR... -#include "lldb/Utility/FileSpec.h" // for FileSpec -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN +#include "lldb/Core/SearchFilter.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/lldb-defines.h" -#include // for uint32_t +#include namespace lldb_private { class Address; @@ -47,7 +47,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; void GetDescription(Stream *s) override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolverName.h b/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolverName.h index 49a805f2115a..b4291938b290 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolverName.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/AddressResolverName.h @@ -11,10 +11,10 @@ #define liblldb_AddressResolverName_h_ #include "lldb/Core/AddressResolver.h" -#include "lldb/Core/SearchFilter.h" // for Searcher, Searcher::Call... -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Core/SearchFilter.h" +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/RegularExpression.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN +#include "lldb/lldb-defines.h" namespace lldb_private { class Address; @@ -52,7 +52,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; void GetDescription(Stream *s) override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Architecture.h b/contrib/llvm/tools/lldb/include/lldb/Core/Architecture.h index 3a5a9789223d..20537d67b02c 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Architecture.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Architecture.h @@ -67,6 +67,51 @@ public: virtual void AdjustBreakpointAddress(const Symbol &func, Address &addr) const {} + + //------------------------------------------------------------------ + /// Get \a load_addr as a callable code load address for this target + /// + /// Take \a load_addr and potentially add any address bits that are + /// needed to make the address callable. For ARM this can set bit + /// zero (if it already isn't) if \a load_addr is a thumb function. + /// If \a addr_class is set to AddressClass::eInvalid, then the address + /// adjustment will always happen. If it is set to an address class + /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be + /// returned. + //------------------------------------------------------------------ + virtual lldb::addr_t GetCallableLoadAddress( + lldb::addr_t addr, AddressClass addr_class = AddressClass::eInvalid) const { + return addr; + } + + //------------------------------------------------------------------ + /// Get \a load_addr as an opcode for this target. + /// + /// Take \a load_addr and potentially strip any address bits that are + /// needed to make the address point to an opcode. For ARM this can + /// clear bit zero (if it already isn't) if \a load_addr is a + /// thumb function and load_addr is in code. + /// If \a addr_class is set to AddressClass::eInvalid, then the address + /// adjustment will always happen. If it is set to an address class + /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be + /// returned. + //------------------------------------------------------------------ + + virtual lldb::addr_t GetOpcodeLoadAddress( + lldb::addr_t addr, AddressClass addr_class = AddressClass::eInvalid) const { + return addr; + } + + // Get load_addr as breakable load address for this target. Take a addr and + // check if for any reason there is a better address than this to put a + // breakpoint on. If there is then return that address. For MIPS, if + // instruction at addr is a delay slot instruction then this method will find + // the address of its previous instruction and return that address. + virtual lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr, + Target &target) const { + return addr; + } + private: Architecture(const Architecture &) = delete; void operator=(const Architecture &) = delete; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ClangForward.h b/contrib/llvm/tools/lldb/include/lldb/Core/ClangForward.h index b3cab8a22f21..3fc12a555301 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ClangForward.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ClangForward.h @@ -10,10 +10,6 @@ #ifndef liblldb_ClangForward_h_ #define liblldb_ClangForward_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #if defined(__cplusplus) diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Communication.h b/contrib/llvm/tools/lldb/include/lldb/Core/Communication.h index 3e29307039e4..f129b8f879d0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Communication.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Communication.h @@ -10,21 +10,21 @@ #ifndef liblldb_Communication_h_ #define liblldb_Communication_h_ -#include "lldb/Core/Broadcaster.h" #include "lldb/Host/HostThread.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Timeout.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ConnectionStatus, FLAGS_ANONYMOU... -#include "lldb/lldb-forward.h" // for ConnectionSP -#include "lldb/lldb-types.h" // for thread_arg_t, thread_result_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" #include #include -#include // for micro +#include #include -#include // for size_t -#include // for uint8_t +#include +#include namespace lldb_private { class Connection; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Debugger.h b/contrib/llvm/tools/lldb/include/lldb/Core/Debugger.h index cc7176e5c95d..09f75ef0f8c6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Debugger.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Debugger.h @@ -10,44 +10,40 @@ #ifndef liblldb_Debugger_h_ #define liblldb_Debugger_h_ -// C Includes #include -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/SourceManager.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/Terminal.h" -#include "lldb/Target/ExecutionContext.h" // for ExecutionContext +#include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "lldb/Target/TargetList.h" -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/Utility/FileSpec.h" // for FileSpec -#include "lldb/Utility/Status.h" // for Status +#include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Status.h" #include "lldb/Utility/UserID.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ScriptLanguage, Langua... -#include "lldb/lldb-forward.h" // for StreamFileSP, DebuggerSP -#include "lldb/lldb-private-enumerations.h" // for VarSetOperationType -#include "lldb/lldb-private-types.h" // for LoadPluginCallbackType -#include "lldb/lldb-types.h" // for LogOutputCallback, thr... +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-private-types.h" +#include "lldb/lldb-types.h" -#include "llvm/ADT/ArrayRef.h" // for ArrayRef -#include "llvm/ADT/StringMap.h" // for StringMap -#include "llvm/ADT/StringRef.h" // for StringRef -#include "llvm/Support/DynamicLibrary.h" // for DynamicLibrary +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Threading.h" -#include // for assert -#include // for size_t +#include +#include #include namespace lldb_private { @@ -192,7 +188,8 @@ public: lldb::StreamFileSP &out, lldb::StreamFileSP &err); - void PushIOHandler(const lldb::IOHandlerSP &reader_sp); + void PushIOHandler(const lldb::IOHandlerSP &reader_sp, + bool cancel_top_handler = true); bool PopIOHandler(const lldb::IOHandlerSP &reader_sp); @@ -264,6 +261,8 @@ public: void SetPrompt(llvm::StringRef p); void SetPrompt(const char *) = delete; + llvm::StringRef GetReproducerPath() const; + bool GetUseExternalEditor() const; bool SetUseExternalEditor(bool use_external_editor_p); @@ -272,11 +271,13 @@ public: bool SetUseColor(bool use_color); + bool GetHighlightSource() const; + lldb::StopShowColumn GetStopShowColumn() const; - const FormatEntity::Entry *GetStopShowColumnAnsiPrefix() const; + llvm::StringRef GetStopShowColumnAnsiPrefix() const; - const FormatEntity::Entry *GetStopShowColumnAnsiSuffix() const; + llvm::StringRef GetStopShowColumnAnsiSuffix() const; uint32_t GetStopSourceLineCount(bool before) const; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Disassembler.h b/contrib/llvm/tools/lldb/include/lldb/Core/Disassembler.h index ef1f2ee54dd1..7cec837e71f8 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Disassembler.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Disassembler.h @@ -12,32 +12,32 @@ #include "lldb/Core/Address.h" #include "lldb/Core/EmulateInstruction.h" -#include "lldb/Core/FormatEntity.h" // for FormatEntity +#include "lldb/Core/FormatEntity.h" #include "lldb/Core/Opcode.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Symbol/LineEntry.h" -#include "lldb/Target/ExecutionContext.h" // for ExecutionContext +#include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-forward.h" // for InstructionSP, DisassemblerSP -#include "lldb/lldb-private-enumerations.h" // for AddressClass -#include "lldb/lldb-types.h" // for addr_t, offset_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" -#include // for function +#include #include -#include // for enable_shared_from_this +#include #include #include #include -#include // for size_t -#include // for uint32_t, int64_t -#include // for FILE +#include +#include +#include namespace lldb_private { class AddressRange; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/DumpDataExtractor.h b/contrib/llvm/tools/lldb/include/lldb/Core/DumpDataExtractor.h index 46e676c239d1..88446d48fa64 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/DumpDataExtractor.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/DumpDataExtractor.h @@ -10,11 +10,11 @@ #ifndef LLDB_CORE_DUMPDATAEXTRACTOR_H #define LLDB_CORE_DUMPDATAEXTRACTOR_H -#include "lldb/lldb-enumerations.h" // for Format +#include "lldb/lldb-enumerations.h" #include "lldb/lldb-types.h" -#include // for size_t -#include // for uint32_t, uint64_t +#include +#include namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/EmulateInstruction.h b/contrib/llvm/tools/lldb/include/lldb/Core/EmulateInstruction.h index 5d23bcd7b96e..5198f3eac922 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/EmulateInstruction.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/EmulateInstruction.h @@ -12,18 +12,18 @@ #include -#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Address.h" #include "lldb/Core/Opcode.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Utility/ArchSpec.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for RegisterKind, ByteOrder -#include "lldb/lldb-private-enumerations.h" // for InstructionType -#include "lldb/lldb-private-types.h" // for RegisterInfo -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-private-types.h" +#include "lldb/lldb-types.h" -#include // for size_t -#include // for uint32_t, uint64_t, int64_t +#include +#include namespace lldb_private { class OptionValueDictionary; } diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/FileLineResolver.h b/contrib/llvm/tools/lldb/include/lldb/Core/FileLineResolver.h index 855d749ed5d4..6de99bc0c4dc 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/FileLineResolver.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/FileLineResolver.h @@ -10,12 +10,12 @@ #ifndef liblldb_FileLineResolver_h_ #define liblldb_FileLineResolver_h_ -#include "lldb/Core/SearchFilter.h" // for Searcher, Searcher::CallbackR... +#include "lldb/Core/SearchFilter.h" #include "lldb/Symbol/SymbolContext.h" -#include "lldb/Utility/FileSpec.h" // for FileSpec -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN +#include "lldb/Utility/FileSpec.h" +#include "lldb/lldb-defines.h" -#include // for uint32_t, UINT32_MAX +#include namespace lldb_private { class Address; @@ -48,7 +48,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; void GetDescription(Stream *s) override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/FileSpecList.h b/contrib/llvm/tools/lldb/include/lldb/Core/FileSpecList.h index 713ed2aaffc6..db6490ef7133 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/FileSpecList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/FileSpecList.h @@ -15,7 +15,7 @@ #include -#include // for size_t +#include namespace lldb_private { class Stream; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/FormatEntity.h b/contrib/llvm/tools/lldb/include/lldb/Core/FormatEntity.h index 93c7b3a94e4e..b58f3b104e46 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/FormatEntity.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/FormatEntity.h @@ -11,13 +11,13 @@ #define liblldb_FormatEntity_h_ #include "lldb/Utility/CompletionRequest.h" -#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" -#include "lldb/lldb-enumerations.h" // for Format::eFormatDefault, Format -#include "lldb/lldb-types.h" // for addr_t -#include // for min -#include // for size_t -#include // for uint32_t, uint64_t +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-types.h" +#include +#include +#include #include #include @@ -88,6 +88,7 @@ public: FrameRegisterFP, FrameRegisterFlags, FrameRegisterByName, + FrameIsArtificial, ScriptFrame, FunctionID, FunctionDidChange, @@ -104,6 +105,7 @@ public: FunctionIsOptimized, LineEntryFile, LineEntryLineNumber, + LineEntryColumn, LineEntryStartAddress, LineEntryEndAddress, CurrentPCArrow diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Highlighter.h b/contrib/llvm/tools/lldb/include/lldb/Core/Highlighter.h new file mode 100644 index 000000000000..220557c1f032 --- /dev/null +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Highlighter.h @@ -0,0 +1,165 @@ +//===-- Highlighter.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_Highlighter_h_ +#define liblldb_Highlighter_h_ + +#include +#include + +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-enumerations.h" +#include "llvm/ADT/StringRef.h" + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// Represents style that the highlighter should apply to the given source code. +/// Stores information about how every kind of token should be annotated. +//---------------------------------------------------------------------- +struct HighlightStyle { + + //---------------------------------------------------------------------- + /// A pair of strings that should be placed around a certain token. Usually + /// stores color codes in these strings (the suffix string is often used for + /// resetting the terminal attributes back to normal). + //---------------------------------------------------------------------- + class ColorStyle { + std::string m_prefix; + std::string m_suffix; + + public: + ColorStyle() = default; + ColorStyle(llvm::StringRef prefix, llvm::StringRef suffix) { + Set(prefix, suffix); + } + + /// Applies this style to the given value. + /// \param s + /// The stream to which the result should be appended. + /// \param value + /// The value that we should place our strings around. + void Apply(Stream &s, llvm::StringRef value) const; + + /// Sets the prefix and suffix strings. + /// @param prefix + /// @param suffix + void Set(llvm::StringRef prefix, llvm::StringRef suffix); + }; + + /// The style for the token which is below the cursor of the user. Note that + /// this style is overwritten by the SourceManager with the values of + /// stop-show-column-ansi-prefix/stop-show-column-ansi-suffix. + ColorStyle selected; + + /// Matches identifiers to variable or functions. + ColorStyle identifier; + /// Matches any string or character literals in the language: "foo" or 'f' + ColorStyle string_literal; + /// Matches scalar value literals like '42' or '0.1'. + ColorStyle scalar_literal; + /// Matches all reserved keywords in the language. + ColorStyle keyword; + /// Matches any comments in the language. + ColorStyle comment; + /// Matches commas: ',' + ColorStyle comma; + /// Matches one colon: ':' + ColorStyle colon; + /// Matches any semicolon: ';' + ColorStyle semicolons; + /// Matches operators like '+', '-', '%', '&', '=' + ColorStyle operators; + + /// Matches '{' or '}' + ColorStyle braces; + /// Matches '[' or ']' + ColorStyle square_brackets; + /// Matches '(' or ')' + ColorStyle parentheses; + + //----------------------------------------------------------------------- + // C language specific options + //----------------------------------------------------------------------- + + /// Matches directives to a preprocessor (if the language has any). + ColorStyle pp_directive; + + /// Returns a HighlightStyle that is based on vim's default highlight style. + static HighlightStyle MakeVimStyle(); +}; + +//---------------------------------------------------------------------- +/// Annotates source code with color attributes. +//---------------------------------------------------------------------- +class Highlighter { +public: + Highlighter() = default; + virtual ~Highlighter() = default; + DISALLOW_COPY_AND_ASSIGN(Highlighter); + + /// Returns a human readable name for the selected highlighter. + virtual llvm::StringRef GetName() const = 0; + + /// Highlights the given line + /// \param options + /// \param line + /// The user supplied line that needs to be highlighted. + /// \param cursor_pos + /// The cursor position of the user in this line, starting at 0 (which + /// means the cursor is on the first character in 'line'). + /// \param previous_lines + /// Any previous lines the user has written which we should only use + /// for getting the context of the Highlighting right. + /// \param s + /// The stream to which the highlighted version of the user string should + /// be written. + virtual void Highlight(const HighlightStyle &options, llvm::StringRef line, + llvm::Optional cursor_pos, + llvm::StringRef previous_lines, Stream &s) const = 0; + + /// Utility method for calling Highlight without a stream. + std::string Highlight(const HighlightStyle &options, llvm::StringRef line, + llvm::Optional cursor_pos, + llvm::StringRef previous_lines = "") const; +}; + +/// A default highlighter that only highlights the user cursor, but doesn't +/// do any other highlighting. +class DefaultHighlighter : public Highlighter { +public: + llvm::StringRef GetName() const override { return "none"; } + + void Highlight(const HighlightStyle &options, llvm::StringRef line, + llvm::Optional cursor_pos, + llvm::StringRef previous_lines, Stream &s) const override; +}; + +/// Manages the available highlighters. +class HighlighterManager { + DefaultHighlighter m_default; + +public: + /// Queries all known highlighter for one that can highlight some source code. + /// \param language_type + /// The language type that the caller thinks the source code was given in. + /// \param path + /// The path to the file the source code is from. Used as a fallback when + /// the user can't provide a language. + /// \return + /// The highlighter that wants to highlight the source code. Could be an + /// empty highlighter that does nothing. + const Highlighter &getHighlighterFor(lldb::LanguageType language_type, + llvm::StringRef path) const; + const Highlighter &getDefaultHighlighter() const { return m_default; } +}; + +} // namespace lldb_private + +#endif // liblldb_Highlighter_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/IOHandler.h b/contrib/llvm/tools/lldb/include/lldb/Core/IOHandler.h index 2170ad10674e..4bd577390b2c 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/IOHandler.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/IOHandler.h @@ -11,22 +11,22 @@ #define liblldb_IOHandler_h_ #include "lldb/Core/ValueObjectList.h" -#include "lldb/Host/Predicate.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" +#include "lldb/Utility/Predicate.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StringList.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-forward.h" // for IOHandlerSP, StreamFileSP -#include "llvm/ADT/StringRef.h" // for StringRef +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringRef.h" #include #include #include #include -#include // for uint32_t -#include // for FILE +#include +#include namespace lldb_private { class Debugger; @@ -205,7 +205,7 @@ public: virtual int IOHandlerComplete(IOHandler &io_handler, const char *current_line, const char *cursor, const char *last_char, int skip_first_n_matches, int max_matches, - StringList &matches); + StringList &matches, StringList &descriptions); virtual const char *IOHandlerGetFixIndentationCharacters() { return nullptr; } @@ -430,7 +430,8 @@ private: static int AutoCompleteCallback(const char *current_line, const char *cursor, const char *last_char, int skip_first_n_matches, int max_matches, - StringList &matches, void *baton); + StringList &matches, StringList &descriptions, + void *baton); #endif protected: @@ -464,7 +465,7 @@ public: int IOHandlerComplete(IOHandler &io_handler, const char *current_line, const char *cursor, const char *last_char, int skip_first_n_matches, int max_matches, - StringList &matches) override; + StringList &matches, StringList &descriptions) override; void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/LoadedModuleInfoList.h b/contrib/llvm/tools/lldb/include/lldb/Core/LoadedModuleInfoList.h index 6554c64fa870..5ef0f8929b89 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/LoadedModuleInfoList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/LoadedModuleInfoList.h @@ -10,14 +10,11 @@ #ifndef liblldb_LoadedModuleInfoList_h_ #define liblldb_LoadedModuleInfoList_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes #include "lldb/lldb-defines.h" #include "lldb/lldb-private-forward.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Mangled.h b/contrib/llvm/tools/lldb/include/lldb/Core/Mangled.h index d263297ecfc6..12edf8200e43 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Mangled.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Mangled.h @@ -11,18 +11,15 @@ #define liblldb_Mangled_h_ #if defined(__cplusplus) +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" + #include "lldb/Utility/ConstString.h" -#include "lldb/lldb-enumerations.h" // for LanguageType -#include "llvm/ADT/StringRef.h" // for StringRef -#include // for size_t +#include "llvm/ADT/StringRef.h" -namespace lldb_private { -class RegularExpression; -} -namespace lldb_private { -class Stream; -} +#include +#include namespace lldb_private { @@ -238,7 +235,6 @@ public: return true; return GetDemangledName(language) == name; } - bool NameMatches(const RegularExpression ®ex, lldb::LanguageType language) const; @@ -300,6 +296,36 @@ public: //---------------------------------------------------------------------- lldb::LanguageType GuessLanguage() const; + /// Function signature for filtering mangled names. + using SkipMangledNameFn = bool(llvm::StringRef, ManglingScheme); + + //---------------------------------------------------------------------- + /// Trigger explicit demangling to obtain rich mangling information. This is + /// optimized for batch processing while populating a name index. To get the + /// pure demangled name string for a single entity, use GetDemangledName() + /// instead. + /// + /// For names that match the Itanium mangling scheme, this uses LLVM's + /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin + /// parser currently. + /// + /// This function is thread-safe when used with different \a context + /// instances in different threads. + /// + /// @param[in] context + /// The context for this function. A single instance can be stack- + /// allocated in the caller's frame and used for multiple calls. + /// + /// @param[in] skip_mangled_name + /// A filtering function for skipping entities based on name and mangling + /// scheme. This can be null if unused. + /// + /// @return + /// True on success, false otherwise. + //---------------------------------------------------------------------- + bool DemangleWithRichManglingInfo(RichManglingContext &context, + SkipMangledNameFn *skip_mangled_name); + private: //---------------------------------------------------------------------- /// Mangled member variables. diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/MappedHash.h b/contrib/llvm/tools/lldb/include/lldb/Core/MappedHash.h index 1bdf59c73649..8d9a91e69079 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/MappedHash.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/MappedHash.h @@ -10,18 +10,14 @@ #ifndef liblldb_MappedHash_h_ #define liblldb_MappedHash_h_ -// C Includes #include #include -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Stream.h" #include "llvm/Support/DJB.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Module.h b/contrib/llvm/tools/lldb/include/lldb/Core/Module.h index 83d5f519f086..270a401172fa 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Module.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Module.h @@ -10,31 +10,31 @@ #ifndef liblldb_Module_h_ #define liblldb_Module_h_ -#include "lldb/Core/Address.h" // for Address -#include "lldb/Core/ModuleSpec.h" // for ModuleSpec -#include "lldb/Symbol/ObjectFile.h" // for ObjectFile +#include "lldb/Core/Address.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContextScope.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Status.h" // for Status +#include "lldb/Utility/Status.h" #include "lldb/Utility/UUID.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for LanguageType, SymbolType +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" -#include "lldb/lldb-types.h" // for addr_t, offset_t +#include "lldb/lldb-types.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Chrono.h" #include -#include // for enable_shared_from_this +#include #include -#include // for size_t -#include // for uint32_t, uint64_t +#include +#include #include #include @@ -168,10 +168,11 @@ public: // Once we get the object file, update our module with the object file's // architecture since it might differ in vendor/os if some parts were // unknown. - if (!module_sp->m_objfile_sp->GetArchitecture(module_sp->m_arch)) - return nullptr; - - return module_sp; + if (ArchSpec arch = module_sp->m_objfile_sp->GetArchitecture()) { + module_sp->m_arch = arch; + return module_sp; + } + return nullptr; } //------------------------------------------------------------------ @@ -380,7 +381,7 @@ public: //------------------------------------------------------------------ size_t FindFunctions(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool symbols_ok, + lldb::FunctionNameType name_type_mask, bool symbols_ok, bool inlines_ok, bool append, SymbolContextList &sc_list); @@ -498,10 +499,6 @@ public: /// have to specify complete scoping on all expressions, but it also allows /// for exact matching when required. /// - /// @param[in] sc - /// A symbol context that scopes where to extract a type list - /// from. - /// /// @param[in] type_name /// The name of the type we are looking for that is a fully /// or partially qualified type name. @@ -520,8 +517,7 @@ public: /// The number of matches added to \a type_list. //------------------------------------------------------------------ size_t - FindTypes(const SymbolContext &sc, const ConstString &type_name, - bool exact_match, size_t max_matches, + FindTypes(const ConstString &type_name, bool exact_match, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeList &types); @@ -533,10 +529,6 @@ public: /// expression parser when searches need to happen in an exact namespace /// scope. /// - /// @param[in] sc - /// A symbol context that scopes where to extract a type list - /// from. - /// /// @param[in] type_name /// The name of a type within a namespace that should not include /// any qualifying namespaces (just a type basename). @@ -550,8 +542,7 @@ public: /// @return /// The number of matches added to \a type_list. //------------------------------------------------------------------ - size_t FindTypesInNamespace(const SymbolContext &sc, - const ConstString &type_name, + size_t FindTypesInNamespace(const ConstString &type_name, const CompilerDeclContext *parent_decl_ctx, size_t max_matches, TypeList &type_list); @@ -816,10 +807,9 @@ public: /// /// @see SymbolContext::Scope //------------------------------------------------------------------ - uint32_t - ResolveSymbolContextForAddress(const Address &so_addr, uint32_t resolve_scope, - SymbolContext &sc, - bool resolve_tail_call_address = false); + uint32_t ResolveSymbolContextForAddress( + const Address &so_addr, lldb::SymbolContextItem resolve_scope, + SymbolContext &sc, bool resolve_tail_call_address = false); //------------------------------------------------------------------ /// Resolve items in the symbol context for a given file and line. @@ -862,10 +852,9 @@ public: /// /// @see SymbolContext::Scope //------------------------------------------------------------------ - uint32_t ResolveSymbolContextForFilePath(const char *file_path, uint32_t line, - bool check_inlines, - uint32_t resolve_scope, - SymbolContextList &sc_list); + uint32_t ResolveSymbolContextForFilePath( + const char *file_path, uint32_t line, bool check_inlines, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); //------------------------------------------------------------------ /// Resolve items in the symbol context for a given file and line. @@ -909,10 +898,9 @@ public: /// /// @see SymbolContext::Scope //------------------------------------------------------------------ - uint32_t ResolveSymbolContextsForFileSpec(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - uint32_t resolve_scope, - SymbolContextList &sc_list); + uint32_t ResolveSymbolContextsForFileSpec( + const FileSpec &file_spec, uint32_t line, bool check_inlines, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); void SetFileSpecAndObjectName(const FileSpec &file, const ConstString &object_name); @@ -1031,9 +1019,10 @@ public: public: LookupInfo() : m_name(), m_lookup_name(), m_language(lldb::eLanguageTypeUnknown), - m_name_type_mask(0), m_match_name_after_lookup(false) {} + m_name_type_mask(lldb::eFunctionNameTypeNone), + m_match_name_after_lookup(false) {} - LookupInfo(const ConstString &name, uint32_t name_type_mask, + LookupInfo(const ConstString &name, lldb::FunctionNameType name_type_mask, lldb::LanguageType language); const ConstString &GetName() const { return m_name; } @@ -1044,24 +1033,31 @@ public: void SetLookupName(const ConstString &name) { m_lookup_name = name; } - uint32_t GetNameTypeMask() const { return m_name_type_mask; } + lldb::FunctionNameType GetNameTypeMask() const { return m_name_type_mask; } - void SetNameTypeMask(uint32_t mask) { m_name_type_mask = mask; } + void SetNameTypeMask(lldb::FunctionNameType mask) { + m_name_type_mask = mask; + } void Prune(SymbolContextList &sc_list, size_t start_idx) const; protected: - ConstString m_name; ///< What the user originally typed - ConstString m_lookup_name; ///< The actual name will lookup when calling in - ///the object or symbol file - lldb::LanguageType - m_language; ///< Limit matches to only be for this language - uint32_t m_name_type_mask; ///< One or more bits from lldb::FunctionNameType - ///that indicate what kind of names we are - ///looking for - bool m_match_name_after_lookup; ///< If \b true, then demangled names that - ///match will need to contain "m_name" in - ///order to be considered a match + /// What the user originally typed + ConstString m_name; + + /// The actual name will lookup when calling in the object or symbol file + ConstString m_lookup_name; + + /// Limit matches to only be for this language + lldb::LanguageType m_language; + + /// One or more bits from lldb::FunctionNameType that indicate what kind of + /// names we are looking for + lldb::FunctionNameType m_name_type_mask; + + ///< If \b true, then demangled names that match will need to contain + ///< "m_name" in order to be considered a match + bool m_match_name_after_lookup; }; protected: @@ -1155,7 +1151,7 @@ protected: //------------------------------------------------------------------ uint32_t ResolveSymbolContextForAddress(lldb::addr_t vm_addr, bool vm_addr_is_file_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, Address &so_addr, SymbolContext &sc); void SymbolIndicesToSymbolContextList(Symtab *symtab, @@ -1176,9 +1172,8 @@ private: Module(); // Only used internally by CreateJITModule () size_t FindTypes_Impl( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - size_t max_matches, + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ModuleList.h b/contrib/llvm/tools/lldb/include/lldb/Core/ModuleList.h index e1d8a9a7fb85..a28d97113d63 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ModuleList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ModuleList.h @@ -10,12 +10,12 @@ #ifndef liblldb_ModuleList_h_ #define liblldb_ModuleList_h_ -#include "lldb/Core/Address.h" // for Address -#include "lldb/Core/ModuleSpec.h" // for ModuleSpec +#include "lldb/Core/Address.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/UserSettingsController.h" -#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Iterable.h" -#include "lldb/Utility/Status.h" // for Status +#include "lldb/Utility/Status.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" @@ -27,8 +27,8 @@ #include #include -#include // for size_t -#include // for uint32_t +#include +#include namespace lldb_private { class ConstString; @@ -300,14 +300,16 @@ public: //------------------------------------------------------------------ /// @see Module::FindFunctions () //------------------------------------------------------------------ - size_t FindFunctions(const ConstString &name, uint32_t name_type_mask, + size_t FindFunctions(const ConstString &name, + lldb::FunctionNameType name_type_mask, bool include_symbols, bool include_inlines, bool append, SymbolContextList &sc_list) const; //------------------------------------------------------------------ /// @see Module::FindFunctionSymbols () //------------------------------------------------------------------ - size_t FindFunctionSymbols(const ConstString &name, uint32_t name_type_mask, + size_t FindFunctionSymbols(const ConstString &name, + lldb::FunctionNameType name_type_mask, SymbolContextList &sc_list); //------------------------------------------------------------------ @@ -415,9 +417,9 @@ public: //------------------------------------------------------------------ /// Find types by name. /// - /// @param[in] sc - /// A symbol context that scopes where to extract a type list - /// from. + /// @param[in] search_first + /// If non-null, this module will be searched before any other + /// modules. /// /// @param[in] name /// The name of the type we are looking for. @@ -445,7 +447,7 @@ public: /// @return /// The number of matches added to \a type_list. //------------------------------------------------------------------ - size_t FindTypes(const SymbolContext &sc, const ConstString &name, + size_t FindTypes(Module *search_first, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeList &types) const; @@ -495,26 +497,24 @@ public: /// &,uint32_t,SymbolContext&) //------------------------------------------------------------------ uint32_t ResolveSymbolContextForAddress(const Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, SymbolContext &sc) const; //------------------------------------------------------------------ /// @copydoc Module::ResolveSymbolContextForFilePath (const char /// *,uint32_t,bool,uint32_t,SymbolContextList&) //------------------------------------------------------------------ - uint32_t ResolveSymbolContextForFilePath(const char *file_path, uint32_t line, - bool check_inlines, - uint32_t resolve_scope, - SymbolContextList &sc_list) const; + uint32_t ResolveSymbolContextForFilePath( + const char *file_path, uint32_t line, bool check_inlines, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const; //------------------------------------------------------------------ /// @copydoc Module::ResolveSymbolContextsForFileSpec (const FileSpec /// &,uint32_t,bool,uint32_t,SymbolContextList&) //------------------------------------------------------------------ - uint32_t ResolveSymbolContextsForFileSpec(const FileSpec &file_spec, - uint32_t line, bool check_inlines, - uint32_t resolve_scope, - SymbolContextList &sc_list) const; + uint32_t ResolveSymbolContextsForFileSpec( + const FileSpec &file_spec, uint32_t line, bool check_inlines, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) const; //------------------------------------------------------------------ /// Gets the size of the module list. diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ModuleSpec.h b/contrib/llvm/tools/lldb/include/lldb/Core/ModuleSpec.h index 16a35a187780..ae772c2a1efe 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ModuleSpec.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ModuleSpec.h @@ -10,18 +10,15 @@ #ifndef liblldb_ModuleSpec_h_ #define liblldb_ModuleSpec_h_ -// Project includes +#include "lldb/Host/FileSystem.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/UUID.h" -// Other libraries and framework includes #include "llvm/Support/Chrono.h" -// C Includes -// C++ Includes #include #include @@ -34,15 +31,17 @@ public: m_object_name(), m_object_offset(0), m_object_size(0), m_source_mappings() {} - ModuleSpec(const FileSpec &file_spec, const UUID& uuid = UUID()) + ModuleSpec(const FileSpec &file_spec, const UUID &uuid = UUID()) : m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(), m_uuid(uuid), m_object_name(), m_object_offset(0), - m_object_size(file_spec.GetByteSize()), m_source_mappings() {} + m_object_size(FileSystem::Instance().GetByteSize(file_spec)), + m_source_mappings() {} ModuleSpec(const FileSpec &file_spec, const ArchSpec &arch) : m_file(file_spec), m_platform_file(), m_symbol_file(), m_arch(arch), m_uuid(), m_object_name(), m_object_offset(0), - m_object_size(file_spec.GetByteSize()), m_source_mappings() {} + m_object_size(FileSystem::Instance().GetByteSize(file_spec)), + m_source_mappings() {} ModuleSpec(const ModuleSpec &rhs) : m_file(rhs.m_file), m_platform_file(rhs.m_platform_file), @@ -256,20 +255,20 @@ public: if (match_module_spec.GetFileSpecPtr()) { const FileSpec &fspec = match_module_spec.GetFileSpec(); if (!FileSpec::Equal(fspec, GetFileSpec(), - fspec.GetDirectory().IsEmpty() == false)) + !fspec.GetDirectory().IsEmpty())) return false; } if (GetPlatformFileSpec() && match_module_spec.GetPlatformFileSpecPtr()) { const FileSpec &fspec = match_module_spec.GetPlatformFileSpec(); if (!FileSpec::Equal(fspec, GetPlatformFileSpec(), - fspec.GetDirectory().IsEmpty() == false)) + !fspec.GetDirectory().IsEmpty())) return false; } // Only match the symbol file spec if there is one in this ModuleSpec if (GetSymbolFileSpec() && match_module_spec.GetSymbolFileSpecPtr()) { const FileSpec &fspec = match_module_spec.GetSymbolFileSpec(); if (!FileSpec::Equal(fspec, GetSymbolFileSpec(), - fspec.GetDirectory().IsEmpty() == false)) + !fspec.GetDirectory().IsEmpty())) return false; } if (match_module_spec.GetArchitecturePtr()) { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Opcode.h b/contrib/llvm/tools/lldb/include/lldb/Core/Opcode.h index 33857457b2c4..fb6cc825abd2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Opcode.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Opcode.h @@ -11,12 +11,12 @@ #define lldb_Opcode_h #include "lldb/Utility/Endian.h" -#include "lldb/lldb-enumerations.h" // for ByteOrder, ByteOrder::eByteOrde... +#include "lldb/lldb-enumerations.h" #include "llvm/Support/MathExtras.h" -#include // for assert -#include // for uint32_t, uint8_t, uint16_t +#include +#include #include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/PluginInterface.h b/contrib/llvm/tools/lldb/include/lldb/Core/PluginInterface.h index edda15a1ace0..24f53c62ab09 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/PluginInterface.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/PluginInterface.h @@ -10,10 +10,6 @@ #ifndef liblldb_PluginInterface_h_ #define liblldb_PluginInterface_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/PluginManager.h b/contrib/llvm/tools/lldb/include/lldb/Core/PluginManager.h index b782294f1f60..598ee9a8d8e3 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/PluginManager.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/PluginManager.h @@ -12,14 +12,14 @@ #include "lldb/Core/Architecture.h" #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-enumerations.h" // for ScriptLanguage -#include "lldb/lldb-forward.h" // for OptionValuePropertiesSP -#include "lldb/lldb-private-interfaces.h" // for DebuggerInitializeCallback -#include "llvm/ADT/StringRef.h" // for StringRef +#include "lldb/Utility/Status.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-interfaces.h" +#include "llvm/ADT/StringRef.h" -#include // for size_t -#include // for uint32_t +#include +#include namespace lldb_private { class CommandInterpreter; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h b/contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h index 45bda26e2659..5a75a24f7f61 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/RangeMap.h @@ -10,15 +10,11 @@ #ifndef liblldb_RangeMap_h_ #define liblldb_RangeMap_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "llvm/ADT/SmallVector.h" -// Project includes #include "lldb/lldb-private.h" // Uncomment to make sure all Range objects are sorted when needed @@ -169,8 +165,6 @@ public: #ifdef ASSERT_RANGEMAP_ARE_SORTED bool IsSorted() const { typename Collection::const_iterator pos, end, prev; - // First we determine if we can combine any of the Entry objects so we - // don't end up allocating and making a new collection for no reason for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++) { if (prev != end && *pos < *prev) @@ -639,201 +633,12 @@ struct RangeData : public Range { } }; -template class RangeDataArray { +template +class RangeDataVector { public: typedef RangeData Entry; typedef llvm::SmallVector Collection; - RangeDataArray() = default; - - ~RangeDataArray() = default; - - void Append(const Entry &entry) { m_entries.push_back(entry); } - - void Sort() { - if (m_entries.size() > 1) - std::stable_sort(m_entries.begin(), m_entries.end()); - } - -#ifdef ASSERT_RANGEMAP_ARE_SORTED - bool IsSorted() const { - typename Collection::const_iterator pos, end, prev; - // First we determine if we can combine any of the Entry objects so we - // don't end up allocating and making a new collection for no reason - for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; - prev = pos++) { - if (prev != end && *pos < *prev) - return false; - } - return true; - } -#endif - - void CombineConsecutiveEntriesWithEqualData() { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - typename Collection::iterator pos; - typename Collection::iterator end; - typename Collection::iterator prev; - bool can_combine = false; - // First we determine if we can combine any of the Entry objects so we - // don't end up allocating and making a new collection for no reason - for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; - prev = pos++) { - if (prev != end && prev->data == pos->data) { - can_combine = true; - break; - } - } - - // We we can combine at least one entry, then we make a new collection and - // populate it accordingly, and then swap it into place. - if (can_combine) { - Collection minimal_ranges; - for (pos = m_entries.begin(), end = m_entries.end(), prev = end; - pos != end; prev = pos++) { - if (prev != end && prev->data == pos->data) - minimal_ranges.back().SetRangeEnd(pos->GetRangeEnd()); - else - minimal_ranges.push_back(*pos); - } - // Use the swap technique in case our new vector is much smaller. We must - // swap when using the STL because std::vector objects never release or - // reduce the memory once it has been allocated/reserved. - m_entries.swap(minimal_ranges); - } - } - - void Clear() { m_entries.clear(); } - - bool IsEmpty() const { return m_entries.empty(); } - - size_t GetSize() const { return m_entries.size(); } - - const Entry *GetEntryAtIndex(size_t i) const { - return ((i < m_entries.size()) ? &m_entries[i] : nullptr); - } - - // Clients must ensure that "i" is a valid index prior to calling this - // function - const Entry &GetEntryRef(size_t i) const { return m_entries[i]; } - - static bool BaseLessThan(const Entry &lhs, const Entry &rhs) { - return lhs.GetRangeBase() < rhs.GetRangeBase(); - } - - uint32_t FindEntryIndexThatContains(B addr) const { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (!m_entries.empty()) { - Entry entry(addr, 1); - typename Collection::const_iterator begin = m_entries.begin(); - typename Collection::const_iterator end = m_entries.end(); - typename Collection::const_iterator pos = - std::lower_bound(begin, end, entry, BaseLessThan); - - if (pos != end && pos->Contains(addr)) { - return std::distance(begin, pos); - } else if (pos != begin) { - --pos; - if (pos->Contains(addr)) - return std::distance(begin, pos); - } - } - return UINT32_MAX; - } - - Entry *FindEntryThatContains(B addr) { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (!m_entries.empty()) { - Entry entry; - entry.SetRangeBase(addr); - entry.SetByteSize(1); - typename Collection::iterator begin = m_entries.begin(); - typename Collection::iterator end = m_entries.end(); - typename Collection::iterator pos = - std::lower_bound(begin, end, entry, BaseLessThan); - - if (pos != end && pos->Contains(addr)) { - return &(*pos); - } else if (pos != begin) { - --pos; - if (pos->Contains(addr)) { - return &(*pos); - } - } - } - return nullptr; - } - - const Entry *FindEntryThatContains(B addr) const { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (!m_entries.empty()) { - Entry entry; - entry.SetRangeBase(addr); - entry.SetByteSize(1); - typename Collection::const_iterator begin = m_entries.begin(); - typename Collection::const_iterator end = m_entries.end(); - typename Collection::const_iterator pos = - std::lower_bound(begin, end, entry, BaseLessThan); - - if (pos != end && pos->Contains(addr)) { - return &(*pos); - } else if (pos != begin) { - --pos; - if (pos->Contains(addr)) { - return &(*pos); - } - } - } - return nullptr; - } - - const Entry *FindEntryThatContains(const Entry &range) const { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (!m_entries.empty()) { - typename Collection::const_iterator begin = m_entries.begin(); - typename Collection::const_iterator end = m_entries.end(); - typename Collection::const_iterator pos = - std::lower_bound(begin, end, range, BaseLessThan); - - if (pos != end && pos->Contains(range)) { - return &(*pos); - } else if (pos != begin) { - --pos; - if (pos->Contains(range)) { - return &(*pos); - } - } - } - return nullptr; - } - - Entry *Back() { return (m_entries.empty() ? nullptr : &m_entries.back()); } - - const Entry *Back() const { - return (m_entries.empty() ? nullptr : &m_entries.back()); - } - -protected: - Collection m_entries; -}; - -// Same as RangeDataArray, but uses std::vector as to not require static -// storage of N items in the class itself -template class RangeDataVector { -public: - typedef RangeData Entry; - typedef std::vector Collection; - RangeDataVector() = default; ~RangeDataVector() = default; @@ -895,38 +700,8 @@ public: } } - // Calculate the byte size of ranges with zero byte sizes by finding the next - // entry with a base address > the current base address - void CalculateSizesOfZeroByteSizeRanges(S full_size = 0) { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - typename Collection::iterator pos; - typename Collection::iterator end; - typename Collection::iterator next; - for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos) { - if (pos->GetByteSize() == 0) { - // Watch out for multiple entries with same address and make sure we - // find an entry that is greater than the current base address before - // we use that for the size - auto curr_base = pos->GetRangeBase(); - for (next = pos + 1; next != end; ++next) { - auto next_base = next->GetRangeBase(); - if (next_base > curr_base) { - pos->SetByteSize(next_base - curr_base); - break; - } - } - if (next == end && full_size > curr_base) - pos->SetByteSize(full_size - curr_base); - } - } - } - void Clear() { m_entries.clear(); } - void Reserve(typename Collection::size_type size) { m_entries.resize(size); } - bool IsEmpty() const { return m_entries.empty(); } size_t GetSize() const { return m_entries.size(); } @@ -948,22 +723,9 @@ public: } uint32_t FindEntryIndexThatContains(B addr) const { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (!m_entries.empty()) { - Entry entry(addr, 1); - typename Collection::const_iterator begin = m_entries.begin(); - typename Collection::const_iterator end = m_entries.end(); - typename Collection::const_iterator pos = - std::lower_bound(begin, end, entry, BaseLessThan); - - while (pos != begin && pos[-1].Contains(addr)) - --pos; - - if (pos != end && pos->Contains(addr)) - return std::distance(begin, pos); - } + const Entry *entry = FindEntryThatContains(addr); + if (entry) + return std::distance(m_entries.begin(), entry); return UINT32_MAX; } @@ -983,47 +745,13 @@ public: } Entry *FindEntryThatContains(B addr) { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (!m_entries.empty()) { - Entry entry; - entry.SetRangeBase(addr); - entry.SetByteSize(1); - typename Collection::iterator begin = m_entries.begin(); - typename Collection::iterator end = m_entries.end(); - typename Collection::iterator pos = - std::lower_bound(begin, end, entry, BaseLessThan); - - while (pos != begin && pos[-1].Contains(addr)) - --pos; - - if (pos != end && pos->Contains(addr)) - return &(*pos); - } - return nullptr; + return const_cast( + static_cast(this)->FindEntryThatContains( + addr)); } const Entry *FindEntryThatContains(B addr) const { -#ifdef ASSERT_RANGEMAP_ARE_SORTED - assert(IsSorted()); -#endif - if (!m_entries.empty()) { - Entry entry; - entry.SetRangeBase(addr); - entry.SetByteSize(1); - typename Collection::const_iterator begin = m_entries.begin(); - typename Collection::const_iterator end = m_entries.end(); - typename Collection::const_iterator pos = - std::lower_bound(begin, end, entry, BaseLessThan); - - while (pos != begin && pos[-1].Contains(addr)) - --pos; - - if (pos != end && pos->Contains(addr)) - return &(*pos); - } - return nullptr; + return FindEntryThatContains(Entry(addr, 1)); } const Entry *FindEntryThatContains(const Entry &range) const { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/RichManglingContext.h b/contrib/llvm/tools/lldb/include/lldb/Core/RichManglingContext.h new file mode 100644 index 000000000000..30841bfb2668 --- /dev/null +++ b/contrib/llvm/tools/lldb/include/lldb/Core/RichManglingContext.h @@ -0,0 +1,108 @@ +//===-- RichManglingContext.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RichManglingContext_h_ +#define liblldb_RichManglingContext_h_ + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private.h" + +#include "lldb/Utility/ConstString.h" + +#include "llvm/ADT/Any.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Demangle/Demangle.h" + +namespace lldb_private { + +/// Uniform wrapper for access to rich mangling information from different +/// providers. See Mangled::DemangleWithRichManglingInfo() +class RichManglingContext { +public: + RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) { + m_ipd_buf = static_cast(std::malloc(m_ipd_buf_size)); + m_ipd_buf[0] = '\0'; + } + + ~RichManglingContext() { std::free(m_ipd_buf); } + + /// Use the ItaniumPartialDemangler to obtain rich mangling information from + /// the given mangled name. + bool FromItaniumName(const ConstString &mangled); + + /// Use the legacy language parser implementation to obtain rich mangling + /// information from the given demangled name. + bool FromCxxMethodName(const ConstString &demangled); + + /// If this symbol describes a constructor or destructor. + bool IsCtorOrDtor() const; + + /// If this symbol describes a function. + bool IsFunction() const; + + /// Get the base name of a function. This doesn't include trailing template + /// arguments, ie "a::b" gives "b". The result will overwrite the + /// internal buffer. It can be obtained via GetBufferRef(). + void ParseFunctionBaseName(); + + /// Get the context name for a function. For "a::b::c", this function returns + /// "a::b". The result will overwrite the internal buffer. It can be obtained + /// via GetBufferRef(). + void ParseFunctionDeclContextName(); + + /// Get the entire demangled name. The result will overwrite the internal + /// buffer. It can be obtained via GetBufferRef(). + void ParseFullName(); + + /// Obtain a StringRef to the internal buffer that holds the result of the + /// most recent ParseXy() operation. The next ParseXy() call invalidates it. + llvm::StringRef GetBufferRef() const { + assert(m_provider != None && "Initialize a provider first"); + return m_buffer; + } + +private: + enum InfoProvider { None, ItaniumPartialDemangler, PluginCxxLanguage }; + + /// Selects the rich mangling info provider. + InfoProvider m_provider; + + /// Reference to the buffer used for results of ParseXy() operations. + llvm::StringRef m_buffer; + + /// Members for ItaniumPartialDemangler + llvm::ItaniumPartialDemangler m_ipd; + char *m_ipd_buf; + size_t m_ipd_buf_size; + + /// Members for PluginCxxLanguage + /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The + /// respective header is in Plugins and including it from here causes cyclic + /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp. + llvm::Any m_cxx_method_parser; + + /// Clean up memory and set a new info provider for this instance. + void ResetProvider(InfoProvider new_provider); + + /// Uniform handling of string buffers for ItaniumPartialDemangler. + void processIPDStrResult(char *ipd_res, size_t res_len); + + /// Cast the given parser to the given type. Ideally we would have a type + /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we + /// can't access CPlusPlusLanguage::MethodName from within the header. + template static ParserT *get(llvm::Any parser) { + assert(parser.hasValue()); + assert(llvm::any_isa(parser)); + return llvm::any_cast(parser); + } +}; + +} // namespace lldb_private + +#endif diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/STLUtils.h b/contrib/llvm/tools/lldb/include/lldb/Core/STLUtils.h index 55f1ac05c975..0ed354fa4e32 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/STLUtils.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/STLUtils.h @@ -10,16 +10,12 @@ #ifndef liblldb_STLUtils_h_ #define liblldb_STLUtils_h_ -// C Includes #include -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes //---------------------------------------------------------------------- // C string less than compare function object diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/SearchFilter.h b/contrib/llvm/tools/lldb/include/lldb/Core/SearchFilter.h index 2e641983dc73..f53ef658fd3f 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/SearchFilter.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/SearchFilter.h @@ -13,10 +13,10 @@ #include "lldb/Core/FileSpecList.h" #include "lldb/Utility/StructuredData.h" -#include "lldb/Utility/FileSpec.h" // for FileSpec -#include "lldb/lldb-forward.h" // for SearchFilterSP, TargetSP, Modu... +#include "lldb/Utility/FileSpec.h" +#include "lldb/lldb-forward.h" -#include // for uint32_t +#include namespace lldb_private { class Address; @@ -70,15 +70,6 @@ public: eCallbackReturnPop // Pop one level up and continue iterating } CallbackReturn; - typedef enum { - eDepthTarget, - eDepthModule, - eDepthCompUnit, - eDepthFunction, - eDepthBlock, - eDepthAddress - } Depth; - Searcher(); virtual ~Searcher(); @@ -87,7 +78,7 @@ public: SymbolContext &context, Address *addr, bool complete) = 0; - virtual Depth GetDepth() = 0; + virtual lldb::SearchDepth GetDepth() = 0; //------------------------------------------------------------------ /// Prints a canonical description for the searcher to the stream \a s. @@ -192,6 +183,18 @@ public: //------------------------------------------------------------------ virtual bool CompUnitPasses(CompileUnit &compUnit); + //------------------------------------------------------------------ + /// Call this method with a Function to see if \a function passes the + /// filter. + /// + /// @param[in] function + /// The Functions to check against the filter. + /// + /// @return + /// \b true if \a function passes, and \b false otherwise. + //------------------------------------------------------------------ + virtual bool FunctionPasses(Function &function); + //------------------------------------------------------------------ /// Call this method to do the search using the Searcher. /// diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Section.h b/contrib/llvm/tools/lldb/include/lldb/Core/Section.h index 8e275ce3199e..4157bb877b4c 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Section.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Section.h @@ -14,16 +14,16 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Flags.h" #include "lldb/Utility/UserID.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for SectionType -#include "lldb/lldb-forward.h" // for SectionSP, ModuleSP, SectionWP -#include "lldb/lldb-types.h" // for addr_t, offset_t, user_id_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" -#include // for enable_shared_from_this -#include // for vector +#include +#include -#include // for size_t -#include // for uint32_t, UINT32_MAX +#include +#include namespace lldb_private { class Address; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/SourceManager.h b/contrib/llvm/tools/lldb/include/lldb/Core/SourceManager.h index ef652531244d..d31ba037c5d6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/SourceManager.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/SourceManager.h @@ -11,16 +11,16 @@ #define liblldb_SourceManager_h_ #include "lldb/Utility/FileSpec.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-forward.h" // for DebuggerSP, DebuggerWP, DataBufferSP +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" #include "llvm/Support/Chrono.h" -#include // for uint32_t, UINT32_MAX +#include #include #include -#include // for size_t -#include // for string +#include +#include #include namespace lldb_private { @@ -52,7 +52,7 @@ public: void UpdateIfNeeded(); - size_t DisplaySourceLines(uint32_t line, uint32_t column, + size_t DisplaySourceLines(uint32_t line, llvm::Optional column, uint32_t context_before, uint32_t context_after, Stream *s); void FindLinesMatchingRegex(RegularExpression ®ex, uint32_t start_line, diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/StreamAsynchronousIO.h b/contrib/llvm/tools/lldb/include/lldb/Core/StreamAsynchronousIO.h index 29b109757da7..89667be05878 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/StreamAsynchronousIO.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/StreamAsynchronousIO.h @@ -14,7 +14,7 @@ #include -#include // for size_t +#include namespace lldb_private { class Debugger; @@ -30,7 +30,8 @@ public: void Flush() override; - size_t Write(const void *src, size_t src_len) override; +protected: + size_t WriteImpl(const void *src, size_t src_len) override; private: Debugger &m_debugger; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/StreamBuffer.h b/contrib/llvm/tools/lldb/include/lldb/Core/StreamBuffer.h index 307dc7e18a5e..7b2468330ad2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/StreamBuffer.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/StreamBuffer.h @@ -30,12 +30,6 @@ public: // Nothing to do when flushing a buffer based stream... } - virtual size_t Write(const void *s, size_t length) { - if (s && length) - m_packet.append((const char *)s, ((const char *)s) + length); - return length; - } - void Clear() { m_packet.clear(); } // Beware, this might not be NULL terminated as you can expect from @@ -48,6 +42,12 @@ public: protected: llvm::SmallVector m_packet; + + virtual size_t WriteImpl(const void *s, size_t length) { + if (s && length) + m_packet.append((const char *)s, ((const char *)s) + length); + return length; + } }; } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/StreamFile.h b/contrib/llvm/tools/lldb/include/lldb/Core/StreamFile.h index a26ae84c7be5..86db3e4ae487 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/StreamFile.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/StreamFile.h @@ -12,11 +12,11 @@ #include "lldb/Host/File.h" #include "lldb/Utility/Stream.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for FilePermissions::eFilePermission... +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" -#include // for uint32_t -#include // for size_t, FILE +#include +#include namespace lldb_private { @@ -46,13 +46,13 @@ public: void Flush() override; - size_t Write(const void *s, size_t length) override; protected: //------------------------------------------------------------------ // Classes that inherit from StreamFile can see and modify these //------------------------------------------------------------------ File m_file; + size_t WriteImpl(const void *s, size_t length) override; private: DISALLOW_COPY_AND_ASSIGN(StreamFile); diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/StructuredDataImpl.h b/contrib/llvm/tools/lldb/include/lldb/Core/StructuredDataImpl.h index 819d1d9e5d2f..2912f4ec7de0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/StructuredDataImpl.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/StructuredDataImpl.h @@ -10,8 +10,8 @@ #ifndef liblldb_StructuredDataImpl_h_ #define liblldb_StructuredDataImpl_h_ -#include "lldb/Core/Event.h" #include "lldb/Target/StructuredDataPlugin.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StructuredData.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeDenseMap.h b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeDenseMap.h index 9b52e0355314..2fc428c4f7d4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeDenseMap.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeDenseMap.h @@ -11,14 +11,10 @@ #ifndef liblldb_ThreadSafeDenseMap_h_ #define liblldb_ThreadSafeDenseMap_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/DenseMap.h" -// Project includes namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeDenseSet.h b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeDenseSet.h index 44ec2464385f..74a010544705 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeDenseSet.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeDenseSet.h @@ -11,14 +11,10 @@ #ifndef liblldb_ThreadSafeDenseSet_h_ #define liblldb_ThreadSafeDenseSet_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/DenseSet.h" -// Project includes namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeSTLMap.h b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeSTLMap.h index 5520920c4559..4058fdfe15a8 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeSTLMap.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeSTLMap.h @@ -10,13 +10,9 @@ #ifndef liblldb_ThreadSafeSTLMap_h_ #define liblldb_ThreadSafeSTLMap_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeSTLVector.h b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeSTLVector.h index 466f4309c2d5..b65936f81fec 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeSTLVector.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeSTLVector.h @@ -11,13 +11,9 @@ #ifndef liblldb_ThreadSafeSTLVector_h_ #define liblldb_ThreadSafeSTLVector_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeValue.h b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeValue.h index 10ef8fa41d0c..35424a1791e6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeValue.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ThreadSafeValue.h @@ -10,13 +10,9 @@ #ifndef liblldb_ThreadSafeValue_h_ #define liblldb_ThreadSafeValue_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/UniqueCStringMap.h b/contrib/llvm/tools/lldb/include/lldb/Core/UniqueCStringMap.h index fe3e831a6045..cfb84b4c2160 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/UniqueCStringMap.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/UniqueCStringMap.h @@ -10,13 +10,9 @@ #ifndef liblldb_UniqueCStringMap_h_ #define liblldb_UniqueCStringMap_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/ConstString.h" #include "lldb/Utility/RegularExpression.h" @@ -221,7 +217,7 @@ public: // } // my_map.Sort(); //------------------------------------------------------------------ - void Sort() { std::sort(m_map.begin(), m_map.end()); } + void Sort() { llvm::sort(m_map.begin(), m_map.end()); } //------------------------------------------------------------------ // Since we are using a vector to contain our items it will always double its diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/UserSettingsController.h b/contrib/llvm/tools/lldb/include/lldb/Core/UserSettingsController.h index aefd42e751ab..350b5babb47b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/UserSettingsController.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/UserSettingsController.h @@ -10,16 +10,16 @@ #ifndef liblldb_UserSettingsController_h_ #define liblldb_UserSettingsController_h_ -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-forward.h" // for OptionValuePropertiesSP -#include "lldb/lldb-private-enumerations.h" // for VarSetOperationType +#include "lldb/Utility/Status.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" #include -#include // for size_t -#include // for uint32_t +#include +#include namespace lldb_private { class CommandInterpreter; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Value.h b/contrib/llvm/tools/lldb/include/lldb/Core/Value.h index 801e818c6f5c..249adb24fbc9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Value.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/Value.h @@ -10,20 +10,20 @@ #ifndef liblldb_Value_h_ #define liblldb_Value_h_ -#include "lldb/Core/Scalar.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" -#include "lldb/lldb-enumerations.h" // for ByteOrder, ByteOrder::eB... -#include "lldb/lldb-private-enumerations.h" // for AddressType -#include "lldb/lldb-private-types.h" // for type128, RegisterInfo +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-private-types.h" -#include "llvm/ADT/APInt.h" // for APInt +#include "llvm/ADT/APInt.h" #include -#include // for uint8_t, uint32_t, uint64_t -#include // for size_t, memcpy +#include +#include namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObject.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObject.h index fddc06413196..cb6de7b41807 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObject.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObject.h @@ -12,7 +12,7 @@ #include "lldb/Core/Value.h" #include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/Type.h" // for TypeImpl +#include "lldb/Symbol/Type.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Utility/ConstString.h" @@ -20,26 +20,26 @@ #include "lldb/Utility/SharedCluster.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/UserID.h" -#include "lldb/lldb-defines.h" // for LLDB_INVALID... -#include "lldb/lldb-enumerations.h" // for DynamicValue... -#include "lldb/lldb-forward.h" // for ValueObjectSP -#include "lldb/lldb-private-enumerations.h" // for AddressType -#include "lldb/lldb-types.h" // for addr_t, offs... +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" #include #include #include -#include // for recursive_mutex -#include // for string -#include // for pair +#include +#include +#include -#include // for size_t -#include // for uint32_t +#include +#include namespace lldb_private { class Declaration; } @@ -635,9 +635,6 @@ public: virtual void SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS, AddressType address_type = eAddressTypeLoad) {} - // Find the address of the C++ vtable pointer - virtual lldb::addr_t GetCPPVTableAddress(AddressType &address_type); - virtual lldb::ValueObjectSP Cast(const CompilerType &compiler_type); virtual lldb::ValueObjectSP CastPointerType(const char *name, diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectCast.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectCast.h index aaa1ecb67db8..34814d9b17bb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectCast.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectCast.h @@ -11,13 +11,13 @@ #define liblldb_ValueObjectCast_h_ #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ValueType -#include "lldb/lldb-forward.h" // for ValueObjectSP +#include "lldb/Symbol/CompilerType.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" -#include // for size_t -#include // for uint32_t, uint64_t +#include +#include namespace lldb_private { class ConstString; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectChild.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectChild.h index ec8c9e805cdf..6800775dc8f9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectChild.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectChild.h @@ -12,17 +12,17 @@ #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ValueType -#include "lldb/lldb-private-enumerations.h" // for LazyBool, AddressType -#include "lldb/lldb-types.h" // for offset_t +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" #include "llvm/ADT/Optional.h" -#include // for size_t -#include // for uint32_t, uint64_t, int32_t +#include +#include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResult.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResult.h index 1f56129df24a..c1c56d8dcb22 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResult.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResult.h @@ -10,20 +10,20 @@ #ifndef liblldb_ValueObjectConstResult_h_ #define liblldb_ValueObjectConstResult_h_ -#include "lldb/Core/Value.h" // for Value +#include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResultImpl.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-enumerations.h" // for ByteOrder, Dynamic... -#include "lldb/lldb-forward.h" // for ValueObjectSP, Dat... -#include "lldb/lldb-private-enumerations.h" // for AddressType, Addre... -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" -#include // for size_t -#include // for uint32_t, uint64_t +#include +#include namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultCast.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultCast.h index 442cce420855..bb2b4e6f092f 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultCast.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultCast.h @@ -12,14 +12,14 @@ #include "lldb/Core/ValueObjectCast.h" #include "lldb/Core/ValueObjectConstResultImpl.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_... -#include "lldb/lldb-forward.h" // for ValueObjectSP -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" -#include // for size_t -#include // for uint32_t, int32_t +#include +#include namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultChild.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultChild.h index a74da0013aba..f14fb75640e6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultChild.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultChild.h @@ -12,14 +12,14 @@ #include "lldb/Core/ValueObjectChild.h" #include "lldb/Core/ValueObjectConstResultImpl.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_... -#include "lldb/lldb-forward.h" // for ValueObjectSP -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" -#include // for size_t -#include // for uint32_t, int32_t +#include +#include namespace lldb_private { class DataExtractor; } @@ -63,6 +63,9 @@ public: lldb::ValueObjectSP AddressOf(Status &error) override; + lldb::addr_t GetAddressOf(bool scalar_is_load_address = true, + AddressType *address_type = nullptr) override; + size_t GetPointeeData(DataExtractor &data, uint32_t item_idx = 0, uint32_t item_count = 1) override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultImpl.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultImpl.h index d86f25e30579..5ea47bb3b3fa 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultImpl.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectConstResultImpl.h @@ -10,14 +10,14 @@ #ifndef liblldb_ValueObjectConstResultImpl_h_ #define liblldb_ValueObjectConstResultImpl_h_ -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-forward.h" // for ValueObjectSP -#include "lldb/lldb-private-enumerations.h" // for AddressType, AddressType... -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" -#include // for size_t -#include // for uint32_t, int32_t +#include +#include namespace lldb_private { class CompilerType; } diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectDynamicValue.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectDynamicValue.h index 018ee2c764bf..0c9ec8cce06e 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectDynamicValue.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectDynamicValue.h @@ -10,20 +10,20 @@ #ifndef liblldb_ValueObjectDynamicValue_h_ #define liblldb_ValueObjectDynamicValue_h_ -#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Address.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Type.h" -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/Utility/SharingPtr.h" // for operator== -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for DynamicValueType, Langua... -#include "lldb/lldb-forward.h" // for ValueObjectSP, VariableSP -#include "lldb/lldb-private-enumerations.h" // for LazyBool, LazyBool::eLaz... +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/SharingPtr.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" -#include // for assert -#include // for size_t -#include // for uint64_t, uint32_t +#include +#include +#include namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectList.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectList.h index a0d2e681dedb..d17510f7f581 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectList.h @@ -10,12 +10,12 @@ #ifndef liblldb_ValueObjectList_h_ #define liblldb_ValueObjectList_h_ -#include "lldb/lldb-forward.h" // for ValueObjectSP -#include "lldb/lldb-types.h" // for user_id_t +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" #include -#include // for size_t +#include namespace lldb_private { class ValueObject; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectMemory.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectMemory.h index 8bb649cc3c52..c4b946af98ce 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectMemory.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectMemory.h @@ -10,17 +10,17 @@ #ifndef liblldb_ValueObjectMemory_h_ #define liblldb_ValueObjectMemory_h_ -#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Address.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ValueType -#include "lldb/lldb-forward.h" // for TypeSP, ValueObjectSP, ModuleSP -#include "llvm/ADT/StringRef.h" // for StringRef +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringRef.h" -#include // for size_t -#include // for uint32_t, uint64_t +#include +#include namespace lldb_private { class ExecutionContextScope; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectRegister.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectRegister.h index 2aaef9bee99e..fb10c259e7d0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectRegister.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectRegister.h @@ -10,17 +10,17 @@ #ifndef liblldb_ValueObjectRegister_h_ #define liblldb_ValueObjectRegister_h_ -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ValueType, ValueType::eValueTy... -#include "lldb/lldb-forward.h" // for RegisterContextSP, ValueObjectSP -#include "lldb/lldb-private-types.h" // for RegisterInfo, RegisterSet (ptr... +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-types.h" -#include // for size_t -#include // for uint32_t, uint64_t, int32_t +#include +#include namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h index b3af6c0ae827..9495d4ca5e25 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -13,17 +13,17 @@ #include "lldb/Core/ThreadSafeSTLMap.h" #include "lldb/Core/ThreadSafeSTLVector.h" #include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for ThreadSafeSTLMap::operator= -#include "lldb/lldb-enumerations.h" // for DynamicValueType, Langua... -#include "lldb/lldb-forward.h" // for ValueObjectSP, Synthetic... -#include "lldb/lldb-private-enumerations.h" // for LazyBool, LazyBool::eLaz... +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" -#include // for uint32_t, uint64_t +#include #include -#include // for size_t +#include namespace lldb_private { class Declaration; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectVariable.h b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectVariable.h index 9dd140a84f45..81a8eabdacbb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectVariable.h +++ b/contrib/llvm/tools/lldb/include/lldb/Core/ValueObjectVariable.h @@ -12,15 +12,15 @@ #include "lldb/Core/ValueObject.h" -#include "lldb/Core/Value.h" // for Value -#include "lldb/Symbol/CompilerType.h" // for CompilerType -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ValueType -#include "lldb/lldb-forward.h" // for VariableSP, ModuleSP, ValueObj... +#include "lldb/Core/Value.h" +#include "lldb/Symbol/CompilerType.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" -#include // for size_t -#include // for uint32_t, uint64_t +#include +#include namespace lldb_private { class DataExtractor; diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/DataVisualization.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/DataVisualization.h index 369fa686a9ff..9ca2e95cd9cb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/DataVisualization.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/DataVisualization.h @@ -10,11 +10,7 @@ #ifndef lldb_DataVisualization_h_ #define lldb_DataVisualization_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/FormatClasses.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Utility/ConstString.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h index 00baea77f793..113c48afa6f8 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/DumpValueObjectOptions.h @@ -10,12 +10,8 @@ #ifndef lldb_DumpValueObjectOptions_h_ #define lldb_DumpValueObjectOptions_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatCache.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatCache.h index 9901ec91ebd2..2c09b65a420a 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatCache.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatCache.h @@ -11,13 +11,9 @@ #ifndef lldb_FormatCache_h_ #define lldb_FormatCache_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/ConstString.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatClasses.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatClasses.h index 458477578d3f..1f08485d0292 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatClasses.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatClasses.h @@ -10,15 +10,11 @@ #ifndef lldb_FormatClasses_h_ #define lldb_FormatClasses_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/TypeFormat.h" #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/DataFormatters/TypeSynthetic.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatManager.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatManager.h index e973c8b3e849..9046ccf2e0bb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatManager.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormatManager.h @@ -10,16 +10,12 @@ #ifndef lldb_FormatManager_h_ #define lldb_FormatManager_h_ -// C Includes -// C++ Includes #include #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersContainer.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersContainer.h index df88e88011fe..dd8995d81132 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersContainer.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersContainer.h @@ -10,16 +10,12 @@ #ifndef lldb_FormattersContainer_h_ #define lldb_FormattersContainer_h_ -// C Includes -// C++ Includes #include #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-public.h" #include "lldb/Core/ValueObject.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersHelpers.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersHelpers.h index 14ba5e48feb4..028d5cc27688 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersHelpers.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/FormattersHelpers.h @@ -11,10 +11,6 @@ #ifndef lldb_FormattersHelpers_h_ #define lldb_FormattersHelpers_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/LanguageCategory.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/LanguageCategory.h index e94429407837..f2ac628636d4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/LanguageCategory.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/LanguageCategory.h @@ -11,11 +11,7 @@ #ifndef lldb_LanguageCategory_h_ #define lldb_LanguageCategory_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/FormatCache.h" #include "lldb/DataFormatters/FormatClasses.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/StringPrinter.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/StringPrinter.h index 18207921bb71..38033f915bf9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/StringPrinter.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/StringPrinter.h @@ -10,13 +10,9 @@ #ifndef liblldb_StringPrinter_h_ #define liblldb_StringPrinter_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-forward.h" #include "lldb/Utility/DataExtractor.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeCategory.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeCategory.h index 0a5b09baa624..177e602e6ec3 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeCategory.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeCategory.h @@ -10,16 +10,12 @@ #ifndef lldb_TypeCategory_h_ #define lldb_TypeCategory_h_ -// C Includes -// C++ Includes #include #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" @@ -348,7 +344,7 @@ public: bool IsEnabled() const { return m_enabled; } uint32_t GetEnabledPosition() { - if (m_enabled == false) + if (!m_enabled) return UINT32_MAX; else return m_enabled_position; diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeCategoryMap.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeCategoryMap.h index f767c985ff34..0ff078edf51b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeCategoryMap.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeCategoryMap.h @@ -10,15 +10,11 @@ #ifndef lldb_TypeCategoryMap_h_ #define lldb_TypeCategoryMap_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeFormat.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeFormat.h index 77e3542f5522..57ef0cf942cb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeFormat.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeFormat.h @@ -11,16 +11,12 @@ #ifndef lldb_TypeFormat_h_ #define lldb_TypeFormat_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeSummary.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeSummary.h index 17cd61ae8c1e..78947728be29 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeSummary.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeSummary.h @@ -10,16 +10,12 @@ #ifndef lldb_TypeSummary_h_ #define lldb_TypeSummary_h_ -// C Includes #include -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeSynthetic.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeSynthetic.h index 07dacd670a62..a9025fdb5397 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeSynthetic.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeSynthetic.h @@ -10,18 +10,14 @@ #ifndef lldb_TypeSynthetic_h_ #define lldb_TypeSynthetic_h_ -// C Includes #include -// C++ Includes #include #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeValidator.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeValidator.h index fa2a89148118..a50949cf22fe 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeValidator.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/TypeValidator.h @@ -11,15 +11,11 @@ #ifndef lldb_TypeValidator_h_ #define lldb_TypeValidator_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h index 67048a4932cf..13124c9210c8 100644 --- a/contrib/llvm/tools/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/contrib/llvm/tools/lldb/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -11,11 +11,7 @@ #ifndef lldb_ValueObjectPrinter_h_ #define lldb_ValueObjectPrinter_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" #include "lldb/lldb-public.h" @@ -24,10 +20,6 @@ #include "lldb/DataFormatters/DumpValueObjectOptions.h" #include "lldb/Symbol/CompilerType.h" -//#include -//#include -//#include - namespace lldb_private { class ValueObjectPrinter { diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/DWARFExpression.h b/contrib/llvm/tools/lldb/include/lldb/Expression/DWARFExpression.h index b4bd9697da58..cdede56d86d9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/DWARFExpression.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/DWARFExpression.h @@ -12,8 +12,8 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Disassembler.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" #include @@ -40,7 +40,10 @@ public: enum LocationListFormat : uint8_t { NonLocationList, // Not a location list RegularLocationList, // Location list format used in non-split dwarf files - SplitDwarfLocationList, // Location list format used in split dwarf files + SplitDwarfLocationList, // Location list format used in pre-DWARF v5 split + // dwarf files (.debug_loc.dwo) + LocLists, // Location list format used in DWARF v5 + // (.debug_loclists/.debug_loclists.dwo). }; //------------------------------------------------------------------ @@ -153,6 +156,8 @@ public: bool Update_DW_OP_addr(lldb::addr_t file_addr); + void SetModule(const lldb::ModuleSP &module) { m_module_wp = module; } + bool ContainsThreadLocalStorage() const; bool LinkThreadLocalStorage( diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/Expression.h b/contrib/llvm/tools/lldb/include/lldb/Expression/Expression.h index 6b9363864722..162dcd3e4672 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/Expression.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/Expression.h @@ -10,14 +10,10 @@ #ifndef liblldb_Expression_h_ #define liblldb_Expression_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Expression/ExpressionTypeSystemHelper.h" #include "lldb/lldb-forward.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/ExpressionParser.h b/contrib/llvm/tools/lldb/include/lldb/Expression/ExpressionParser.h index 66957926650a..7d337bd00ca6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/ExpressionParser.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/ExpressionParser.h @@ -10,6 +10,7 @@ #ifndef liblldb_ExpressionParser_h_ #define liblldb_ExpressionParser_h_ +#include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-public.h" @@ -49,6 +50,41 @@ public: //------------------------------------------------------------------ virtual ~ExpressionParser(){}; + //------------------------------------------------------------------ + /// Attempts to find possible command line completions for the given + /// expression. + /// + /// @param[out] request + /// The completion request to fill out. The completion should be a string + /// that would complete the current token at the cursor position. + /// Note that the string in the list replaces the current token + /// in the command line. + /// + /// @param[in] line + /// The line with the completion cursor inside the expression as a string. + /// The first line in the expression has the number 0. + /// + /// @param[in] pos + /// The character position in the line with the completion cursor. + /// If the value is 0, then the cursor is on top of the first character + /// in the line (i.e. the user has requested completion from the start of + /// the expression). + /// + /// @param[in] typed_pos + /// The cursor position in the line as typed by the user. If the user + /// expression has not been transformed in some form (e.g. wrapping it + /// in a function body for C languages), then this is equal to the + /// 'pos' parameter. The semantics of this value are otherwise equal to + /// 'pos' (e.g. a value of 0 means the cursor is at start of the + /// expression). + /// + /// @return + /// True if we added any completion results to the output; + /// false otherwise. + //------------------------------------------------------------------ + virtual bool Complete(CompletionRequest &request, unsigned line, unsigned pos, + unsigned typed_pos) = 0; + //------------------------------------------------------------------ /// Parse a single expression and convert it to IR using Clang. Don't wrap /// the expression in anything at all. diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/ExpressionVariable.h b/contrib/llvm/tools/lldb/include/lldb/Expression/ExpressionVariable.h index 89b0500faf9c..01e9c416e7c0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/ExpressionVariable.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/ExpressionVariable.h @@ -10,15 +10,11 @@ #ifndef liblldb_ExpressionVariable_h_ #define liblldb_ExpressionVariable_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "llvm/ADT/DenseMap.h" -// Project includes #include "lldb/Core/ValueObject.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/FunctionCaller.h b/contrib/llvm/tools/lldb/include/lldb/Expression/FunctionCaller.h index c36263e34240..0ec7e202dac9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/FunctionCaller.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/FunctionCaller.h @@ -10,15 +10,11 @@ #ifndef liblldb_FunctionCaller_h_ #define liblldb_FunctionCaller_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/Address.h" #include "lldb/Core/Value.h" #include "lldb/Expression/Expression.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/IRExecutionUnit.h b/contrib/llvm/tools/lldb/include/lldb/Expression/IRExecutionUnit.h index e73f8956d955..b966d135deab 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/IRExecutionUnit.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/IRExecutionUnit.h @@ -10,18 +10,14 @@ #ifndef liblldb_IRExecutionUnit_h_ #define liblldb_IRExecutionUnit_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/Module.h" -// Project includes #include "lldb/Expression/IRMemoryMap.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" @@ -112,7 +108,7 @@ public: void PopulateSectionList(lldb_private::ObjectFile *obj_file, lldb_private::SectionList §ion_list) override; - bool GetArchitecture(lldb_private::ArchSpec &arch) override; + ArchSpec GetArchitecture() override; lldb::ModuleSP GetJITModule(); diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/IRMemoryMap.h b/contrib/llvm/tools/lldb/include/lldb/Expression/IRMemoryMap.h index df8a03f4763f..026ca6b98110 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/IRMemoryMap.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/IRMemoryMap.h @@ -39,7 +39,7 @@ public: IRMemoryMap(lldb::TargetSP target_sp); ~IRMemoryMap(); - enum AllocationPolicy { + enum AllocationPolicy : uint8_t { eAllocationPolicyInvalid = 0, ///< It is an error for an allocation to have this policy. eAllocationPolicyHostOnly, ///< This allocation was created in the host and @@ -91,32 +91,32 @@ protected: private: struct Allocation { lldb::addr_t - m_process_alloc; ///< The (unaligned) base for the remote allocation + m_process_alloc; ///< The (unaligned) base for the remote allocation. lldb::addr_t - m_process_start; ///< The base address of the allocation in the process - size_t m_size; ///< The size of the requested allocation - uint32_t m_permissions; ///< The access permissions on the memory in the - ///process. In the host, the memory is always - ///read/write. - uint8_t m_alignment; ///< The alignment of the requested allocation + m_process_start; ///< The base address of the allocation in the process. + size_t m_size; ///< The size of the requested allocation. DataBufferHeap m_data; - ///< Flags + /// Flags. Keep these grouped together to avoid structure padding. AllocationPolicy m_policy; bool m_leak; + uint8_t m_permissions; ///< The access permissions on the memory in the + /// process. In the host, the memory is always + /// read/write. + uint8_t m_alignment; ///< The alignment of the requested allocation. public: Allocation(lldb::addr_t process_alloc, lldb::addr_t process_start, size_t size, uint32_t permissions, uint8_t alignment, AllocationPolicy m_policy); - Allocation() - : m_process_alloc(LLDB_INVALID_ADDRESS), - m_process_start(LLDB_INVALID_ADDRESS), m_size(0), m_permissions(0), - m_alignment(0), m_data(), m_policy(eAllocationPolicyInvalid), - m_leak(false) {} + DISALLOW_COPY_AND_ASSIGN(Allocation); }; + static_assert(sizeof(Allocation) <= + (4 * sizeof(lldb::addr_t)) + sizeof(DataBufferHeap), + "IRMemoryMap::Allocation is larger than expected"); + lldb::ProcessWP m_process_wp; lldb::TargetWP m_target_wp; typedef std::map AllocationMap; diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/LLVMUserExpression.h b/contrib/llvm/tools/lldb/include/lldb/Expression/LLVMUserExpression.h index a2f87e8a6e25..1ba822265fca 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/LLVMUserExpression.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/LLVMUserExpression.h @@ -10,16 +10,12 @@ #ifndef liblldb_LLVMUserExpression_h #define liblldb_LLVMUserExpression_h -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes #include "llvm/IR/LegacyPassManager.h" -// Project includes #include "lldb/Expression/UserExpression.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/Materializer.h b/contrib/llvm/tools/lldb/include/lldb/Expression/Materializer.h index b86bc656d6b5..0bdfd372e921 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/Materializer.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/Materializer.h @@ -10,13 +10,9 @@ #ifndef liblldb_Materializer_h #define liblldb_Materializer_h -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Expression/IRMemoryMap.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/StackFrame.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/REPL.h b/contrib/llvm/tools/lldb/include/lldb/Expression/REPL.h index 0c1e97fec259..f7780772cbea 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/REPL.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/REPL.h @@ -10,12 +10,8 @@ #ifndef lldb_REPL_h #define lldb_REPL_h -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/../../source/Commands/CommandObjectExpression.h" #include "lldb/Interpreter/OptionGroupFormat.h" #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" @@ -117,7 +113,7 @@ public: int IOHandlerComplete(IOHandler &io_handler, const char *current_line, const char *cursor, const char *last_char, int skip_first_n_matches, int max_matches, - StringList &matches) override; + StringList &matches, StringList &descriptions) override; protected: static int CalculateActualIndentation(const StringList &lines); diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/UserExpression.h b/contrib/llvm/tools/lldb/include/lldb/Expression/UserExpression.h index 96ca80c882e5..812d7e9a0eac 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/UserExpression.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/UserExpression.h @@ -10,14 +10,10 @@ #ifndef liblldb_UserExpression_h_ #define liblldb_UserExpression_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/Address.h" #include "lldb/Expression/Expression.h" #include "lldb/Expression/Materializer.h" @@ -98,6 +94,34 @@ public: lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info) = 0; + //------------------------------------------------------------------ + /// Attempts to find possible command line completions for the given + /// (possible incomplete) user expression. + /// + /// @param[in] exe_ctx + /// The execution context to use when looking up entities that + /// are needed for parsing and completing (locations of functions, types + /// of variables, persistent variables, etc.) + /// + /// @param[out] request + /// The completion request to fill out. The completion should be a string + /// that would complete the current token at the cursor position. + /// Note that the string in the list replaces the current token + /// in the command line. + /// + /// @param[in] complete_pos + /// The position of the cursor inside the user expression string. + /// The completion process starts on the token that the cursor is in. + /// + /// @return + /// True if we added any completion results to the output; + /// false otherwise. + //------------------------------------------------------------------ + virtual bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request, + unsigned complete_pos) { + return false; + } + virtual bool CanInterpret() = 0; bool MatchesContext(ExecutionContext &exe_ctx); diff --git a/contrib/llvm/tools/lldb/include/lldb/Expression/UtilityFunction.h b/contrib/llvm/tools/lldb/include/lldb/Expression/UtilityFunction.h index 5d4bc8676b95..4c87f4d10479 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Expression/UtilityFunction.h +++ b/contrib/llvm/tools/lldb/include/lldb/Expression/UtilityFunction.h @@ -11,13 +11,9 @@ #ifndef liblldb_UtilityFunction_h_ #define liblldb_UtilityFunction_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Expression/Expression.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/Debug.h b/contrib/llvm/tools/lldb/include/lldb/Host/Debug.h index ed8e633c113f..d88725cf4e2e 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/Debug.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/Debug.h @@ -10,12 +10,8 @@ #ifndef liblldb_Debug_h_ #define liblldb_Debug_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/Editline.h b/contrib/llvm/tools/lldb/include/lldb/Host/Editline.h index beb96e7c4924..51d6e58c1e7a 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/Editline.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/Editline.h @@ -54,8 +54,8 @@ #include #include "lldb/Host/ConnectionFileDescriptor.h" -#include "lldb/Host/Predicate.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Predicate.h" namespace lldb_private { namespace line_editor { @@ -101,7 +101,8 @@ typedef int (*FixIndentationCallbackType)(Editline *editline, typedef int (*CompleteCallbackType)(const char *current_line, const char *cursor, const char *last_char, int skip_first_n_matches, int max_matches, - StringList &matches, void *baton); + StringList &matches, + StringList &descriptions, void *baton); /// Status used to decide when and how to start editing another line in /// multi-line sessions diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/File.h b/contrib/llvm/tools/lldb/include/lldb/Host/File.h index d240f810bc8b..69ae2004e422 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/File.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/File.h @@ -33,6 +33,8 @@ public: static int kInvalidDescriptor; static FILE *kInvalidStream; + // NB this enum is used in the lldb platform gdb-remote packet + // vFile:open: and existing values cannot be modified. enum OpenOptions { eOpenOptionRead = (1u << 0), // Open file for reading eOpenOptionWrite = (1u << 1), // Open file for writing @@ -54,57 +56,15 @@ public: : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor), m_stream(kInvalidStream), m_options(0), m_own_stream(false), m_is_interactive(eLazyBoolCalculate), - m_is_real_terminal(eLazyBoolCalculate) {} + m_is_real_terminal(eLazyBoolCalculate), + m_supports_colors(eLazyBoolCalculate) {} File(FILE *fh, bool transfer_ownership) : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor), m_stream(fh), m_options(0), m_own_stream(transfer_ownership), m_is_interactive(eLazyBoolCalculate), - m_is_real_terminal(eLazyBoolCalculate) {} - - //------------------------------------------------------------------ - /// Constructor with path. - /// - /// Takes a path to a file which can be just a filename, or a full path. If - /// \a path is not nullptr or empty, this function will call File::Open - /// (const char *path, uint32_t options, uint32_t permissions). - /// - /// @param[in] path - /// The full or partial path to a file. - /// - /// @param[in] options - /// Options to use when opening (see File::OpenOptions) - /// - /// @param[in] permissions - /// Options to use when opening (see File::Permissions) - /// - /// @see File::Open (const char *path, uint32_t options, uint32_t - /// permissions) - //------------------------------------------------------------------ - File(const char *path, uint32_t options, - uint32_t permissions = lldb::eFilePermissionsFileDefault); - - //------------------------------------------------------------------ - /// Constructor with FileSpec. - /// - /// Takes a FileSpec pointing to a file which can be just a filename, or a - /// full path. If \a path is not nullptr or empty, this function will call - /// File::Open (const char *path, uint32_t options, uint32_t permissions). - /// - /// @param[in] filespec - /// The FileSpec for this file. - /// - /// @param[in] options - /// Options to use when opening (see File::OpenOptions) - /// - /// @param[in] permissions - /// Options to use when opening (see File::Permissions) - /// - /// @see File::Open (const char *path, uint32_t options, uint32_t - /// permissions) - //------------------------------------------------------------------ - File(const FileSpec &filespec, uint32_t options, - uint32_t permissions = lldb::eFilePermissionsFileDefault); + m_is_real_terminal(eLazyBoolCalculate), + m_supports_colors(eLazyBoolCalculate) {} File(int fd, bool transfer_ownership) : IOObject(eFDTypeFile, transfer_ownership), m_descriptor(fd), @@ -167,23 +127,6 @@ public: //------------------------------------------------------------------ Status GetFileSpec(FileSpec &file_spec) const; - //------------------------------------------------------------------ - /// Open a file for read/writing with the specified options. - /// - /// Takes a path to a file which can be just a filename, or a full path. - /// - /// @param[in] path - /// The full or partial path to a file. - /// - /// @param[in] options - /// Options to use when opening (see File::OpenOptions) - /// - /// @param[in] permissions - /// Options to use when opening (see File::Permissions) - //------------------------------------------------------------------ - Status Open(const char *path, uint32_t options, - uint32_t permissions = lldb::eFilePermissionsFileDefault); - Status Close() override; void Clear(); @@ -417,8 +360,6 @@ public: //------------------------------------------------------------------ uint32_t GetPermissions(Status &error) const; - static uint32_t GetPermissions(const FileSpec &file_spec, Status &error); - //------------------------------------------------------------------ /// Return true if this file is interactive. /// @@ -461,8 +402,10 @@ public: void SetOptions(uint32_t options) { m_options = options; } + static bool DescriptorIsValid(int descriptor) { return descriptor >= 0; }; + protected: - bool DescriptorIsValid() const { return m_descriptor >= 0; } + bool DescriptorIsValid() const { return DescriptorIsValid(m_descriptor); } bool StreamIsValid() const { return m_stream != kInvalidStream; } diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/FileSystem.h b/contrib/llvm/tools/lldb/include/lldb/Host/FileSystem.h index c13d5c84c631..9e36649b0046 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/FileSystem.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/FileSystem.h @@ -10,9 +10,14 @@ #ifndef liblldb_Host_FileSystem_h #define liblldb_Host_FileSystem_h +#include "lldb/Host/File.h" +#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" + +#include "llvm/ADT/Optional.h" #include "llvm/Support/Chrono.h" +#include "llvm/Support/VirtualFileSystem.h" #include "lldb/lldb-types.h" @@ -26,17 +31,147 @@ public: static const char *DEV_NULL; static const char *PATH_CONVERSION_ERROR; - static Status Symlink(const FileSpec &src, const FileSpec &dst); - static Status Readlink(const FileSpec &src, FileSpec &dst); + FileSystem() : m_fs(llvm::vfs::getRealFileSystem()) {} + FileSystem(llvm::IntrusiveRefCntPtr fs) : m_fs(fs) {} - static Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst); + FileSystem(const FileSystem &fs) = delete; + FileSystem &operator=(const FileSystem &fs) = delete; - /// Wraps ::fopen in a platform-independent way. Once opened, FILEs can be - /// manipulated and closed with the normal ::fread, ::fclose, etc. functions. - static FILE *Fopen(const char *path, const char *mode); + static FileSystem &Instance(); - static llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec); + static void Initialize(); + static void Initialize(llvm::IntrusiveRefCntPtr fs); + static void Terminate(); + + Status Symlink(const FileSpec &src, const FileSpec &dst); + Status Readlink(const FileSpec &src, FileSpec &dst); + + Status ResolveSymbolicLink(const FileSpec &src, FileSpec &dst); + + /// Wraps ::fopen in a platform-independent way. + FILE *Fopen(const char *path, const char *mode); + + /// Wraps ::open in a platform-independent way. + int Open(const char *path, int flags, int mode); + + Status Open(File &File, const FileSpec &file_spec, uint32_t options, + uint32_t permissions = lldb::eFilePermissionsFileDefault); + + /// Get a directory iterator. + /// @{ + llvm::vfs::directory_iterator DirBegin(const FileSpec &file_spec, + std::error_code &ec); + llvm::vfs::directory_iterator DirBegin(const llvm::Twine &dir, + std::error_code &ec); + /// @} + + /// Returns the Status object for the given file. + /// @{ + llvm::ErrorOr GetStatus(const FileSpec &file_spec) const; + llvm::ErrorOr GetStatus(const llvm::Twine &path) const; + /// @} + + /// Returns the modification time of the given file. + /// @{ + llvm::sys::TimePoint<> GetModificationTime(const FileSpec &file_spec) const; + llvm::sys::TimePoint<> GetModificationTime(const llvm::Twine &path) const; + /// @} + + /// Returns the on-disk size of the given file in bytes. + /// @{ + uint64_t GetByteSize(const FileSpec &file_spec) const; + uint64_t GetByteSize(const llvm::Twine &path) const; + /// @} + + /// Return the current permissions of the given file. + /// + /// Returns a bitmask for the current permissions of the file (zero or more + /// of the permission bits defined in File::Permissions). + /// @{ + uint32_t GetPermissions(const FileSpec &file_spec) const; + uint32_t GetPermissions(const llvm::Twine &path) const; + uint32_t GetPermissions(const FileSpec &file_spec, std::error_code &ec) const; + uint32_t GetPermissions(const llvm::Twine &path, std::error_code &ec) const; + /// @} + + /// Returns whether the given file exists. + /// @{ + bool Exists(const FileSpec &file_spec) const; + bool Exists(const llvm::Twine &path) const; + /// @} + + /// Returns whether the given file is readable. + /// @{ + bool Readable(const FileSpec &file_spec) const; + bool Readable(const llvm::Twine &path) const; + /// @} + + /// Returns whether the given path is a directory. + /// @{ + bool IsDirectory(const FileSpec &file_spec) const; + bool IsDirectory(const llvm::Twine &path) const; + /// @} + + /// Returns whether the given path is local to the file system. + /// @{ + bool IsLocal(const FileSpec &file_spec) const; + bool IsLocal(const llvm::Twine &path) const; + /// @} + + /// Make the given file path absolute. + /// @{ + std::error_code MakeAbsolute(llvm::SmallVectorImpl &path) const; + std::error_code MakeAbsolute(FileSpec &file_spec) const; + /// @} + + /// Resolve path to make it canonical. + /// @{ + void Resolve(llvm::SmallVectorImpl &path); + void Resolve(FileSpec &file_spec); + /// @} + + //// Create memory buffer from path. + /// @{ + std::shared_ptr CreateDataBuffer(const llvm::Twine &path, + uint64_t size = 0, + uint64_t offset = 0); + std::shared_ptr CreateDataBuffer(const FileSpec &file_spec, + uint64_t size = 0, + uint64_t offset = 0); + /// @} + + /// Call into the Host to see if it can help find the file. + bool ResolveExecutableLocation(FileSpec &file_spec); + + enum EnumerateDirectoryResult { + /// Enumerate next entry in the current directory. + eEnumerateDirectoryResultNext, + /// Recurse into the current entry if it is a directory or symlink, or next + /// if not. + eEnumerateDirectoryResultEnter, + /// Stop directory enumerations at any level. + eEnumerateDirectoryResultQuit + }; + + typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType)( + void *baton, llvm::sys::fs::file_type file_type, llvm::StringRef); + + typedef std::function + DirectoryCallback; + + void EnumerateDirectory(llvm::Twine path, bool find_directories, + bool find_files, bool find_other, + EnumerateDirectoryCallbackType callback, + void *callback_baton); + + std::error_code GetRealPath(const llvm::Twine &path, + llvm::SmallVectorImpl &output) const; + +private: + static llvm::Optional &InstanceImpl(); + llvm::IntrusiveRefCntPtr m_fs; }; -} +} // namespace lldb_private #endif diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/HostInfoBase.h b/contrib/llvm/tools/lldb/include/lldb/Host/HostInfoBase.h index b2567b296277..f3e49c8f25d7 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/HostInfoBase.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/HostInfoBase.h @@ -75,10 +75,6 @@ public: /// member of the FileSpec is filled in. static FileSpec GetHeaderDir(); - /// Returns the directory containing the python modules. Only the directory - /// member of the FileSpec is filled in. - static FileSpec GetPythonDir(); - /// Returns the directory containing the system plugins. Only the directory /// member of the FileSpec is filled in. static FileSpec GetSystemPluginDir(); diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/HostNativeThreadBase.h b/contrib/llvm/tools/lldb/include/lldb/Host/HostNativeThreadBase.h index f1f89f3b75fe..326a9c6c793f 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/HostNativeThreadBase.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/HostNativeThreadBase.h @@ -35,6 +35,7 @@ public: virtual Status Cancel() = 0; virtual bool IsJoinable() const; virtual void Reset(); + virtual bool EqualsThread(lldb::thread_t thread) const; lldb::thread_t Release(); lldb::thread_t GetSystemHandle() const; diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/MonitoringProcessLauncher.h b/contrib/llvm/tools/lldb/include/lldb/Host/MonitoringProcessLauncher.h index 341284800a4e..179823efb966 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/MonitoringProcessLauncher.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/MonitoringProcessLauncher.h @@ -10,11 +10,7 @@ #ifndef lldb_Host_MonitoringProcessLauncher_h_ #define lldb_Host_MonitoringProcessLauncher_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Host/ProcessLauncher.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/PipeBase.h b/contrib/llvm/tools/lldb/include/lldb/Host/PipeBase.h index ad62072c7ba5..88bd703960c4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/PipeBase.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/PipeBase.h @@ -41,6 +41,9 @@ public: virtual bool CanRead() const = 0; virtual bool CanWrite() const = 0; + virtual lldb::pipe_t GetReadPipe() const = 0; + virtual lldb::pipe_t GetWritePipe() const = 0; + virtual int GetReadFileDescriptor() const = 0; virtual int GetWriteFileDescriptor() const = 0; virtual int ReleaseReadFileDescriptor() = 0; diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/ProcessRunLock.h b/contrib/llvm/tools/lldb/include/lldb/Host/ProcessRunLock.h index 6f39eea716e8..272772fedce1 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/ProcessRunLock.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/ProcessRunLock.h @@ -10,13 +10,9 @@ #ifndef liblldb_ProcessRunLock_h_ #define liblldb_ProcessRunLock_h_ -// C Includes #include #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" //---------------------------------------------------------------------- diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/SafeMachO.h b/contrib/llvm/tools/lldb/include/lldb/Host/SafeMachO.h similarity index 100% rename from contrib/llvm/tools/lldb/include/lldb/Utility/SafeMachO.h rename to contrib/llvm/tools/lldb/include/lldb/Host/SafeMachO.h diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/Socket.h b/contrib/llvm/tools/lldb/include/lldb/Host/Socket.h index f6e51fd45679..8b7f9fa4ed93 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/Socket.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/Socket.h @@ -15,9 +15,9 @@ #include "lldb/lldb-private.h" -#include "lldb/Host/Predicate.h" #include "lldb/Host/SocketAddress.h" #include "lldb/Utility/IOObject.h" +#include "lldb/Utility/Predicate.h" #include "lldb/Utility/Status.h" #ifdef _WIN32 diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/SocketAddress.h b/contrib/llvm/tools/lldb/include/lldb/Host/SocketAddress.h index 749a9c664c81..5e54ef1d8e0c 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/SocketAddress.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/SocketAddress.h @@ -10,7 +10,6 @@ #ifndef liblldb_SocketAddress_h_ #define liblldb_SocketAddress_h_ -// C Includes #include #ifdef _WIN32 @@ -28,9 +27,6 @@ typedef ADDRESS_FAMILY sa_family_t; #include #endif -// C++ Includes -// Other libraries and framework includes -// Project includes #include #include diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/StringConvert.h b/contrib/llvm/tools/lldb/include/lldb/Host/StringConvert.h index d197df10d79e..1a85471a20c2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/StringConvert.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/StringConvert.h @@ -10,13 +10,9 @@ #ifndef liblldb_StringConvert_h_ #define liblldb_StringConvert_h_ -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/Symbols.h b/contrib/llvm/tools/lldb/include/lldb/Host/Symbols.h index ce95d91497f8..8b00900d3321 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/Symbols.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/Symbols.h @@ -10,12 +10,8 @@ #ifndef liblldb_Symbols_h_ #define liblldb_Symbols_h_ -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/FileSpec.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/TaskPool.h b/contrib/llvm/tools/lldb/include/lldb/Host/TaskPool.h index fe1714151076..4001d187a2a9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/TaskPool.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/TaskPool.h @@ -11,12 +11,12 @@ #define utility_TaskPool_h_ #include "llvm/ADT/STLExtras.h" -#include // for bind, function +#include #include #include -#include // for make_shared -#include // for mutex, unique_lock, condition_variable -#include // for forward, result_of, move +#include +#include +#include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/XML.h b/contrib/llvm/tools/lldb/include/lldb/Host/XML.h index 5088f1f25b0d..57e300752003 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/XML.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/XML.h @@ -10,20 +10,16 @@ #ifndef liblldb_XML_h_ #define liblldb_XML_h_ -// C Includes #if defined(LIBXML2_DEFINED) #include #endif -// C++ Includes #include #include #include -// Other libraries and framework includes #include "llvm/ADT/StringRef.h" -// Project includes #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpoint.h b/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpoint.h deleted file mode 100644 index 681570aadef0..000000000000 --- a/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpoint.h +++ /dev/null @@ -1,56 +0,0 @@ -//===-- NativeBreakpoint.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_NativeBreakpoint_h_ -#define liblldb_NativeBreakpoint_h_ - -#include "lldb/lldb-types.h" - -namespace lldb_private { -class NativeBreakpointList; - -class NativeBreakpoint { - friend class NativeBreakpointList; - -public: - // The assumption is that derived breakpoints are enabled when created. - NativeBreakpoint(lldb::addr_t addr); - - virtual ~NativeBreakpoint(); - - Status Enable(); - - Status Disable(); - - lldb::addr_t GetAddress() const { return m_addr; } - - bool IsEnabled() const { return m_enabled; } - - virtual bool IsSoftwareBreakpoint() const = 0; - -protected: - const lldb::addr_t m_addr; - int32_t m_ref_count; - - virtual Status DoEnable() = 0; - - virtual Status DoDisable() = 0; - -private: - bool m_enabled; - - // ----------------------------------------------------------- interface for - // NativeBreakpointList - // ----------------------------------------------------------- - void AddRef(); - int32_t DecRef(); -}; -} - -#endif // ifndef liblldb_NativeBreakpoint_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpointList.h b/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpointList.h index ffa659fdd869..b57174e51564 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpointList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeBreakpointList.h @@ -10,13 +10,9 @@ #ifndef liblldb_NativeBreakpointList_h_ #define liblldb_NativeBreakpointList_h_ -#include "lldb/Utility/Status.h" #include "lldb/lldb-private-forward.h" -// #include "lldb/Host/NativeBreakpoint.h" - -#include +#include "lldb/lldb-types.h" #include -#include namespace lldb_private { @@ -26,35 +22,6 @@ struct HardwareBreakpoint { }; using HardwareBreakpointMap = std::map; - -class NativeBreakpointList { -public: - typedef std::function - CreateBreakpointFunc; - - NativeBreakpointList(); - - Status AddRef(lldb::addr_t addr, size_t size_hint, bool hardware, - CreateBreakpointFunc create_func); - - Status DecRef(lldb::addr_t addr); - - Status EnableBreakpoint(lldb::addr_t addr); - - Status DisableBreakpoint(lldb::addr_t addr); - - Status GetBreakpoint(lldb::addr_t addr, NativeBreakpointSP &breakpoint_sp); - - Status RemoveTrapsFromBuffer(lldb::addr_t addr, void *buf, size_t size) const; - -private: - typedef std::map BreakpointMap; - - std::recursive_mutex m_mutex; - BreakpointMap m_breakpoints; -}; } #endif // ifndef liblldb_NativeBreakpointList_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeProcessProtocol.h b/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeProcessProtocol.h index d96835d75839..cb3b18eb0a3d 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeProcessProtocol.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeProcessProtocol.h @@ -25,6 +25,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/MemoryBuffer.h" +#include +#include #include namespace lldb_private { @@ -35,8 +37,6 @@ class ResumeActionList; // NativeProcessProtocol //------------------------------------------------------------------ class NativeProcessProtocol { - friend class SoftwareBreakpoint; - public: virtual ~NativeProcessProtocol() {} @@ -84,8 +84,8 @@ public: virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) = 0; - virtual Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, - size_t size, size_t &bytes_read) = 0; + Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, + size_t &bytes_read); virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) = 0; @@ -111,10 +111,6 @@ public: virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false); - virtual Status EnableBreakpoint(lldb::addr_t addr); - - virtual Status DisableBreakpoint(lldb::addr_t addr); - //---------------------------------------------------------------------- // Hardware Breakpoint functions //---------------------------------------------------------------------- @@ -402,6 +398,13 @@ public: } protected: + struct SoftwareBreakpoint { + uint32_t ref_count; + llvm::SmallVector saved_opcodes; + llvm::ArrayRef breakpoint_opcodes; + }; + + std::unordered_map m_software_breakpoints; lldb::pid_t m_pid; std::vector> m_threads; @@ -415,7 +418,6 @@ protected: std::recursive_mutex m_delegates_mutex; std::vector m_delegates; - NativeBreakpointList m_breakpoint_list; NativeWatchpointList m_watchpoint_list; HardwareBreakpointMap m_hw_breakpoints_map; int m_terminal_fd; @@ -446,12 +448,23 @@ protected: // ----------------------------------------------------------- Internal // interface for software breakpoints // ----------------------------------------------------------- - Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint); - virtual Status - GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint, - size_t &actual_opcode_size, - const uint8_t *&trap_opcode_bytes) = 0; + Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint); + Status RemoveSoftwareBreakpoint(lldb::addr_t addr); + + virtual llvm::Expected> + GetSoftwareBreakpointTrapOpcode(size_t size_hint); + + /// Return the offset of the PC relative to the software breakpoint that was hit. If an + /// architecture (e.g. arm) reports breakpoint hits before incrementing the PC, this offset + /// will be 0. If an architecture (e.g. intel) reports breakpoints hits after incrementing the + /// PC, this offset will be the size of the breakpoint opcode. + virtual size_t GetSoftwareBreakpointPCOffset(); + + // Adjust the thread's PC after hitting a software breakpoint. On + // architectures where the PC points after the breakpoint instruction, this + // resets it to point to the breakpoint itself. + void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread); // ----------------------------------------------------------- /// Notify the delegate that an exec occurred. @@ -465,6 +478,8 @@ protected: private: void SynchronouslyNotifyProcessStateChanged(lldb::StateType state); + llvm::Expected + EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint); }; } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeRegisterContext.h b/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeRegisterContext.h index 26458db153c1..268e0f2473fd 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeRegisterContext.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/common/NativeRegisterContext.h @@ -10,10 +10,6 @@ #ifndef liblldb_NativeRegisterContext_h_ #define liblldb_NativeRegisterContext_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/common/NativeWatchpointList.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/common/SoftwareBreakpoint.h b/contrib/llvm/tools/lldb/include/lldb/Host/common/SoftwareBreakpoint.h deleted file mode 100644 index e0f235fecd93..000000000000 --- a/contrib/llvm/tools/lldb/include/lldb/Host/common/SoftwareBreakpoint.h +++ /dev/null @@ -1,53 +0,0 @@ -//===-- SoftwareBreakpoint.h ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_SoftwareBreakpoint_h_ -#define liblldb_SoftwareBreakpoint_h_ - -#include "NativeBreakpoint.h" -#include "lldb/lldb-private-forward.h" - -namespace lldb_private { -class SoftwareBreakpoint : public NativeBreakpoint { - friend class NativeBreakpointList; - -public: - static Status CreateSoftwareBreakpoint(NativeProcessProtocol &process, - lldb::addr_t addr, size_t size_hint, - NativeBreakpointSP &breakpoint_spn); - - SoftwareBreakpoint(NativeProcessProtocol &process, lldb::addr_t addr, - const uint8_t *saved_opcodes, const uint8_t *trap_opcodes, - size_t opcode_size); - -protected: - Status DoEnable() override; - - Status DoDisable() override; - - bool IsSoftwareBreakpoint() const override; - -private: - /// Max number of bytes that a software trap opcode sequence can occupy. - static const size_t MAX_TRAP_OPCODE_SIZE = 8; - - NativeProcessProtocol &m_process; - uint8_t m_saved_opcodes[MAX_TRAP_OPCODE_SIZE]; - uint8_t m_trap_opcodes[MAX_TRAP_OPCODE_SIZE]; - const size_t m_opcode_size; - - static Status EnableSoftwareBreakpoint(NativeProcessProtocol &process, - lldb::addr_t addr, - size_t bp_opcode_size, - const uint8_t *bp_opcode_bytes, - uint8_t *saved_opcode_bytes); -}; -} - -#endif // #ifndef liblldb_SoftwareBreakpoint_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/contrib/llvm/tools/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index 0d125ca2c813..e44737e481e6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -10,19 +10,16 @@ #ifndef liblldb_Host_posix_ConnectionFileDescriptorPosix_h_ #define liblldb_Host_posix_ConnectionFileDescriptorPosix_h_ -// C++ Includes #include #include #include #include "lldb/lldb-forward.h" -// Other libraries and framework includes -// Project includes #include "lldb/Host/Pipe.h" -#include "lldb/Host/Predicate.h" #include "lldb/Utility/Connection.h" #include "lldb/Utility/IOObject.h" +#include "lldb/Utility/Predicate.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/posix/HostProcessPosix.h b/contrib/llvm/tools/lldb/include/lldb/Host/posix/HostProcessPosix.h index 0a6d8822d44f..2cbd4871dd6a 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/posix/HostProcessPosix.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/posix/HostProcessPosix.h @@ -10,10 +10,6 @@ #ifndef lldb_Host_HostProcesPosix_h_ #define lldb_Host_HostProcesPosix_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/HostNativeProcessBase.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/posix/PipePosix.h b/contrib/llvm/tools/lldb/include/lldb/Host/posix/PipePosix.h index bb65a56abd00..30d19d97152b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/posix/PipePosix.h +++ b/contrib/llvm/tools/lldb/include/lldb/Host/posix/PipePosix.h @@ -27,7 +27,7 @@ public: static int kInvalidDescriptor; PipePosix(); - PipePosix(int read_fd, int write_fd); + PipePosix(lldb::pipe_t read, lldb::pipe_t write); PipePosix(const PipePosix &) = delete; PipePosix(PipePosix &&pipe_posix); PipePosix &operator=(const PipePosix &) = delete; @@ -49,6 +49,13 @@ public: bool CanRead() const override; bool CanWrite() const override; + lldb::pipe_t GetReadPipe() const override { + return lldb::pipe_t(GetReadFileDescriptor()); + } + lldb::pipe_t GetWritePipe() const override { + return lldb::pipe_t(GetWriteFileDescriptor()); + } + int GetReadFileDescriptor() const override; int GetWriteFileDescriptor() const override; int ReleaseReadFileDescriptor() override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemInitializer.h b/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemInitializer.h index 58bbb44b1f34..b665b9997214 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemInitializer.h +++ b/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemInitializer.h @@ -10,13 +10,24 @@ #ifndef LLDB_INITIALIZATION_SYSTEM_INITIALIZER_H #define LLDB_INITIALIZATION_SYSTEM_INITIALIZER_H +#include "llvm/Support/Error.h" + +#include + namespace lldb_private { + +struct InitializerOptions { + bool reproducer_capture = false; + bool reproducer_replay = false; + std::string reproducer_path; +}; + class SystemInitializer { public: SystemInitializer(); virtual ~SystemInitializer(); - virtual void Initialize() = 0; + virtual llvm::Error Initialize(const InitializerOptions &options) = 0; virtual void Terminate() = 0; }; } diff --git a/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemInitializerCommon.h b/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemInitializerCommon.h index 2a9851c6a34c..f33acaf40466 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemInitializerCommon.h +++ b/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemInitializerCommon.h @@ -28,7 +28,7 @@ public: SystemInitializerCommon(); ~SystemInitializerCommon() override; - void Initialize() override; + llvm::Error Initialize(const InitializerOptions &options) override; void Terminate() override; }; diff --git a/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemLifetimeManager.h b/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemLifetimeManager.h index 0ebd4a50a342..0839856f21e2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemLifetimeManager.h +++ b/contrib/llvm/tools/lldb/include/lldb/Initialization/SystemLifetimeManager.h @@ -10,21 +10,23 @@ #ifndef LLDB_INITIALIZATION_SYSTEM_LIFETIME_MANAGER_H #define LLDB_INITIALIZATION_SYSTEM_LIFETIME_MANAGER_H +#include "lldb/Initialization/SystemInitializer.h" #include "lldb/lldb-private-types.h" +#include "llvm/Support/Error.h" #include #include namespace lldb_private { -class SystemInitializer; class SystemLifetimeManager { public: SystemLifetimeManager(); ~SystemLifetimeManager(); - void Initialize(std::unique_ptr initializer, - LoadPluginCallbackType plugin_callback); + llvm::Error Initialize(std::unique_ptr initializer, + const InitializerOptions &options, + LoadPluginCallbackType plugin_callback); void Terminate(); private: diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandAlias.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandAlias.h index 01522bd6ecea..c865ad7ff2c9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandAlias.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandAlias.h @@ -10,12 +10,8 @@ #ifndef liblldb_CommandAlias_h_ #define liblldb_CommandAlias_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/CompletionRequest.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandCompletions.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandCompletions.h index d17864e05f3e..71b0af3295b6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandCompletions.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandCompletions.h @@ -10,12 +10,8 @@ #ifndef lldb_CommandCompletions_h_ #define lldb_CommandCompletions_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/FileSpecList.h" #include "lldb/Core/SearchFilter.h" #include "lldb/Utility/CompletionRequest.h" @@ -116,7 +112,7 @@ public: CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, Address *addr, bool complete) override = 0; - Depth GetDepth() override = 0; + lldb::SearchDepth GetDepth() override = 0; virtual size_t DoCompletion(SearchFilter *filter) = 0; @@ -136,7 +132,7 @@ public: SourceFileCompleter(CommandInterpreter &interpreter, bool include_support_files, CompletionRequest &request); - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, @@ -162,7 +158,7 @@ public: ModuleCompleter(CommandInterpreter &interpreter, CompletionRequest &request); - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, @@ -186,7 +182,7 @@ public: SymbolCompleter(CommandInterpreter &interpreter, CompletionRequest &request); - Searcher::Depth GetDepth() override; + lldb::SearchDepth GetDepth() override; Searcher::CallbackReturn SearchCallback(SearchFilter &filter, SymbolContext &context, diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandHistory.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandHistory.h index faef220bbe94..f414c55e2d64 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandHistory.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandHistory.h @@ -10,14 +10,10 @@ #ifndef liblldb_CommandHistory_h_ #define liblldb_CommandHistory_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Stream.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandInterpreter.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandInterpreter.h index 78f505c24754..558246037ad0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandInterpreter.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandInterpreter.h @@ -10,80 +10,81 @@ #ifndef liblldb_CommandInterpreter_h_ #define liblldb_CommandInterpreter_h_ -// C Includes -// C++ Includes -#include -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Event.h" #include "lldb/Core/IOHandler.h" #include "lldb/Interpreter/CommandAlias.h" #include "lldb/Interpreter/CommandHistory.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/CompletionRequest.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StringList.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" +#include namespace lldb_private { class CommandInterpreterRunOptions { public: //------------------------------------------------------------------ - /// Construct a CommandInterpreterRunOptions object. - /// This class is used to control all the instances where we run multiple - /// commands, e.g. + /// Construct a CommandInterpreterRunOptions object. This class is used to + /// control all the instances where we run multiple commands, e.g. /// HandleCommands, HandleCommandsFromFile, RunCommandInterpreter. + /// /// The meanings of the options in this object are: /// /// @param[in] stop_on_continue - /// If \b true execution will end on the first command that causes the - /// process in the - /// execution context to continue. If \false, we won't check the execution - /// status. + /// If \b true, execution will end on the first command that causes the + /// process in the execution context to continue. If \b false, we won't + /// check the execution status. /// @param[in] stop_on_error - /// If \b true execution will end on the first command that causes an + /// If \b true, execution will end on the first command that causes an /// error. /// @param[in] stop_on_crash - /// If \b true when a command causes the target to run, and the end of the - /// run is a - /// signal or exception, stop executing the commands. + /// If \b true, when a command causes the target to run, and the end of the + /// run is a signal or exception, stop executing the commands. /// @param[in] echo_commands - /// If \b true echo the command before executing it. If \false, execute + /// If \b true, echo the command before executing it. If \b false, execute /// silently. + /// @param[in] echo_comments + /// If \b true, echo command even if it is a pure comment line. If + /// \b false, print no ouput in this case. This setting has an effect only + /// if \param echo_commands is \b true. /// @param[in] print_results - /// If \b true print the results of the command after executing it. If - /// \false, execute silently. + /// If \b true print the results of the command after executing it. If + /// \b false, execute silently. /// @param[in] add_to_history - /// If \b true add the commands to the command history. If \false, don't + /// If \b true add the commands to the command history. If \b false, don't /// add them. //------------------------------------------------------------------ CommandInterpreterRunOptions(LazyBool stop_on_continue, LazyBool stop_on_error, LazyBool stop_on_crash, - LazyBool echo_commands, LazyBool print_results, - LazyBool add_to_history) + LazyBool echo_commands, LazyBool echo_comments, + LazyBool print_results, LazyBool add_to_history) : m_stop_on_continue(stop_on_continue), m_stop_on_error(stop_on_error), m_stop_on_crash(stop_on_crash), m_echo_commands(echo_commands), - m_print_results(print_results), m_add_to_history(add_to_history) {} + m_echo_comment_commands(echo_comments), m_print_results(print_results), + m_add_to_history(add_to_history) {} CommandInterpreterRunOptions() : m_stop_on_continue(eLazyBoolCalculate), m_stop_on_error(eLazyBoolCalculate), m_stop_on_crash(eLazyBoolCalculate), m_echo_commands(eLazyBoolCalculate), + m_echo_comment_commands(eLazyBoolCalculate), m_print_results(eLazyBoolCalculate), m_add_to_history(eLazyBoolCalculate) {} void SetSilent(bool silent) { LazyBool value = silent ? eLazyBoolNo : eLazyBoolYes; - m_echo_commands = value; m_print_results = value; + m_echo_commands = value; + m_echo_comment_commands = value; m_add_to_history = value; } // These return the default behaviors if the behavior is not @@ -97,7 +98,7 @@ public: m_stop_on_continue = stop_on_continue ? eLazyBoolYes : eLazyBoolNo; } - bool GetStopOnError() const { return DefaultToNo(m_stop_on_continue); } + bool GetStopOnError() const { return DefaultToNo(m_stop_on_error); } void SetStopOnError(bool stop_on_error) { m_stop_on_error = stop_on_error ? eLazyBoolYes : eLazyBoolNo; @@ -115,6 +116,14 @@ public: m_echo_commands = echo_commands ? eLazyBoolYes : eLazyBoolNo; } + bool GetEchoCommentCommands() const { + return DefaultToYes(m_echo_comment_commands); + } + + void SetEchoCommentCommands(bool echo_comments) { + m_echo_comment_commands = echo_comments ? eLazyBoolYes : eLazyBoolNo; + } + bool GetPrintResults() const { return DefaultToYes(m_print_results); } void SetPrintResults(bool print_results) { @@ -131,6 +140,7 @@ public: LazyBool m_stop_on_error; LazyBool m_stop_on_crash; LazyBool m_echo_commands; + LazyBool m_echo_comment_commands; LazyBool m_print_results; LazyBool m_add_to_history; @@ -206,7 +216,8 @@ public: bool include_aliases) const; CommandObject *GetCommandObject(llvm::StringRef cmd, - StringList *matches = nullptr) const; + StringList *matches = nullptr, + StringList *descriptions = nullptr) const; bool CommandExists(llvm::StringRef cmd) const; @@ -310,7 +321,8 @@ public: // FIXME: Only max_return_elements == -1 is supported at present. int HandleCompletion(const char *current_line, const char *cursor, const char *last_char, int match_start_point, - int max_return_elements, StringList &matches); + int max_return_elements, StringList &matches, + StringList &descriptions); // This version just returns matches, and doesn't compute the substring. It // is here so the Help command can call it for the first argument. It uses @@ -319,7 +331,8 @@ public: int GetCommandNamesMatchingPartialString(const char *cmd_cstr, bool include_aliases, - StringList &matches); + StringList &matches, + StringList &descriptions); void GetHelp(CommandReturnObject &result, uint32_t types = eCommandTypesAllThem); @@ -456,6 +469,12 @@ public: void SetPromptOnQuit(bool b); + bool GetEchoCommands() const; + void SetEchoCommands(bool b); + + bool GetEchoCommentCommands() const; + void SetEchoCommentCommands(bool b); + //------------------------------------------------------------------ /// Specify if the command interpreter should allow that the user can /// specify a custom exit code when calling 'quit'. @@ -520,7 +539,8 @@ protected: lldb::CommandObjectSP GetCommandSP(llvm::StringRef cmd, bool include_aliases = true, bool exact = true, - StringList *matches = nullptr) const; + StringList *matches = nullptr, + StringList *descriptions = nullptr) const; private: Status PreprocessCommand(std::string &command); @@ -538,6 +558,9 @@ private: // An interruptible wrapper around the stream output void PrintCommandOutput(Stream &stream, llvm::StringRef str); + bool EchoCommandNonInteractive(llvm::StringRef line, + const Flags &io_handler_flags) const; + // A very simple state machine which models the command handling transitions enum class CommandHandlingState { eIdle, diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObject.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObject.h index 7afb18b2f598..f72628b8a643 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObject.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObject.h @@ -10,14 +10,10 @@ #ifndef liblldb_CommandObject_h_ #define liblldb_CommandObject_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Flags.h" #include "lldb/Interpreter/CommandCompletions.h" @@ -37,8 +33,9 @@ namespace lldb_private { // number added. template -int AddNamesMatchingPartialString(const std::map &in_map, - llvm::StringRef cmd_str, StringList &matches) { +int AddNamesMatchingPartialString( + const std::map &in_map, llvm::StringRef cmd_str, + StringList &matches, StringList *descriptions = nullptr) { int number_added = 0; const bool add_all = cmd_str.empty(); @@ -47,6 +44,8 @@ int AddNamesMatchingPartialString(const std::map &in_map if (add_all || (iter->first.find(cmd_str, 0) == 0)) { ++number_added; matches.AppendString(iter->first.c_str()); + if (descriptions) + descriptions->AppendString(iter->second->GetHelp()); } } diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObjectMultiword.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObjectMultiword.h index d9eff9a6e545..e1ea39f7ec34 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObjectMultiword.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectMultiword_h_ #define liblldb_CommandObjectMultiword_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" #include "lldb/Utility/CompletionRequest.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h index 36c3f068bdf3..d50bc3ba9141 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandObjectRegexCommand.h @@ -10,12 +10,8 @@ #ifndef liblldb_CommandObjectRegexCommand_h_ #define liblldb_CommandObjectRegexCommand_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/RegularExpression.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandOptionValidators.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandOptionValidators.h index 05724cace172..e0c8ddde6ecb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandOptionValidators.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandOptionValidators.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandOptionValidators_h_ #define liblldb_CommandOptionValidators_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private-types.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandReturnObject.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandReturnObject.h index 7b04c391bc76..53a908f97ccb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandReturnObject.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/CommandReturnObject.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandReturnObject_h_ #define liblldb_CommandReturnObject_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/STLUtils.h" #include "lldb/Core/StreamFile.h" #include "lldb/Utility/StreamString.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionArgParser.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionArgParser.h index 5ace7e5d0250..b5a083929067 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionArgParser.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionArgParser.h @@ -24,7 +24,7 @@ struct OptionArgParser { static char ToChar(llvm::StringRef s, char fail_value, bool *success_ptr); static int64_t ToOptionEnum(llvm::StringRef s, - OptionEnumValueElement *enum_values, + const OptionEnumValues &enum_values, int32_t fail_value, Status &error); static lldb::ScriptLanguage ToScriptLanguage(llvm::StringRef s, diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupBoolean.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupBoolean.h index 2489a648dd7e..161c12a41f9f 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupBoolean.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupBoolean.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupBoolean_h_ #define liblldb_OptionGroupBoolean_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupFile.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupFile.h index d0c25b8bf8e6..4a56e4c742fd 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupFile.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupFile.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupFile_h_ #define liblldb_OptionGroupFile_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueFileSpec.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupFormat.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupFormat.h index ddf2ccece3bd..52113d8777f5 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupFormat.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupFormat.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupFormat_h_ #define liblldb_OptionGroupFormat_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueFormat.h" #include "lldb/Interpreter/OptionValueSInt64.h" #include "lldb/Interpreter/OptionValueUInt64.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h index 19453c6215ef..88d45797358d 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupOutputFile.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupOutputFile_h_ #define liblldb_OptionGroupOutputFile_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueBoolean.h" #include "lldb/Interpreter/OptionValueFileSpec.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupPlatform.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupPlatform.h index cda4246f1b01..9bc9588deab3 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupPlatform.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupPlatform.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupPlatform_h_ #define liblldb_OptionGroupPlatform_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/Options.h" #include "lldb/Utility/ConstString.h" #include "llvm/Support/VersionTuple.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupString.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupString.h index 01e8aa9dc3b6..41889fe57d77 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupString.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupString.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupString_h_ #define liblldb_OptionGroupString_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupUInt64.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupUInt64.h index 82eb0e26af9b..d6b06066b964 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupUInt64.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupUInt64.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupUInt64_h_ #define liblldb_OptionGroupUInt64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupUUID.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupUUID.h index def97d5f2551..390f128a8618 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupUUID.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupUUID.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupUUID_h_ #define liblldb_OptionGroupUUID_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueUUID.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h index 0e075773b3f7..8684453d89c6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupValueObjectDisplay_h_ #define liblldb_OptionGroupValueObjectDisplay_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/ValueObject.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupVariable.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupVariable.h index c9e90320e141..663705acebbc 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupVariable.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupVariable.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupVariable_h_ #define liblldb_OptionGroupVariable_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/Options.h" @@ -39,6 +35,8 @@ public: bool include_frame_options : 1, show_args : 1, // Frame option only (include_frame_options == true) + show_recognized_args : 1, // Frame option only (include_frame_options == + // true) show_locals : 1, // Frame option only (include_frame_options == true) show_globals : 1, // Frame option only (include_frame_options == true) use_regex : 1, show_scope : 1, show_decl : 1; diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h index f2665638ba85..2d4456ef31a9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionGroupWatchpoint.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionGroupWatchpoint_h_ #define liblldb_OptionGroupWatchpoint_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/Options.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValue.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValue.h index 4748e309c77e..e90d7ed6d8eb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValue.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValue.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValue_h_ #define liblldb_OptionValue_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/FormatEntity.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/ConstString.h" @@ -58,9 +54,11 @@ public: eDumpOptionValue = (1u << 2), eDumpOptionDescription = (1u << 3), eDumpOptionRaw = (1u << 4), + eDumpOptionCommand = (1u << 5), eDumpGroupValue = (eDumpOptionName | eDumpOptionType | eDumpOptionValue), eDumpGroupHelp = - (eDumpOptionName | eDumpOptionType | eDumpOptionDescription) + (eDumpOptionName | eDumpOptionType | eDumpOptionDescription), + eDumpGroupExport = (eDumpOptionCommand | eDumpOptionName | eDumpOptionValue) }; OptionValue() diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueArgs.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueArgs.h index 433679da134e..41af1298c2cb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueArgs.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueArgs.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValueArgs_h_ #define liblldb_OptionValueArgs_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValueArray.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueArray.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueArray.h index 44709d00763f..06c482840260 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueArray.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueArray.h @@ -10,12 +10,8 @@ #ifndef liblldb_OptionValueArray_h_ #define liblldb_OptionValueArray_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueBoolean.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueBoolean.h index 6d2a16e59597..572e6b1861fb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueBoolean.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueBoolean.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValueBoolean_h_ #define liblldb_OptionValueBoolean_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueChar.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueChar.h index 0c5f602efe9b..e73976fefccc 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueChar.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueChar.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValueChar_h_ #define liblldb_OptionValueChar_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueDictionary.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueDictionary.h index 4e8c86008ea4..b6163e7a9a25 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueDictionary.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueDictionary.h @@ -10,12 +10,8 @@ #ifndef liblldb_OptionValueDictionary_h_ #define liblldb_OptionValueDictionary_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueEnumeration.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueEnumeration.h index 08d6ac70de52..16c09c589a27 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueEnumeration.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueEnumeration.h @@ -30,8 +30,7 @@ public: typedef UniqueCStringMap EnumerationMap; typedef EnumerationMap::Entry EnumerationMapEntry; - OptionValueEnumeration(const OptionEnumValueElement *enumerators, - enum_type value); + OptionValueEnumeration(const OptionEnumValues &enumerators, enum_type value); ~OptionValueEnumeration() override; @@ -80,7 +79,7 @@ public: void SetDefaultValue(enum_type value) { m_default_value = value; } protected: - void SetEnumerations(const OptionEnumValueElement *enumerators); + void SetEnumerations(const OptionEnumValues &enumerators); enum_type m_current_value; enum_type m_default_value; diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h index 9529fbcf38bc..5c43b85bcea7 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFileSpecList.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValueFileSpecList_h_ #define liblldb_OptionValueFileSpecList_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/FileSpecList.h" #include "lldb/Interpreter/OptionValue.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFormat.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFormat.h index ce7997024b09..6d46957d26f7 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFormat.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFormat.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValueFormat_h_ #define liblldb_OptionValueFormat_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h index 880e434dc5c0..5d5a8ca02c97 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueFormatEntity.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValueFormatEntity_h_ #define liblldb_OptionValueFormatEntity_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/FormatEntity.h" #include "lldb/Interpreter/OptionValue.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueLanguage.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueLanguage.h index 8f81c5df0739..9d4956c6d789 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueLanguage.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueLanguage.h @@ -11,10 +11,6 @@ #ifndef liblldb_OptionValueLanguage_h_ #define liblldb_OptionValueLanguage_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" #include "lldb/lldb-enumerations.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValuePathMappings.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValuePathMappings.h index 0e2e98d74b74..85f9926b21f8 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValuePathMappings.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValuePathMappings.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValuePathMappings_h_ #define liblldb_OptionValuePathMappings_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" #include "lldb/Target/PathMappingList.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueProperties.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueProperties.h index 96bd93ab3d7b..941e48561f77 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueProperties.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueProperties.h @@ -10,12 +10,8 @@ #ifndef liblldb_OptionValueProperties_h_ #define liblldb_OptionValueProperties_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/FormatEntity.h" #include "lldb/Core/UniqueCStringMap.h" #include "lldb/Interpreter/OptionValue.h" @@ -62,7 +58,7 @@ public: void Apropos(llvm::StringRef keyword, std::vector &matching_properties) const; - void Initialize(const PropertyDefinition *setting_definitions); + void Initialize(const PropertyDefinitions &setting_definitions); // bool // GetQualifiedName (Stream &strm); diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueRegex.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueRegex.h index afe9318ae014..a77eb5323f23 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueRegex.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueRegex.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValueRegex_h_ #define liblldb_OptionValueRegex_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/RegularExpression.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueSInt64.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueSInt64.h index a6893d23e692..f630cbb8e283 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueSInt64.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueSInt64.h @@ -11,10 +11,6 @@ #ifndef liblldb_OptionValueSInt64_h_ #define liblldb_OptionValueSInt64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueString.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueString.h index 4a9f2227680e..ab15595a08b4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueString.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueString.h @@ -10,12 +10,8 @@ #ifndef liblldb_OptionValueString_h_ #define liblldb_OptionValueString_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Flags.h" #include "lldb/Interpreter/OptionValue.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueUInt64.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueUInt64.h index 96404bed8e67..5cbcafdb6e58 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueUInt64.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueUInt64.h @@ -11,10 +11,6 @@ #ifndef liblldb_OptionValueUInt64_h_ #define liblldb_OptionValueUInt64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueUUID.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueUUID.h index 950efb518d5a..c2ee48962b42 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueUUID.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/OptionValueUUID.h @@ -10,10 +10,6 @@ #ifndef liblldb_OptionValueUUID_h_ #define liblldb_OptionValueUUID_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/UUID.h" #include "lldb/Interpreter/OptionValue.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/Options.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/Options.h index 316bf568fd92..aa9e564083a9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/Options.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/Options.h @@ -10,13 +10,9 @@ #ifndef liblldb_Options_h_ #define liblldb_Options_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Args.h" #include "lldb/Utility/CompletionRequest.h" #include "lldb/Utility/Status.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/Property.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/Property.h index 9d0dc5fa0fd8..a7515e9903a4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/Property.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/Property.h @@ -28,10 +28,12 @@ struct PropertyDefinition { bool global; // false == this setting is a global setting by default uintptr_t default_uint_value; const char *default_cstr_value; - OptionEnumValueElement *enum_values; + OptionEnumValues enum_values; const char *description; }; +using PropertyDefinitions = llvm::ArrayRef; + class Property { public: Property(const PropertyDefinition &definition); diff --git a/contrib/llvm/tools/lldb/include/lldb/Interpreter/ScriptInterpreter.h b/contrib/llvm/tools/lldb/include/lldb/Interpreter/ScriptInterpreter.h index d2189edd04a6..640d9d34c617 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Interpreter/ScriptInterpreter.h +++ b/contrib/llvm/tools/lldb/include/lldb/Interpreter/ScriptInterpreter.h @@ -10,15 +10,12 @@ #ifndef liblldb_ScriptInterpreter_h_ #define liblldb_ScriptInterpreter_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" #include "lldb/Breakpoint/BreakpointOptions.h" -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/SearchFilter.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" @@ -172,6 +169,17 @@ public: return StructuredData::GenericSP(); } + virtual StructuredData::GenericSP + CreateFrameRecognizer(const char *class_name) { + return StructuredData::GenericSP(); + } + + virtual lldb::ValueObjectListSP GetRecognizedArguments( + const StructuredData::ObjectSP &implementor, + lldb::StackFrameSP frame_sp) { + return lldb::ValueObjectListSP(); + } + virtual StructuredData::GenericSP OSPlugin_CreatePluginObject(const char *class_name, lldb::ProcessSP process_sp) { @@ -234,6 +242,26 @@ public: return lldb::eStateStepping; } + virtual StructuredData::GenericSP + CreateScriptedBreakpointResolver(const char *class_name, + StructuredDataImpl *args_data, + lldb::BreakpointSP &bkpt_sp) { + return StructuredData::GenericSP(); + } + + virtual bool + ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp, + SymbolContext *sym_ctx) + { + return false; + } + + virtual lldb::SearchDepth + ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp) + { + return lldb::eSearchDepthModule; + } + virtual StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { return StructuredData::ObjectSP(); diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/Block.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/Block.h index 1664362431f9..2428a1d3ffca 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/Block.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/Block.h @@ -10,12 +10,8 @@ #ifndef liblldb_Block_h_ #define liblldb_Block_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/AddressRange.h" #include "lldb/Core/RangeMap.h" #include "lldb/Symbol/CompilerType.h" @@ -327,6 +323,14 @@ public: return m_inlineInfoSP.get(); } + //------------------------------------------------------------------ + /// Get the symbol file which contains debug info for this block's + /// symbol context module. + /// + /// @return A pointer to the symbol file or nullptr. + //------------------------------------------------------------------ + SymbolFile *GetSymbolFile(); + CompilerDeclContext GetDeclContext(); //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTContext.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTContext.h index 38632c5bd5de..026d5caeb50b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTContext.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTContext.h @@ -10,10 +10,8 @@ #ifndef liblldb_ClangASTContext_h_ #define liblldb_ClangASTContext_h_ -// C Includes #include -// C++ Includes #include #include #include @@ -23,13 +21,12 @@ #include #include -// Other libraries and framework includes #include "clang/AST/ASTContext.h" #include "clang/AST/ExternalASTMerger.h" #include "clang/AST/TemplateBase.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" -// Project includes #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" #include "lldb/Core/ClangForward.h" #include "lldb/Symbol/CompilerType.h" @@ -216,19 +213,24 @@ public: static CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl); template - CompilerType GetTypeForIdentifier(const ConstString &type_name) { + CompilerType + GetTypeForIdentifier(const ConstString &type_name, + clang::DeclContext *decl_context = nullptr) { CompilerType compiler_type; if (type_name.GetLength()) { clang::ASTContext *ast = getASTContext(); if (ast) { + if (!decl_context) + decl_context = ast->getTranslationUnitDecl(); + clang::IdentifierInfo &myIdent = ast->Idents.get(type_name.GetCString()); clang::DeclarationName myName = ast->DeclarationNames.getIdentifier(&myIdent); clang::DeclContext::lookup_result result = - ast->getTranslationUnitDecl()->lookup(myName); + decl_context->lookup(myName); if (!result.empty()) { clang::NamedDecl *named_decl = result[0]; @@ -374,7 +376,17 @@ public: const CompilerType &result_type, const CompilerType *args, unsigned num_args, bool is_variadic, - unsigned type_quals); + unsigned type_quals, + clang::CallingConv cc); + + static CompilerType CreateFunctionType(clang::ASTContext *ast, + const CompilerType &result_type, + const CompilerType *args, + unsigned num_args, bool is_variadic, + unsigned type_quals) { + return ClangASTContext::CreateFunctionType( + ast, result_type, args, num_args, is_variadic, type_quals, clang::CC_C); + } CompilerType CreateFunctionType(const CompilerType &result_type, const CompilerType *args, unsigned num_args, @@ -383,7 +395,17 @@ public: getASTContext(), result_type, args, num_args, is_variadic, type_quals); } - clang::ParmVarDecl *CreateParameterDeclaration(const char *name, + CompilerType CreateFunctionType(const CompilerType &result_type, + const CompilerType *args, unsigned num_args, + bool is_variadic, unsigned type_quals, + clang::CallingConv cc) { + return ClangASTContext::CreateFunctionType(getASTContext(), result_type, + args, num_args, is_variadic, + type_quals, cc); + } + + clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx, + const char *name, const CompilerType ¶m_type, int storage); @@ -724,7 +746,8 @@ public: size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) override; + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) override; CompilerType GetBuiltinTypeByName(const ConstString &name) override; @@ -813,7 +836,7 @@ public: // Modifying RecordType //---------------------------------------------------------------------- static clang::FieldDecl *AddFieldToRecordType(const CompilerType &type, - const char *name, + llvm::StringRef name, const CompilerType &field_type, lldb::AccessType access, uint32_t bitfield_bit_size); @@ -823,7 +846,7 @@ public: static void SetIsPacked(const CompilerType &type); static clang::VarDecl *AddVariableToRecordType(const CompilerType &type, - const char *name, + llvm::StringRef name, const CompilerType &var_type, lldb::AccessType access); @@ -835,19 +858,17 @@ public: bool is_static, bool is_inline, bool is_explicit, bool is_attr_used, bool is_artificial); + void AddMethodOverridesForCXXRecordType(lldb::opaque_compiler_type_t type); + // C++ Base Classes - clang::CXXBaseSpecifier * + std::unique_ptr CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, lldb::AccessType access, bool is_virtual, bool base_of_class); - static void DeleteBaseClassSpecifiers(clang::CXXBaseSpecifier **base_classes, - unsigned num_base_classes); - - bool - SetBaseClassesForClassType(lldb::opaque_compiler_type_t type, - clang::CXXBaseSpecifier const *const *base_classes, - unsigned num_base_classes); + bool TransferBaseClasses( + lldb::opaque_compiler_type_t type, + std::vector> bases); static bool SetObjCSuperClass(const CompilerType &type, const CompilerType &superclass_compiler_type); @@ -883,10 +904,12 @@ public: //---------------------------------------------------------------------- // Modifying Enumeration types //---------------------------------------------------------------------- - bool AddEnumerationValueToEnumerationType( - lldb::opaque_compiler_type_t type, - const CompilerType &enumerator_qual_type, const Declaration &decl, - const char *name, int64_t enum_value, uint32_t enum_value_bit_size); + clang::EnumConstantDecl *AddEnumerationValueToEnumerationType( + const CompilerType &enum_type, const Declaration &decl, const char *name, + int64_t enum_value, uint32_t enum_value_bit_size); + clang::EnumConstantDecl *AddEnumerationValueToEnumerationType( + const CompilerType &enum_type, const Declaration &decl, const char *name, + const llvm::APSInt &value); CompilerType GetEnumerationIntegerType(lldb::opaque_compiler_type_t type); @@ -908,6 +931,8 @@ public: //---------------------------------------------------------------------- // Dumping types //---------------------------------------------------------------------- + void Dump(Stream &s); + void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, @@ -939,6 +964,8 @@ public: static clang::TagDecl *GetAsTagDecl(const CompilerType &type); + static clang::TypedefNameDecl *GetAsTypedefDecl(const CompilerType &type); + clang::CXXRecordDecl *GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type); static clang::ObjCInterfaceDecl * diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTImporter.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTImporter.h index 52a164a1d2dd..465d7e24a1e7 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTImporter.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangASTImporter.h @@ -10,14 +10,11 @@ #ifndef liblldb_ClangASTImporter_h_ #define liblldb_ClangASTImporter_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes #include "clang/AST/ASTImporter.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" @@ -25,7 +22,6 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" -// Project includes #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h index ef0010314e1d..c077665e51ee 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangExternalASTSourceCallbacks.h @@ -10,15 +10,11 @@ #ifndef liblldb_ClangExternalASTSourceCallbacks_h_ #define liblldb_ClangExternalASTSourceCallbacks_h_ -// C Includes #include -// C++ Includes -// Other libraries and framework includes #include "clang/AST/CharUnits.h" #include "llvm/ADT/DenseMap.h" -// Project includes #include "lldb/Core/ClangForward.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/CompilerType.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangExternalASTSourceCommon.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangExternalASTSourceCommon.h index 3e700ba2439c..894c91f157da 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangExternalASTSourceCommon.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangExternalASTSourceCommon.h @@ -20,7 +20,6 @@ // file. So we have to define NDEBUG when including clang headers to avoid any // mismatches. This is covered by rdar://problem/8691220 -// C Includes #if !defined(NDEBUG) && !defined(LLVM_NDEBUG_OFF) #define LLDB_DEFINED_NDEBUG_FOR_CLANG #define NDEBUG @@ -35,11 +34,8 @@ #include #endif -// C++ Includes -// Other libraries and framework includes #include "clang/AST/ExternalASTSource.h" -// Project includes #include "lldb/Core/dwarf.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangUtil.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangUtil.h index cb380221152a..c8638f782548 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangUtil.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/ClangUtil.h @@ -16,6 +16,10 @@ #include "lldb/Symbol/CompilerType.h" +namespace clang { +class TagDecl; +} + namespace lldb_private { struct ClangUtil { static bool IsClangType(const CompilerType &ct); @@ -25,6 +29,8 @@ struct ClangUtil { static clang::QualType GetCanonicalQualType(const CompilerType &ct); static CompilerType RemoveFastQualifiers(const CompilerType &ct); + + static clang::TagDecl *GetAsTagDecl(const CompilerType &type); }; } diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/CompileUnit.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/CompileUnit.h index b816439cee13..a4d19cd3d8ae 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/CompileUnit.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/CompileUnit.h @@ -18,6 +18,8 @@ #include "lldb/Utility/UserID.h" #include "lldb/lldb-enumerations.h" +#include "llvm/ADT/DenseMap.h" + namespace lldb_private { //---------------------------------------------------------------------- /// @class CompileUnit CompileUnit.h "lldb/Symbol/CompileUnit.h" @@ -163,21 +165,19 @@ public: void GetDescription(Stream *s, lldb::DescriptionLevel level) const; //------------------------------------------------------------------ - /// Get a shared pointer to a function in this compile unit by index. + /// Apply a lambda to each function in this compile unit. /// - /// Typically called when iterating though all functions in a compile unit - /// after all functions have been parsed. This provides raw access to the - /// function shared pointer list and will not cause the SymbolFile plug-in - /// to parse any unparsed functions. + /// This provides raw access to the function shared pointer list and will not + /// cause the SymbolFile plug-in to parse any unparsed functions. /// - /// @param[in] idx - /// An index into the function list. + /// @note Prefer using FindFunctionByUID over this if possible. /// - /// @return - /// A shared pointer to a function that might contain a NULL - /// Function class pointer. + /// @param[in] lambda + /// The lambda that should be applied to every function. The lambda can + /// return true if the iteration should be aborted earlier. //------------------------------------------------------------------ - lldb::FunctionSP GetFunctionAtIndex(size_t idx); + void ForeachFunction( + llvm::function_ref lambda) const; //------------------------------------------------------------------ /// Dump the compile unit contents to the stream \a s. @@ -391,7 +391,7 @@ public: //------------------------------------------------------------------ uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, bool check_inlines, bool exact, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); //------------------------------------------------------------------ @@ -409,15 +409,20 @@ public: //------------------------------------------------------------------ bool GetIsOptimized(); + //------------------------------------------------------------------ + /// Returns the number of functions in this compile unit + //------------------------------------------------------------------ + size_t GetNumFunctions() const { return m_functions_by_uid.size(); } + protected: void *m_user_data; ///< User data for the SymbolFile parser to store ///information into. lldb::LanguageType m_language; ///< The programming language enumeration value. Flags m_flags; ///< Compile unit flags that help with partial parsing. - std::vector m_functions; ///< The sparsely populated list of - ///shared pointers to functions - ///< that gets populated as functions get partially parsed. + + /// Maps UIDs to functions. + llvm::DenseMap m_functions_by_uid; std::vector m_imported_modules; ///< All modules, including the ///current module, imported by ///this diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/CompilerType.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/CompilerType.h index 1170832a7396..353313d8e2a3 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/CompilerType.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/CompilerType.h @@ -10,14 +10,10 @@ #ifndef liblldb_CompilerType_h_ #define liblldb_CompilerType_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/ClangForward.h" #include "lldb/lldb-private.h" #include "llvm/ADT/APSInt.h" @@ -291,9 +287,10 @@ public: struct IntegralTemplateArgument; - uint64_t GetByteSize(ExecutionContextScope *exe_scope) const; - - uint64_t GetBitSize(ExecutionContextScope *exe_scope) const; + /// Return the size of the type in bytes. + llvm::Optional GetByteSize(ExecutionContextScope *exe_scope) const; + /// Return the size of the type in bits. + llvm::Optional GetBitSize(ExecutionContextScope *exe_scope) const; lldb::Encoding GetEncoding(uint64_t &count) const; @@ -301,7 +298,8 @@ public: size_t GetTypeBitAlign() const; - uint32_t GetNumChildren(bool omit_empty_base_classes) const; + uint32_t GetNumChildren(bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) const; lldb::BasicType GetBasicTypeEnumeration() const; diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/DebugMacros.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/DebugMacros.h index 640da027cd59..86700994fbcc 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/DebugMacros.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/DebugMacros.h @@ -10,13 +10,9 @@ #ifndef liblldb_DebugMacros_h_ #define liblldb_DebugMacros_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/Function.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/Function.h index 28c6b4857b10..447abd2e6f78 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/Function.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/Function.h @@ -16,6 +16,7 @@ #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Declaration.h" #include "lldb/Utility/UserID.h" +#include "llvm/ADT/ArrayRef.h" namespace lldb_private { @@ -290,6 +291,64 @@ private: Declaration m_call_decl; }; +class Function; + +//---------------------------------------------------------------------- +/// @class CallEdge Function.h "lldb/Symbol/Function.h" +/// +/// Represent a call made within a Function. This can be used to find a path +/// in the call graph between two functions. +//---------------------------------------------------------------------- +class CallEdge { +public: + /// Construct a call edge using a symbol name to identify the calling + /// function, and a return PC within the calling function to identify a + /// specific call site. + /// + /// TODO: A symbol name may not be globally unique. To disambiguate ODR + /// conflicts, it's necessary to determine the \c Target a call edge is + /// associated with before resolving it. + CallEdge(const char *symbol_name, lldb::addr_t return_pc); + + CallEdge(CallEdge &&) = default; + CallEdge &operator=(CallEdge &&) = default; + + /// Get the callee's definition. + /// + /// Note that this might lazily invoke the DWARF parser. + Function *GetCallee(ModuleList &images); + + /// Get the load PC address of the instruction which executes after the call + /// returns. Returns LLDB_INVALID_ADDRESS iff this is a tail call. \p caller + /// is the Function containing this call, and \p target is the Target which + /// made the call. + lldb::addr_t GetReturnPCAddress(Function &caller, Target &target) const; + + /// Like \ref GetReturnPCAddress, but returns an unslid function-local PC + /// offset. + lldb::addr_t GetUnresolvedReturnPCAddress() const { return return_pc; } + +private: + void ParseSymbolFileAndResolve(ModuleList &images); + + /// Either the callee's mangled name or its definition, discriminated by + /// \ref resolved. + union { + const char *symbol_name; + Function *def; + } lazy_callee; + + /// An invalid address if this is a tail call. Otherwise, the function-local + /// PC offset. Adding this PC offset to the function's base load address + /// gives the return PC for the call. + lldb::addr_t return_pc; + + /// Whether or not an attempt was made to find the callee's definition. + bool resolved; + + DISALLOW_COPY_AND_ASSIGN(CallEdge); +}; + //---------------------------------------------------------------------- /// @class Function Function.h "lldb/Symbol/Function.h" /// A class that describes a function. @@ -348,40 +407,6 @@ public: lldb::user_id_t func_type_uid, const Mangled &mangled, Type *func_type, const AddressRange &range); - //------------------------------------------------------------------ - /// Construct with a compile unit, function UID, function type UID, optional - /// mangled name, function type, and a section offset based address range. - /// - /// @param[in] comp_unit - /// The compile unit to which this function belongs. - /// - /// @param[in] func_uid - /// The UID for this function. This value is provided by the - /// SymbolFile plug-in and can be any value that allows - /// the plug-in to quickly find and parse more detailed - /// information when and if more information is needed. - /// - /// @param[in] func_type_uid - /// The type UID for the function Type to allow for lazy type - /// parsing from the debug information. - /// - /// @param[in] mangled - /// The optional mangled name for this function. If empty, there - /// is no mangled information. - /// - /// @param[in] func_type - /// The optional function type. If NULL, the function type will - /// be parsed on demand when accessed using the - /// Function::GetType() function by asking the SymbolFile - /// plug-in to get the type for \a func_type_uid. - /// - /// @param[in] range - /// The section offset based address for this function. - //------------------------------------------------------------------ - Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, - lldb::user_id_t func_type_uid, const char *mangled, Type *func_type, - const AddressRange &range); - //------------------------------------------------------------------ /// Destructor. //------------------------------------------------------------------ @@ -430,6 +455,18 @@ public: //------------------------------------------------------------------ void GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no); + //------------------------------------------------------------------ + /// Get the outgoing call edges from this function, sorted by their return + /// PC addresses (in increasing order). + //------------------------------------------------------------------ + llvm::MutableArrayRef GetCallEdges(); + + //------------------------------------------------------------------ + /// Get the outgoing tail-calling edges from this function. If none exist, + /// return None. + //------------------------------------------------------------------ + llvm::MutableArrayRef GetTailCallingEdges(); + //------------------------------------------------------------------ /// Get accessor for the block list. /// @@ -621,6 +658,10 @@ protected: Flags m_flags; uint32_t m_prologue_byte_size; ///< Compute the prologue size once and cache it + + bool m_call_edges_resolved = false; ///< Whether call site info has been + /// parsed. + std::vector m_call_edges; ///< Outgoing call edges. private: DISALLOW_COPY_AND_ASSIGN(Function); }; diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/GoASTContext.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/GoASTContext.h deleted file mode 100644 index 29c8cdceacff..000000000000 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/GoASTContext.h +++ /dev/null @@ -1,421 +0,0 @@ -//===-- GoASTContext.h ------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_GoASTContext_h_ -#define liblldb_GoASTContext_h_ - -// C Includes -// C++ Includes -#include -#include -#include -#include -#include - -// Other libraries and framework includes -// Project includes -#include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/TypeSystem.h" -#include "lldb/Utility/ConstString.h" - -namespace lldb_private { - -class Declaration; -class GoType; - -class GoASTContext : public TypeSystem { -public: - GoASTContext(); - ~GoASTContext() override; - - //------------------------------------------------------------------ - // PluginInterface functions - //------------------------------------------------------------------ - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - static ConstString GetPluginNameStatic(); - - static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, - Module *module, Target *target); - - static void EnumerateSupportedLanguages( - std::set &languages_for_types, - std::set &languages_for_expressions); - - static void Initialize(); - - static void Terminate(); - - DWARFASTParser *GetDWARFParser() override; - - void SetAddressByteSize(int byte_size) { m_pointer_byte_size = byte_size; } - - //------------------------------------------------------------------ - // llvm casting support - //------------------------------------------------------------------ - static bool classof(const TypeSystem *ts) { - return ts->getKind() == TypeSystem::eKindGo; - } - - //---------------------------------------------------------------------- - // CompilerDecl functions - //---------------------------------------------------------------------- - ConstString DeclGetName(void *opaque_decl) override { return ConstString(); } - - //---------------------------------------------------------------------- - // CompilerDeclContext functions - //---------------------------------------------------------------------- - - bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override { - return false; - } - - ConstString DeclContextGetName(void *opaque_decl_ctx) override { - return ConstString(); - } - - ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override { - return ConstString(); - } - - bool - DeclContextIsClassMethod(void *opaque_decl_ctx, - lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) override { - return false; - } - - //---------------------------------------------------------------------- - // Creating Types - //---------------------------------------------------------------------- - - CompilerType CreateArrayType(const ConstString &name, - const CompilerType &element_type, - uint64_t length); - - CompilerType CreateBaseType(int go_kind, - const ConstString &type_name_const_str, - uint64_t byte_size); - - // For interface, map, chan. - CompilerType CreateTypedefType(int kind, const ConstString &name, - CompilerType impl); - - CompilerType CreateVoidType(const ConstString &name); - CompilerType CreateFunctionType(const lldb_private::ConstString &name, - CompilerType *params, size_t params_count, - bool is_variadic); - - CompilerType CreateStructType(int kind, const ConstString &name, - uint32_t byte_size); - - void CompleteStructType(const CompilerType &type); - - void AddFieldToStruct(const CompilerType &struct_type, - const ConstString &name, const CompilerType &field_type, - uint32_t byte_offset); - - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- - - static bool IsGoString(const CompilerType &type); - static bool IsGoSlice(const CompilerType &type); - static bool IsGoInterface(const CompilerType &type); - static bool IsDirectIface(uint8_t kind); - static bool IsPointerKind(uint8_t kind); - - bool IsArrayType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size, - bool *is_incomplete) override; - - bool IsAggregateType(lldb::opaque_compiler_type_t type) override; - - bool IsCharType(lldb::opaque_compiler_type_t type) override; - - bool IsCompleteType(lldb::opaque_compiler_type_t type) override; - - bool IsDefined(lldb::opaque_compiler_type_t type) override; - - bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, - bool &is_complex) override; - - bool IsFunctionType(lldb::opaque_compiler_type_t type, - bool *is_variadic_ptr = nullptr) override; - - size_t - GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, - const size_t index) override; - - bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; - - bool IsBlockPointerType(lldb::opaque_compiler_type_t type, - CompilerType *function_pointer_type_ptr) override; - - bool IsIntegerType(lldb::opaque_compiler_type_t type, - bool &is_signed) override; - - bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, - CompilerType *target_type, // Can pass nullptr - bool check_cplusplus, bool check_objc) override; - - bool IsPointerType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr) override; - - bool IsScalarType(lldb::opaque_compiler_type_t type) override; - - bool IsVoidType(lldb::opaque_compiler_type_t type) override; - - bool SupportsLanguage(lldb::LanguageType language) override; - - //---------------------------------------------------------------------- - // Type Completion - //---------------------------------------------------------------------- - - bool GetCompleteType(lldb::opaque_compiler_type_t type) override; - - //---------------------------------------------------------------------- - // AST related queries - //---------------------------------------------------------------------- - - uint32_t GetPointerByteSize() override; - - //---------------------------------------------------------------------- - // Accessors - //---------------------------------------------------------------------- - - ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; - - uint32_t GetTypeInfo( - lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type = nullptr) override; - - lldb::LanguageType - GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; - - lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; - - //---------------------------------------------------------------------- - // Creating related types - //---------------------------------------------------------------------- - - CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, - uint64_t *stride = nullptr) override; - - CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; - - // Returns -1 if this isn't a function of if the function doesn't have a - // prototype Returns a value >= 0 if there is a prototype. - int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) override; - - CompilerType - GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; - - size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; - - TypeMemberFunctionImpl - GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) override; - - CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; - - //---------------------------------------------------------------------- - // Exploring the type - //---------------------------------------------------------------------- - - uint64_t GetBitSize(lldb::opaque_compiler_type_t type, - ExecutionContextScope *exe_scope) override; - - lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, - uint64_t &count) override; - - lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; - - uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) override; - - lldb::BasicType - GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; - - CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, - size_t bit_size) override; - - uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, - std::string &name, uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) override; - - uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override { - return 0; - } - - uint32_t - GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override { - return 0; - } - - CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) override { - return CompilerType(); - } - - CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) override { - return CompilerType(); - } - - CompilerType GetChildCompilerTypeAtIndex( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, - ValueObject *valobj, uint64_t &language_flags) override; - - // Lookup a child given a name. This function will match base class names and - // member member names in "clang_type" only, not descendants. - uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes) override; - - // Lookup a child member given a name. This function will match member names - // only and will descend into "clang_type" children in search for the first - // member in this class, or any base class that matches "name". - // TODO: Return all matches for a given name by returning a - // vector> - // so we catch all names that match a given child name, not just the first. - size_t - GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, - const char *name, bool omit_empty_base_classes, - std::vector &child_indexes) override; - - size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override { - return 0; - } - - //---------------------------------------------------------------------- - // Dumping types - //---------------------------------------------------------------------- - void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, lldb::Format format, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, - bool show_types, bool show_summary, bool verbose, - uint32_t depth) override; - - bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, - lldb::Format format, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) override; - - void DumpTypeDescription( - lldb::opaque_compiler_type_t type) override; // Dump to stdout - - void DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s) override; - - //---------------------------------------------------------------------- - // TODO: These methods appear unused. Should they be removed? - //---------------------------------------------------------------------- - - bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; - - void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size) override; - - // Converts "s" to a floating point value and place resulting floating point - // bytes in the "dst" buffer. - size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) override; - - //---------------------------------------------------------------------- - // TODO: Determine if these methods should move to ClangASTContext. - //---------------------------------------------------------------------- - - bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr) override; - - unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; - - bool IsCStringType(lldb::opaque_compiler_type_t type, - uint32_t &length) override; - - size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; - - CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; - - bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; - - bool IsConst(lldb::opaque_compiler_type_t type) override; - - uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, - CompilerType *base_type_ptr) override; - - bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; - - bool IsTypedefType(lldb::opaque_compiler_type_t type) override; - - // If the current object represents a typedef type, get the underlying type - CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; - - bool IsVectorType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size) override; - - CompilerType - GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; - - bool IsReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr, - bool *is_rvalue = nullptr) override; - -private: - typedef std::map> TypeMap; - int m_pointer_byte_size; - int m_int_byte_size; - std::unique_ptr m_types; - std::unique_ptr m_dwarf_ast_parser_ap; - - GoASTContext(const GoASTContext &) = delete; - const GoASTContext &operator=(const GoASTContext &) = delete; -}; - -class GoASTContextForExpr : public GoASTContext { -public: - GoASTContextForExpr(lldb::TargetSP target) : m_target_wp(target) {} - UserExpression * - GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix, - lldb::LanguageType language, - Expression::ResultType desired_type, - const EvaluateExpressionOptions &options) override; - -private: - lldb::TargetWP m_target_wp; -}; -} -#endif // liblldb_GoASTContext_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/JavaASTContext.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/JavaASTContext.h deleted file mode 100644 index 41a881dcf4eb..000000000000 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/JavaASTContext.h +++ /dev/null @@ -1,350 +0,0 @@ -//===-- JavaASTContext.h ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_JavaASTContext_h_ -#define liblldb_JavaASTContext_h_ - -// C Includes -// C++ Includes -#include -#include -#include - -// Other libraries and framework includes -// Project includes -#include "lldb/Symbol/TypeSystem.h" -#include "lldb/Utility/ConstString.h" - -namespace lldb_private { - -class JavaASTContext : public TypeSystem { -public: - class JavaType; - typedef std::map> JavaTypeMap; - - JavaASTContext(const ArchSpec &arch); - ~JavaASTContext() override; - - //------------------------------------------------------------------ - // PluginInterface functions - //------------------------------------------------------------------ - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - static ConstString GetPluginNameStatic(); - - static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, - Module *module, Target *target); - - static void EnumerateSupportedLanguages( - std::set &languages_for_types, - std::set &languages_for_expressions); - - static void Initialize(); - - static void Terminate(); - - DWARFASTParser *GetDWARFParser() override; - - uint32_t GetPointerByteSize() override; - - //---------------------------------------------------------------------- - // CompilerDecl functions - //---------------------------------------------------------------------- - ConstString DeclGetName(void *opaque_decl) override; - - //---------------------------------------------------------------------- - // CompilerDeclContext functions - //---------------------------------------------------------------------- - - std::vector - DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, - const bool ignore_imported_decls) override; - - bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override; - - ConstString DeclContextGetName(void *opaque_decl_ctx) override; - - bool DeclContextIsClassMethod(void *opaque_decl_ctx, - lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) override; - - //---------------------------------------------------------------------- - // Tests - //---------------------------------------------------------------------- - - bool IsArrayType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size, - bool *is_incomplete) override; - - bool IsAggregateType(lldb::opaque_compiler_type_t type) override; - - bool IsCharType(lldb::opaque_compiler_type_t type) override; - - bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, - bool &is_complex) override; - - bool IsFunctionType(lldb::opaque_compiler_type_t type, - bool *is_variadic_ptr = nullptr) override; - - size_t - GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, - const size_t index) override; - - bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; - - bool IsBlockPointerType(lldb::opaque_compiler_type_t type, - CompilerType *function_pointer_type_ptr) override; - - bool IsIntegerType(lldb::opaque_compiler_type_t type, - bool &is_signed) override; - - bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, - CompilerType *target_type, bool check_cplusplus, - bool check_objc) override; - - bool IsPointerType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr) override; - - bool IsReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr, - bool *is_rvalue = nullptr) override; - - bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr) override; - - bool IsScalarType(lldb::opaque_compiler_type_t type) override; - - bool IsVoidType(lldb::opaque_compiler_type_t type) override; - - bool IsCStringType(lldb::opaque_compiler_type_t type, - uint32_t &length) override; - - bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; - - bool IsTypedefType(lldb::opaque_compiler_type_t type) override; - - bool IsVectorType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size) override; - - bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; - - bool IsCompleteType(lldb::opaque_compiler_type_t type) override; - - bool IsConst(lldb::opaque_compiler_type_t type) override; - - bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; - - bool IsDefined(lldb::opaque_compiler_type_t type) override; - - uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, - CompilerType *base_type_ptr) override; - - bool SupportsLanguage(lldb::LanguageType language) override; - - bool GetCompleteType(lldb::opaque_compiler_type_t type) override; - - ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; - - uint32_t GetTypeInfo( - lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type = nullptr) override; - - lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; - - lldb::LanguageType - GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; - - CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, - uint64_t *stride = nullptr) override; - - CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; - - CompilerType - GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; - - CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, - size_t bit_size) override; - - size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; - - lldb::BasicType - GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; - - uint64_t GetBitSize(lldb::opaque_compiler_type_t type, - ExecutionContextScope *exe_scope) override; - - lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, - uint64_t &count) override; - - lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; - - unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; - - size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; - - int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) override; - - CompilerType - GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; - - size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; - - TypeMemberFunctionImpl - GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) override; - - uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, - std::string &name, uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) override; - - uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) override; - - uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override; - - uint32_t GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override; - - CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) override; - - CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) override; - - size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) override; - - void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, lldb::Format format, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, - bool show_types, bool show_summary, bool verbose, - uint32_t depth) override; - - bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, - lldb::Format format, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) override; - - void DumpTypeDescription(lldb::opaque_compiler_type_t type) override; - - void DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s) override; - - void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size) override; - - CompilerType GetChildCompilerTypeAtIndex( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, - ValueObject *valobj, uint64_t &language_flags) override; - - uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes) override; - - size_t - GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, - const char *name, bool omit_empty_base_classes, - std::vector &child_indexes) override; - - CompilerType - GetLValueReferenceType(lldb::opaque_compiler_type_t type) override; - - ConstString DeclContextGetScopeQualifiedName( - lldb::opaque_compiler_type_t opaque_decl_ctx) override; - - CompilerType CreateBaseType(const ConstString &name); - - CompilerType CreateObjectType(const ConstString &name, - const ConstString &linkage_name, - uint32_t byte_size); - - CompilerType CreateArrayType(const ConstString &linkage_name, - const CompilerType &element_type, - const DWARFExpression &length_expression, - const lldb::addr_t data_offset); - - CompilerType CreateReferenceType(const CompilerType &pointee_type); - - void CompleteObjectType(const CompilerType &object_type); - - void AddBaseClassToObject(const CompilerType &object_type, - const CompilerType &member_type, - uint32_t member_offset); - - void AddMemberToObject(const CompilerType &object_type, - const ConstString &name, - const CompilerType &member_type, - uint32_t member_offset); - - void SetDynamicTypeId(const CompilerType &type, - const DWARFExpression &type_id); - - static uint64_t CalculateDynamicTypeId(ExecutionContext *exe_ctx, - const CompilerType &type, - ValueObject &in_value); - - static ConstString GetLinkageName(const CompilerType &type); - - static uint32_t CalculateArraySize(const CompilerType &type, - ValueObject &in_value); - - static uint64_t CalculateArrayElementOffset(const CompilerType &type, - size_t index); - - //------------------------------------------------------------------ - // llvm casting support - //------------------------------------------------------------------ - static bool classof(const TypeSystem *ts) { - return ts->getKind() == TypeSystem::eKindJava; - } - -private: - uint32_t m_pointer_byte_size; - std::unique_ptr m_dwarf_ast_parser_ap; - JavaTypeMap m_array_type_map; - JavaTypeMap m_base_type_map; - JavaTypeMap m_reference_type_map; - JavaTypeMap m_object_type_map; - - JavaASTContext(const JavaASTContext &) = delete; - const JavaASTContext &operator=(const JavaASTContext &) = delete; -}; -} -#endif // liblldb_JavaASTContext_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/LineTable.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/LineTable.h index fe8be0c55764..684972d50789 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/LineTable.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/LineTable.h @@ -10,12 +10,8 @@ #ifndef liblldb_LineTable_h_ #define liblldb_LineTable_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/ModuleChild.h" #include "lldb/Core/RangeMap.h" #include "lldb/Core/Section.h" @@ -242,21 +238,22 @@ public: protected: struct Entry { Entry() - : file_addr(LLDB_INVALID_ADDRESS), line(0), column(0), file_idx(0), + : file_addr(LLDB_INVALID_ADDRESS), line(0), is_start_of_statement(false), is_start_of_basic_block(false), is_prologue_end(false), is_epilogue_begin(false), - is_terminal_entry(false) {} + is_terminal_entry(false), column(0), file_idx(0) {} Entry(lldb::addr_t _file_addr, uint32_t _line, uint16_t _column, uint16_t _file_idx, bool _is_start_of_statement, bool _is_start_of_basic_block, bool _is_prologue_end, bool _is_epilogue_begin, bool _is_terminal_entry) - : file_addr(_file_addr), line(_line), column(_column), - file_idx(_file_idx), is_start_of_statement(_is_start_of_statement), + : file_addr(_file_addr), line(_line), + is_start_of_statement(_is_start_of_statement), is_start_of_basic_block(_is_start_of_basic_block), is_prologue_end(_is_prologue_end), is_epilogue_begin(_is_epilogue_begin), - is_terminal_entry(_is_terminal_entry) {} + is_terminal_entry(_is_terminal_entry), column(_column), + file_idx(_file_idx) {} int bsearch_compare(const void *key, const void *arrmem); @@ -310,26 +307,30 @@ protected: //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ - lldb::addr_t file_addr; ///< The file address for this line entry - uint32_t line; ///< The source line number, or zero if there is no line - ///number information. - uint16_t column; ///< The column number of the source line, or zero if there - ///is no column information. - uint16_t file_idx : 11, ///< The file index into CompileUnit's file table, - ///or zero if there is no file information. - is_start_of_statement : 1, ///< Indicates this entry is the beginning of - ///a statement. - is_start_of_basic_block : 1, ///< Indicates this entry is the beginning - ///of a basic block. - is_prologue_end : 1, ///< Indicates this entry is one (of possibly many) - ///where execution should be suspended for an entry - ///breakpoint of a function. - is_epilogue_begin : 1, ///< Indicates this entry is one (of possibly - ///many) where execution should be suspended for - ///an exit breakpoint of a function. - is_terminal_entry : 1; ///< Indicates this entry is that of the first - ///byte after the end of a sequence of target - ///machine instructions. + /// The file address for this line entry. + lldb::addr_t file_addr; + /// The source line number, or zero if there is no line number + /// information. + uint32_t line : 27; + /// Indicates this entry is the beginning of a statement. + uint32_t is_start_of_statement : 1; + /// Indicates this entry is the beginning of a basic block. + uint32_t is_start_of_basic_block : 1; + /// Indicates this entry is one (of possibly many) where execution + /// should be suspended for an entry breakpoint of a function. + uint32_t is_prologue_end : 1; + /// Indicates this entry is one (of possibly many) where execution + /// should be suspended for an exit breakpoint of a function. + uint32_t is_epilogue_begin : 1; + /// Indicates this entry is that of the first byte after the end + /// of a sequence of target machine instructions. + uint32_t is_terminal_entry : 1; + /// The column number of the source line, or zero if there is no + /// column information. + uint16_t column; + /// The file index into CompileUnit's file table, or zero if there + /// is no file information. + uint16_t file_idx; }; struct EntrySearchInfo { diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/OCamlASTContext.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/OCamlASTContext.h deleted file mode 100644 index 7144886e1c75..000000000000 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/OCamlASTContext.h +++ /dev/null @@ -1,318 +0,0 @@ -//===-- OCamlASTContext.h ------------------------------------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_OCamlASTContext_h_ -#define liblldb_OCamlASTContext_h_ - -// C Includes -// C++ Includes -#include -#include -#include -#include -#include - -// Other libraries and framework includes -// Project includes -#include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/TypeSystem.h" -#include "lldb/Utility/ConstString.h" - -namespace lldb_private { - -class OCamlASTContext : public TypeSystem { -public: - class OCamlType; - typedef std::map> OCamlTypeMap; - - OCamlASTContext(); - ~OCamlASTContext() override; - - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - static ConstString GetPluginNameStatic(); - - static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, - Module *module, Target *target); - - static void EnumerateSupportedLanguages( - std::set &languages_for_types, - std::set &languages_for_expressions); - - static void Initialize(); - - static void Terminate(); - - DWARFASTParser *GetDWARFParser() override; - - void SetAddressByteSize(int byte_size) { m_pointer_byte_size = byte_size; } - - static bool classof(const TypeSystem *ts) { - return ts->getKind() == TypeSystem::eKindOCaml; - } - - ConstString DeclGetName(void *opaque_decl) override { return ConstString(); } - - bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override { - return false; - } - - ConstString DeclContextGetName(void *opaque_decl_ctx) override { - return ConstString(); - } - - ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override { - return ConstString(); - } - - bool - DeclContextIsClassMethod(void *opaque_decl_ctx, - lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, - ConstString *language_object_name_ptr) override { - return false; - } - - bool SupportsLanguage(lldb::LanguageType language) override; - uint32_t GetPointerByteSize() override; - - bool IsArrayType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size, - bool *is_incomplete) override; - - bool IsAggregateType(lldb::opaque_compiler_type_t type) override; - - bool IsCharType(lldb::opaque_compiler_type_t type) override; - - bool IsCompleteType(lldb::opaque_compiler_type_t type) override; - - bool IsDefined(lldb::opaque_compiler_type_t type) override; - - bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, - bool &is_complex) override; - - bool IsFunctionType(lldb::opaque_compiler_type_t type, - bool *is_variadic_ptr = nullptr) override; - - size_t - GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, - const size_t index) override; - - bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; - - bool IsBlockPointerType(lldb::opaque_compiler_type_t type, - CompilerType *function_pointer_type_ptr) override; - - bool IsIntegerType(lldb::opaque_compiler_type_t type, - bool &is_signed) override; - - bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, - CompilerType *target_type, bool check_cplusplus, - bool check_objc) override; - - bool IsPointerType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr) override; - - bool IsScalarType(lldb::opaque_compiler_type_t type) override; - - bool IsVoidType(lldb::opaque_compiler_type_t type) override; - - bool GetCompleteType(lldb::opaque_compiler_type_t type) override; - - ConstString GetTypeName(lldb::opaque_compiler_type_t type) override; - - uint32_t GetTypeInfo( - lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type = nullptr) override; - - lldb::LanguageType - GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; - - lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override; - - CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type, - uint64_t *stride = nullptr) override; - - CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override; - - int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) override; - - CompilerType - GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; - - size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; - - TypeMemberFunctionImpl - GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) override; - - CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override; - - uint64_t GetBitSize(lldb::opaque_compiler_type_t type, - ExecutionContextScope *exe_scope) override; - - lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type, - uint64_t &count) override; - - lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override; - - uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) override; - - lldb::BasicType - GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; - - CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, - size_t bit_size) override; - - uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override; - - CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, - std::string &name, uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) override; - - uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override { - return 0; - } - - uint32_t - GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override { - return 0; - } - - CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) override { - return CompilerType(); - } - - CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, - uint32_t *bit_offset_ptr) override { - return CompilerType(); - } - - CompilerType GetChildCompilerTypeAtIndex( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, - ValueObject *valobj, uint64_t &language_flags) override; - - uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes) override; - - size_t - GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, - const char *name, bool omit_empty_base_classes, - std::vector &child_indexes) override; - - size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override { - return 0; - } - - void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, lldb::Format format, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, - bool show_types, bool show_summary, bool verbose, - uint32_t depth) override; - - bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, - lldb::Format format, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) override; - - void DumpTypeDescription(lldb::opaque_compiler_type_t type) override; - - void DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s) override; - - bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; - - void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, - Stream *s, const DataExtractor &data, - lldb::offset_t data_offset, size_t data_byte_size) override; - - size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) override; - - bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr) override; - - unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; - - bool IsCStringType(lldb::opaque_compiler_type_t type, - uint32_t &length) override; - - size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; - - CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override; - - bool IsBeingDefined(lldb::opaque_compiler_type_t type) override; - - bool IsConst(lldb::opaque_compiler_type_t type) override; - - uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, - CompilerType *base_type_ptr) override; - - bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; - - bool IsTypedefType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override; - - bool IsVectorType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size) override; - - CompilerType - GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; - - CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override; - - bool IsReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type = nullptr, - bool *is_rvalue = nullptr) override; - - CompilerType CreateBaseType(const ConstString &name, uint64_t); - -private: - int m_pointer_byte_size; - std::unique_ptr m_dwarf_ast_parser_ap; - OCamlTypeMap m_base_type_map; - - OCamlASTContext(const OCamlASTContext &) = delete; - const OCamlASTContext &operator=(const OCamlASTContext &) = delete; -}; - -class OCamlASTContextForExpr : public OCamlASTContext { -public: - OCamlASTContextForExpr(lldb::TargetSP target) : m_target_wp(target) {} - -private: - lldb::TargetWP m_target_wp; -}; -} -#endif // liblldb_OCamlASTContext_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/ObjectContainer.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/ObjectContainer.h index 2138d22808c3..1e14856ea6ea 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/ObjectContainer.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/ObjectContainer.h @@ -10,10 +10,6 @@ #ifndef liblldb_ObjectContainer_h_ #define liblldb_ObjectContainer_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Utility/DataExtractor.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/ObjectFile.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/ObjectFile.h index 1e9ae8b45417..c6bafcecb6f6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/ObjectFile.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/ObjectFile.h @@ -40,7 +40,7 @@ public: virtual void PopulateSectionList(lldb_private::ObjectFile *obj_file, lldb_private::SectionList §ion_list) = 0; - virtual bool GetArchitecture(lldb_private::ArchSpec &arch) = 0; + virtual ArchSpec GetArchitecture() = 0; }; //---------------------------------------------------------------------- @@ -305,19 +305,13 @@ public: virtual const FileSpec &GetFileSpec() const { return m_file; } //------------------------------------------------------------------ - /// Get the name of the cpu, vendor and OS for this object file. - /// - /// This value is a string that represents the target triple where the cpu - /// type, the vendor and the OS are encoded into a string. - /// - /// @param[out] target_triple - /// The string value of the target triple. + /// Get the ArchSpec for this object file. /// /// @return - /// \b True if the target triple was able to be computed, \b - /// false otherwise. + /// The ArchSpec of this object file. In case of error, an invalid + /// ArchSpec object is returned. //------------------------------------------------------------------ - virtual bool GetArchitecture(ArchSpec &arch) = 0; + virtual ArchSpec GetArchitecture() = 0; //------------------------------------------------------------------ /// Gets the section list for the currently selected architecture (and @@ -551,18 +545,16 @@ public: virtual lldb_private::Address GetEntryPointAddress() { return Address(); } //------------------------------------------------------------------ - /// Returns the address that represents the header of this object file. + /// Returns base address of this object file. /// - /// The header address is defined as where the header for the object file is - /// that describes the content of the file. If the header doesn't appear in - /// a section that is defined in the object file, an address with no section - /// is returned that has the file offset set in the m_file_offset member of - /// the lldb_private::Address object. - /// - /// @return - /// Returns the entry address for this module. + /// This also sometimes referred to as the "preferred load address" or the + /// "image base address". Addresses within object files are often expressed + /// relative to this base. If this address corresponds to a specific section + /// (usually the first byte of the first section) then the returned address + /// will have this section set. Otherwise, the address will just have the + /// offset member filled in, indicating that this represents a file address. //------------------------------------------------------------------ - virtual lldb_private::Address GetHeaderAddress() { + virtual lldb_private::Address GetBaseAddress() { return Address(m_memory_addr); } @@ -817,4 +809,16 @@ private: } // namespace lldb_private +namespace llvm { +template <> struct format_provider { + static void format(const lldb_private::ObjectFile::Type &type, + raw_ostream &OS, StringRef Style); +}; + +template <> struct format_provider { + static void format(const lldb_private::ObjectFile::Strata &strata, + raw_ostream &OS, StringRef Style); +}; +} // namespace llvm + #endif // liblldb_ObjectFile_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolContext.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolContext.h index 0ec0006f193a..a7afffb705d2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolContext.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolContext.h @@ -10,14 +10,10 @@ #ifndef liblldb_SymbolContext_h_ #define liblldb_SymbolContext_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/Address.h" #include "lldb/Core/Mangled.h" #include "lldb/Symbol/LineEntry.h" @@ -232,7 +228,7 @@ public: bool GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Status &error); - + //------------------------------------------------------------------ /// Find the best global data symbol visible from this context. /// @@ -469,10 +465,6 @@ public: bool AppendIfUnique(const SymbolContext &sc, bool merge_symbol_into_function); - bool MergeSymbolContextIntoFunctionContext(const SymbolContext &symbol_sc, - uint32_t start_idx = 0, - uint32_t stop_idx = UINT32_MAX); - uint32_t AppendIfUnique(const SymbolContextList &sc_list, bool merge_symbol_into_function); @@ -531,18 +523,6 @@ public: return m_symbol_contexts[idx]; } - //------------------------------------------------------------------ - /// Get accessor for the last symbol context in the list. - /// - /// @param[out] sc - /// A reference to the symbol context to fill in. - /// - /// @return - /// Returns \b true if \a sc was filled in, \b false if the - /// list is empty. - //------------------------------------------------------------------ - bool GetLastContext(SymbolContext &sc) const; - bool RemoveContextAtIndex(size_t idx); //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolContextScope.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolContextScope.h index c2fbb5272fc0..85718b9bba4f 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolContextScope.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolContextScope.h @@ -10,10 +10,6 @@ #ifndef liblldb_SymbolContextScope_h_ #define liblldb_SymbolContextScope_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolFile.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolFile.h index 7b77c60a3c3d..433c20da99e2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolFile.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolFile.h @@ -14,11 +14,20 @@ #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/CompilerType.h" +#include "lldb/Symbol/Function.h" #include "lldb/Symbol/Type.h" #include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" +#include + +#if defined(LLDB_CONFIGURATION_DEBUG) +#define ASSERT_MODULE_LOCK(expr) (expr->AssertModuleLock()) +#else +#define ASSERT_MODULE_LOCK(expr) ((void)0) +#endif + namespace lldb_private { class SymbolFile : public PluginInterface { @@ -92,6 +101,12 @@ public: virtual uint32_t CalculateAbilities() = 0; + //------------------------------------------------------------------ + /// Symbols file subclasses should override this to return the Module that + /// owns the TypeSystem that this symbol file modifies type information in. + //------------------------------------------------------------------ + virtual std::recursive_mutex &GetModuleMutex() const; + //------------------------------------------------------------------ /// Initialize the SymbolFile object. /// @@ -110,24 +125,38 @@ public: virtual uint32_t GetNumCompileUnits() = 0; virtual lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) = 0; - virtual lldb::LanguageType - ParseCompileUnitLanguage(const SymbolContext &sc) = 0; - virtual size_t ParseCompileUnitFunctions(const SymbolContext &sc) = 0; - virtual bool ParseCompileUnitLineTable(const SymbolContext &sc) = 0; - virtual bool ParseCompileUnitDebugMacros(const SymbolContext &sc) = 0; - virtual bool ParseCompileUnitSupportFiles(const SymbolContext &sc, - FileSpecList &support_files) = 0; - virtual bool - ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) { - return false; - } + virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) = 0; + virtual size_t ParseFunctions(CompileUnit &comp_unit) = 0; + virtual bool ParseLineTable(CompileUnit &comp_unit) = 0; + virtual bool ParseDebugMacros(CompileUnit &comp_unit) = 0; + virtual bool ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) = 0; + virtual size_t ParseTypes(CompileUnit &comp_unit) = 0; + virtual bool ParseIsOptimized(CompileUnit &comp_unit) { return false; } + virtual bool ParseImportedModules(const SymbolContext &sc, std::vector &imported_modules) = 0; - virtual size_t ParseFunctionBlocks(const SymbolContext &sc) = 0; - virtual size_t ParseTypes(const SymbolContext &sc) = 0; + virtual size_t ParseBlocksRecursive(Function &func) = 0; virtual size_t ParseVariablesForContext(const SymbolContext &sc) = 0; virtual Type *ResolveTypeUID(lldb::user_id_t type_uid) = 0; + + + /// The characteristics of an array type. + struct ArrayInfo { + int64_t first_index; + llvm::SmallVector element_orders; + uint32_t byte_stride; + uint32_t bit_stride; + }; + /// If \c type_uid points to an array type, return its characteristics. + /// To support variable-length array types, this function takes an + /// optional \p ExtecutionContext. If \c exe_ctx is non-null, the + /// dynamic characteristics for that context are returned. + virtual llvm::Optional + GetDynamicArrayInfoForUID(lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) = 0; + virtual bool CompleteType(CompilerType &compiler_type) = 0; virtual void ParseDeclsForContext(CompilerDeclContext decl_ctx) {} virtual CompilerDecl GetDeclForUID(lldb::user_id_t uid) { @@ -140,12 +169,14 @@ public: return CompilerDeclContext(); } virtual uint32_t ResolveSymbolContext(const Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, SymbolContext &sc) = 0; virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); + + virtual void DumpClangAST(Stream &s) {} virtual uint32_t FindGlobalVariables(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, @@ -155,15 +186,15 @@ public: VariableList &variables); virtual uint32_t FindFunctions(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, - bool append, SymbolContextList &sc_list); + lldb::FunctionNameType name_type_mask, + bool include_inlines, bool append, + SymbolContextList &sc_list); virtual uint32_t FindFunctions(const RegularExpression ®ex, bool include_inlines, bool append, SymbolContextList &sc_list); virtual uint32_t - FindTypes(const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + FindTypes(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); virtual size_t FindTypes(const std::vector &context, @@ -177,7 +208,7 @@ public: // types) = 0; virtual TypeList *GetTypeList(); virtual size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, lldb_private::TypeList &type_list) = 0; virtual void PreloadSymbols(); @@ -186,7 +217,7 @@ public: GetTypeSystemForLanguage(lldb::LanguageType language); virtual CompilerDeclContext - FindNamespace(const SymbolContext &sc, const ConstString &name, + FindNamespace(const ConstString &name, const CompilerDeclContext *parent_decl_ctx) { return CompilerDeclContext(); } @@ -194,6 +225,12 @@ public: ObjectFile *GetObjectFile() { return m_obj_file; } const ObjectFile *GetObjectFile() const { return m_obj_file; } + virtual std::vector ParseCallEdgesInFunction(UserID func_id) { + return {}; + } + + virtual void AddSymbols(Symtab &symtab) {} + //------------------------------------------------------------------ /// Notify the SymbolFile that the file addresses in the Sections /// for this module have been changed. @@ -203,6 +240,8 @@ public: virtual void Dump(Stream &s) {} protected: + void AssertModuleLock(); + ObjectFile *m_obj_file; // The object file that symbols can be extracted from. uint32_t m_abilities; bool m_calculated_abilities; diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolVendor.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolVendor.h index 312b146f2970..d48f646d52cd 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolVendor.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/SymbolVendor.h @@ -46,37 +46,37 @@ public: virtual void Dump(Stream *s); - virtual lldb::LanguageType ParseCompileUnitLanguage(const SymbolContext &sc); + virtual lldb::LanguageType ParseLanguage(CompileUnit &comp_unit); - virtual size_t ParseCompileUnitFunctions(const SymbolContext &sc); + virtual size_t ParseFunctions(CompileUnit &comp_unit); - virtual bool ParseCompileUnitLineTable(const SymbolContext &sc); + virtual bool ParseLineTable(CompileUnit &comp_unit); - virtual bool ParseCompileUnitDebugMacros(const SymbolContext &sc); + virtual bool ParseDebugMacros(CompileUnit &comp_unit); - virtual bool ParseCompileUnitSupportFiles(const SymbolContext &sc, - FileSpecList &support_files); + virtual bool ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files); - virtual bool ParseCompileUnitIsOptimized(const SymbolContext &sc); + virtual bool ParseIsOptimized(CompileUnit &comp_unit); + + virtual size_t ParseTypes(CompileUnit &comp_unit); virtual bool ParseImportedModules(const SymbolContext &sc, std::vector &imported_modules); - virtual size_t ParseFunctionBlocks(const SymbolContext &sc); - - virtual size_t ParseTypes(const SymbolContext &sc); + virtual size_t ParseBlocksRecursive(Function &func); virtual size_t ParseVariablesForContext(const SymbolContext &sc); virtual Type *ResolveTypeUID(lldb::user_id_t type_uid); virtual uint32_t ResolveSymbolContext(const Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, SymbolContext &sc); virtual uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list); virtual size_t FindGlobalVariables(const ConstString &name, @@ -90,17 +90,17 @@ public: virtual size_t FindFunctions(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, - bool append, SymbolContextList &sc_list); + lldb::FunctionNameType name_type_mask, + bool include_inlines, bool append, + SymbolContextList &sc_list); virtual size_t FindFunctions(const RegularExpression ®ex, bool include_inlines, bool append, SymbolContextList &sc_list); virtual size_t - FindTypes(const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - size_t max_matches, + FindTypes(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); @@ -108,7 +108,7 @@ public: bool append, TypeMap &types); virtual CompilerDeclContext - FindNamespace(const SymbolContext &sc, const ConstString &name, + FindNamespace(const ConstString &name, const CompilerDeclContext *parent_decl_ctx); virtual size_t GetNumCompileUnits(); @@ -122,8 +122,8 @@ public: const TypeList &GetTypeList() const { return m_type_list; } - virtual size_t GetTypes(SymbolContextScope *sc_scope, uint32_t type_mask, - TypeList &type_list); + virtual size_t GetTypes(SymbolContextScope *sc_scope, + lldb::TypeClass type_mask, TypeList &type_list); SymbolFile *GetSymbolFile() { return m_sym_file_ap.get(); } @@ -164,6 +164,8 @@ protected: // file) std::unique_ptr m_sym_file_ap; // A single symbol file. Subclasses // can add more of these if needed. + Symtab *m_symtab; // Save a symtab once to not pass it through `AddSymbols` of + // the symbol file each time when it is needed private: //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h index 3d24862af365..286e4f48c2e8 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/Symtab.h @@ -168,12 +168,12 @@ private: Visibility symbol_visibility) const { switch (symbol_debug_type) { case eDebugNo: - if (m_symbols[idx].IsDebug() == true) + if (m_symbols[idx].IsDebug()) return false; break; case eDebugYes: - if (m_symbols[idx].IsDebug() == false) + if (!m_symbols[idx].IsDebug()) return false; break; @@ -197,6 +197,15 @@ private: void SymbolIndicesToSymbolContextList(std::vector &symbol_indexes, SymbolContextList &sc_list); + void RegisterMangledNameEntry( + NameToIndexMap::Entry &entry, std::set &class_contexts, + std::vector> &backlog, + RichManglingContext &rmc); + + void RegisterBacklogEntry(const NameToIndexMap::Entry &entry, + const char *decl_context, + const std::set &class_contexts); + DISALLOW_COPY_AND_ASSIGN(Symtab); }; diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/TypeSystem.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/TypeSystem.h index 94d1b9cdf3fd..6afbd188a234 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/TypeSystem.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/TypeSystem.h @@ -10,18 +10,14 @@ #ifndef liblldb_TypeSystem_h_ #define liblldb_TypeSystem_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes #include "llvm/ADT/APSInt.h" #include "llvm/Support/Casting.h" -// Project includes #include "lldb/Core/PluginInterface.h" #include "lldb/Expression/Expression.h" #include "lldb/Symbol/CompilerDecl.h" @@ -72,8 +68,6 @@ public: enum LLVMCastKind { eKindClang, eKindSwift, - eKindGo, - eKindJava, eKindOCaml, kNumKinds }; @@ -286,7 +280,8 @@ public: virtual lldb::Format GetFormat(lldb::opaque_compiler_type_t type) = 0; virtual uint32_t GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) = 0; + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) = 0; virtual CompilerType GetBuiltinTypeByName(const ConstString &name); @@ -347,7 +342,7 @@ public: const char *name, bool omit_empty_base_classes, std::vector &child_indexes) = 0; - virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) = 0; + virtual size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type); virtual lldb::TemplateArgumentKind GetTemplateArgumentKind(lldb::opaque_compiler_type_t type, size_t idx); diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/UnwindPlan.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/UnwindPlan.h index a76ea23b46bc..7a5cf7f02a67 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/UnwindPlan.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/UnwindPlan.h @@ -10,14 +10,10 @@ #ifndef liblldb_UnwindPlan_h #define liblldb_UnwindPlan_h -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/AddressRange.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Stream.h" @@ -28,14 +24,22 @@ namespace lldb_private { // The UnwindPlan object specifies how to unwind out of a function - where this // function saves the caller's register values before modifying them (for non- // volatile aka saved registers) and how to find this frame's Canonical Frame -// Address (CFA). +// Address (CFA) or Aligned Frame Address (AFA). +// CFA is a DWARF's Canonical Frame Address. // Most commonly, registers are saved on the stack, offset some bytes from the // Canonical Frame Address, or CFA, which is the starting address of this // function's stack frame (the CFA is same as the eh_frame's CFA, whatever that // may be on a given architecture). The CFA address for the stack frame does // not change during the lifetime of the function. +// AFA is an artificially introduced Aligned Frame Address. +// It is used only for stack frames with realignment (e.g. when some of the +// locals has an alignment requirement higher than the stack alignment right +// after the function call). It is used to access register values saved on the +// stack after the realignment (and so they are inaccessible through the CFA). +// AFA usually equals the stack pointer value right after the realignment. + // Internally, the UnwindPlan is structured as a vector of register locations // organized by code address in the function, showing which registers have been // saved at that point and where they are saved. It can be thought of as the @@ -61,6 +65,8 @@ public: same, // reg is unchanged atCFAPlusOffset, // reg = deref(CFA + offset) isCFAPlusOffset, // reg = CFA + offset + atAFAPlusOffset, // reg = deref(AFA + offset) + isAFAPlusOffset, // reg = AFA + offset inOtherRegister, // reg = other reg atDWARFExpression, // reg = deref(eval(dwarf_expr)) isDWARFExpression // reg = eval(dwarf_expr) @@ -90,6 +96,10 @@ public: bool IsAtCFAPlusOffset() const { return m_type == atCFAPlusOffset; } + bool IsAFAPlusOffset() const { return m_type == isAFAPlusOffset; } + + bool IsAtAFAPlusOffset() const { return m_type == atAFAPlusOffset; } + bool IsInOtherRegister() const { return m_type == inOtherRegister; } bool IsAtDWARFExpression() const { return m_type == atDWARFExpression; } @@ -106,6 +116,16 @@ public: m_location.offset = offset; } + void SetAtAFAPlusOffset(int32_t offset) { + m_type = atAFAPlusOffset; + m_location.offset = offset; + } + + void SetIsAFAPlusOffset(int32_t offset) { + m_type = isAFAPlusOffset; + m_location.offset = offset; + } + void SetInRegister(uint32_t reg_num) { m_type = inOtherRegister; m_location.reg_num = reg_num; @@ -120,9 +140,16 @@ public: RestoreType GetLocationType() const { return m_type; } int32_t GetOffset() const { - if (m_type == atCFAPlusOffset || m_type == isCFAPlusOffset) + switch(m_type) + { + case atCFAPlusOffset: + case isCFAPlusOffset: + case atAFAPlusOffset: + case isAFAPlusOffset: return m_location.offset; - return 0; + default: + return 0; + } } void GetDWARFExpr(const uint8_t **opcodes, uint16_t &len) const { @@ -169,20 +196,20 @@ public: } m_location; }; - class CFAValue { + class FAValue { public: enum ValueType { unspecified, // not specified - isRegisterPlusOffset, // CFA = register + offset - isRegisterDereferenced, // CFA = [reg] - isDWARFExpression // CFA = eval(dwarf_expr) + isRegisterPlusOffset, // FA = register + offset + isRegisterDereferenced, // FA = [reg] + isDWARFExpression // FA = eval(dwarf_expr) }; - CFAValue() : m_type(unspecified), m_value() {} + FAValue() : m_type(unspecified), m_value() {} - bool operator==(const CFAValue &rhs) const; + bool operator==(const FAValue &rhs) const; - bool operator!=(const CFAValue &rhs) const { return !(*this == rhs); } + bool operator!=(const FAValue &rhs) const { return !(*this == rhs); } void SetUnspecified() { m_type = unspecified; } @@ -279,7 +306,7 @@ public: uint16_t length; } expr; } m_value; - }; // class CFAValue + }; // class FAValue public: Row(); @@ -302,7 +329,9 @@ public: void SlideOffset(lldb::addr_t offset) { m_offset += offset; } - CFAValue &GetCFAValue() { return m_cfa_value; } + FAValue &GetCFAValue() { return m_cfa_value; } + + FAValue &GetAFAValue() { return m_afa_value; } bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace); @@ -329,7 +358,8 @@ public: typedef std::map collection; lldb::addr_t m_offset; // Offset into the function for this row - CFAValue m_cfa_value; + FAValue m_cfa_value; + FAValue m_afa_value; collection m_register_locations; }; // class Row diff --git a/contrib/llvm/tools/lldb/include/lldb/Symbol/UnwindTable.h b/contrib/llvm/tools/lldb/include/lldb/Symbol/UnwindTable.h index 5c83e3003192..061e7ddc0f99 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Symbol/UnwindTable.h +++ b/contrib/llvm/tools/lldb/include/lldb/Symbol/UnwindTable.h @@ -50,7 +50,7 @@ public: GetUncachedFuncUnwindersContainingAddress(const Address &addr, SymbolContext &sc); - bool GetArchitecture(lldb_private::ArchSpec &arch); + ArchSpec GetArchitecture(); private: void Dump(Stream &s); diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ABI.h b/contrib/llvm/tools/lldb/include/lldb/Target/ABI.h index 343b3a749597..24fff1caf6c4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ABI.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ABI.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABI_h_ #define liblldb_ABI_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Utility/Status.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/CPPLanguageRuntime.h b/contrib/llvm/tools/lldb/include/lldb/Target/CPPLanguageRuntime.h index aae85f420ef7..e96ee168389b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/CPPLanguageRuntime.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/CPPLanguageRuntime.h @@ -11,11 +11,7 @@ #ifndef liblldb_CPPLanguageRuntime_h_ #define liblldb_CPPLanguageRuntime_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/PluginInterface.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/lldb-private.h" @@ -24,6 +20,25 @@ namespace lldb_private { class CPPLanguageRuntime : public LanguageRuntime { public: + enum class LibCppStdFunctionCallableCase { + Lambda = 0, + CallableObject, + FreeOrMemberFunction, + Invalid + }; + + struct LibCppStdFunctionCallableInfo { + Symbol callable_symbol; + Address callable_address; + LineEntry callable_line_entry; + lldb::addr_t member__f_pointer_value = 0u; + LibCppStdFunctionCallableCase callable_case = + LibCppStdFunctionCallableCase::Invalid; + }; + + LibCppStdFunctionCallableInfo + FindLibCppStdFunctionCallableInfo(lldb::ValueObjectSP &valobj_sp); + ~CPPLanguageRuntime() override; lldb::LanguageType GetLanguageType() const override { @@ -37,6 +52,19 @@ public: bool GetObjectDescription(Stream &str, Value &value, ExecutionContextScope *exe_scope) override; + /// Obtain a ThreadPlan to get us into C++ constructs such as std::function. + /// + /// @param[in] thread + /// Curent thrad of execution. + /// + /// @param[in] stop_others + /// True if other threads should pause during execution. + /// + /// @return + /// A ThreadPlan Shared pointer + lldb::ThreadPlanSP GetStepThroughTrampolinePlan(Thread &thread, + bool stop_others); + protected: //------------------------------------------------------------------ // Classes that inherit from CPPLanguageRuntime can see and modify these diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/DynamicLoader.h b/contrib/llvm/tools/lldb/include/lldb/Target/DynamicLoader.h index de9c4e233b0c..fe04f94aa31b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/DynamicLoader.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/DynamicLoader.h @@ -10,18 +10,17 @@ #ifndef liblldb_DynamicLoader_h_ #define liblldb_DynamicLoader_h_ -// Project includes #include "lldb/Core/PluginInterface.h" -#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/UUID.h" -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-forward.h" // for ModuleSP, ThreadPlanSP -#include "lldb/lldb-private-enumerations.h" // for LazyBool, LazyBool::eLaz... -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" -#include // for size_t -#include // for int64_t +#include +#include namespace lldb_private { class ModuleList; } diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ExecutionContext.h b/contrib/llvm/tools/lldb/include/lldb/Target/ExecutionContext.h index 70eba3654dec..167189c3a837 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ExecutionContext.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ExecutionContext.h @@ -10,12 +10,8 @@ #ifndef liblldb_ExecutionContext_h_ #define liblldb_ExecutionContext_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/StackID.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ExecutionContextScope.h b/contrib/llvm/tools/lldb/include/lldb/Target/ExecutionContextScope.h index b73ca576bd8a..3e787584be0b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ExecutionContextScope.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ExecutionContextScope.h @@ -10,10 +10,6 @@ #ifndef liblldb_ExecutionContextScope_h_ #define liblldb_ExecutionContextScope_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/InstrumentationRuntime.h b/contrib/llvm/tools/lldb/include/lldb/Target/InstrumentationRuntime.h index 21d66d5766a9..ba905cb8535d 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/InstrumentationRuntime.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/InstrumentationRuntime.h @@ -10,13 +10,9 @@ #ifndef liblldb_InstrumentationRuntime_h_ #define liblldb_InstrumentationRuntime_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/PluginInterface.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-forward.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h b/contrib/llvm/tools/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h index b11231960ac1..7c72c9524eca 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/InstrumentationRuntimeStopInfo.h @@ -10,12 +10,8 @@ #ifndef liblldb_InstrumentationRuntimeStopInfo_h_ #define liblldb_InstrumentationRuntimeStopInfo_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/StopInfo.h" #include "lldb/Utility/StructuredData.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/Language.h b/contrib/llvm/tools/lldb/include/lldb/Target/Language.h index dd7db26f3ba6..27f40fd1ba83 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/Language.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/Language.h @@ -11,15 +11,12 @@ #ifndef liblldb_Language_h_ #define liblldb_Language_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes +#include "lldb/Core/Highlighter.h" #include "lldb/Core/PluginInterface.h" #include "lldb/DataFormatters/DumpValueObjectOptions.h" #include "lldb/DataFormatters/FormatClasses.h" @@ -152,6 +149,13 @@ public: static Language *FindPlugin(lldb::LanguageType language); + /// Returns the Language associated with the given file path or a nullptr + /// if there is no known language. + static Language *FindPlugin(llvm::StringRef file_path); + + static Language *FindPlugin(lldb::LanguageType language, + llvm::StringRef file_path); + // return false from callback to stop iterating static void ForEach(std::function callback); @@ -159,6 +163,10 @@ public: virtual bool IsTopLevelFunction(Function &function); + virtual bool IsSourceFile(llvm::StringRef file_path) const = 0; + + virtual const Highlighter *GetHighlighter() const { return nullptr; } + virtual lldb::TypeCategoryImplSP GetFormatters(); virtual HardcodedFormatters::HardcodedFormatFinder GetHardcodedFormats(); diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/LanguageRuntime.h b/contrib/llvm/tools/lldb/include/lldb/Target/LanguageRuntime.h index 6537a8f6dd55..2a2f47b85359 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/LanguageRuntime.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/LanguageRuntime.h @@ -11,10 +11,6 @@ #ifndef liblldb_LanguageRuntime_h_ #define liblldb_LanguageRuntime_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Breakpoint/BreakpointResolverName.h" #include "lldb/Core/PluginInterface.h" @@ -123,6 +119,17 @@ public: static Breakpoint::BreakpointPreconditionSP CreateExceptionPrecondition(lldb::LanguageType language, bool catch_bp, bool throw_bp); + + virtual lldb::ValueObjectSP GetExceptionObjectForThread( + lldb::ThreadSP thread_sp) { + return lldb::ValueObjectSP(); + } + + virtual lldb::ThreadSP GetBacktraceThreadFromException( + lldb::ValueObjectSP thread_sp) { + return lldb::ThreadSP(); + } + Process *GetProcess() { return m_process; } Target &GetTargetRef() { return m_process->GetTarget(); } diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/Memory.h b/contrib/llvm/tools/lldb/include/lldb/Target/Memory.h index 16d7b256a78e..d5e6c105f76d 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/Memory.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/Memory.h @@ -10,15 +10,11 @@ #ifndef liblldb_Memory_h_ #define liblldb_Memory_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/RangeMap.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/MemoryHistory.h b/contrib/llvm/tools/lldb/include/lldb/Target/MemoryHistory.h index acc36ffe2eb4..cb3e90053357 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/MemoryHistory.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/MemoryHistory.h @@ -11,12 +11,8 @@ #ifndef liblldb_MemoryHistory_h_ #define liblldb_MemoryHistory_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/PluginInterface.h" #include "lldb/lldb-private.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/MemoryRegionInfo.h b/contrib/llvm/tools/lldb/include/lldb/Target/MemoryRegionInfo.h index 505ecfcfc5ae..a57c4678bb37 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/MemoryRegionInfo.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/MemoryRegionInfo.h @@ -14,7 +14,6 @@ #include "lldb/Core/RangeMap.h" #include "llvm/Support/FormatProviders.h" #include "lldb/Utility/ConstString.h" -#include "lldb/Utility/Range.h" namespace lldb_private { class MemoryRegionInfo { @@ -109,6 +108,26 @@ protected: OptionalBool m_flash; lldb::offset_t m_blocksize; }; + +inline bool operator<(const MemoryRegionInfo &lhs, + const MemoryRegionInfo &rhs) { + return lhs.GetRange() < rhs.GetRange(); +} + +inline bool operator<(const MemoryRegionInfo &lhs, lldb::addr_t rhs) { + return lhs.GetRange().GetRangeBase() < rhs; +} + +inline bool operator<(lldb::addr_t lhs, const MemoryRegionInfo &rhs) { + return lhs < rhs.GetRange().GetRangeBase(); +} + +// Forward-declarable wrapper. +class MemoryRegionInfos : public std::vector { +public: + using std::vector::vector; +}; + } namespace llvm { diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ObjCLanguageRuntime.h b/contrib/llvm/tools/lldb/include/lldb/Target/ObjCLanguageRuntime.h index 6f8354ea3a27..9eebf9463043 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ObjCLanguageRuntime.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ObjCLanguageRuntime.h @@ -10,17 +10,13 @@ #ifndef liblldb_ObjCLanguageRuntime_h_ #define liblldb_ObjCLanguageRuntime_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes #include "llvm/Support/Casting.h" -// Project includes #include "lldb/Core/PluginInterface.h" #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Symbol/CompilerType.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/OperatingSystem.h b/contrib/llvm/tools/lldb/include/lldb/Target/OperatingSystem.h index fe4fdee182f4..4d73bb3906ee 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/OperatingSystem.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/OperatingSystem.h @@ -11,9 +11,6 @@ #ifndef liblldb_OperatingSystem_h_ #define liblldb_OperatingSystem_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "lldb/Core/PluginInterface.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/PathMappingList.h b/contrib/llvm/tools/lldb/include/lldb/Target/PathMappingList.h index a5ee3265a223..29e6ef191e27 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/PathMappingList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/PathMappingList.h @@ -10,14 +10,10 @@ #ifndef liblldb_PathMappingList_h_ #define liblldb_PathMappingList_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" -// Project includes namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/Platform.h b/contrib/llvm/tools/lldb/include/lldb/Target/Platform.h index 217b945d29cd..3dbeef73f0ab 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/Platform.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/Platform.h @@ -10,8 +10,6 @@ #ifndef liblldb_Platform_h_ #define liblldb_Platform_h_ -// C Includes -// C++ Includes #include #include #include @@ -19,8 +17,6 @@ #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/PluginInterface.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Interpreter/Options.h" @@ -1131,10 +1127,6 @@ public: llvm::ArrayRef GetDefinitions() override; - // Options table: Required for subclasses of Options. - - static lldb_private::OptionDefinition g_option_table[]; - // Instance variables to hold the values for command options. bool m_rsync; @@ -1160,10 +1152,6 @@ public: llvm::ArrayRef GetDefinitions() override; - // Options table: Required for subclasses of Options. - - static lldb_private::OptionDefinition g_option_table[]; - // Instance variables to hold the values for command options. bool m_ssh; @@ -1187,10 +1175,6 @@ public: llvm::ArrayRef GetDefinitions() override; - // Options table: Required for subclasses of Options. - - static lldb_private::OptionDefinition g_option_table[]; - // Instance variables to hold the values for command options. std::string m_cache_dir; diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/Process.h b/contrib/llvm/tools/lldb/include/lldb/Target/Process.h index 66ac5a692522..be72b9a9c747 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/Process.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/Process.h @@ -12,10 +12,8 @@ #include "lldb/Host/Config.h" -// C Includes #include -// C++ Includes #include #include #include @@ -24,13 +22,8 @@ #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointSiteList.h" -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/Communication.h" -#include "lldb/Core/Event.h" -#include "lldb/Core/Listener.h" #include "lldb/Core/LoadedModuleInfoList.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/ThreadSafeValue.h" @@ -47,6 +40,9 @@ #include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/Listener.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StructuredData.h" @@ -319,7 +315,7 @@ public: NameMatch process_name_match_type) : m_match_info(), m_name_match_type(process_name_match_type), m_match_all_users(false) { - m_match_info.GetExecutableFile().SetFile(process_name, false, + m_match_info.GetExecutableFile().SetFile(process_name, FileSpec::Style::native); } @@ -402,7 +398,8 @@ class ProcessModID { public: ProcessModID() : m_stop_id(0), m_last_natural_stop_id(0), m_resume_id(0), m_memory_id(0), - m_last_user_expression_resume(0), m_running_user_expression(false) {} + m_last_user_expression_resume(0), m_running_user_expression(false), + m_running_utility_function(0) {} ProcessModID(const ProcessModID &rhs) : m_stop_id(rhs.m_stop_id), m_memory_id(rhs.m_memory_id) {} @@ -431,6 +428,10 @@ public: m_last_user_expression_resume = m_resume_id; } + bool IsRunningUtilityFunction() const { + return m_running_utility_function > 0; + } + uint32_t GetStopID() const { return m_stop_id; } uint32_t GetLastNaturalStopID() const { return m_last_natural_stop_id; } uint32_t GetMemoryID() const { return m_memory_id; } @@ -467,6 +468,17 @@ public: m_running_user_expression--; } + void SetRunningUtilityFunction(bool on) { + if (on) + m_running_utility_function++; + else { + assert(m_running_utility_function > 0 && + "Called SetRunningUtilityFunction(false) without calling " + "SetRunningUtilityFunction(true) before?"); + m_running_utility_function--; + } + } + void SetStopEventForLastNaturalStopID(lldb::EventSP event_sp) { m_last_natural_stop_event = event_sp; } @@ -484,6 +496,7 @@ private: uint32_t m_memory_id; uint32_t m_last_user_expression_resume; uint32_t m_running_user_expression; + uint32_t m_running_utility_function; lldb::EventSP m_last_natural_stop_event; }; @@ -2068,7 +2081,7 @@ public: /// An error value. //------------------------------------------------------------------ virtual Status - GetMemoryRegions(std::vector ®ion_list); + GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list); virtual Status GetWatchpointSupportInfo(uint32_t &num) { Status error; @@ -2554,6 +2567,7 @@ public: virtual bool StopNoticingNewThreads() { return true; } void SetRunningUserExpression(bool on); + void SetRunningUtilityFunction(bool on); //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions @@ -3225,6 +3239,24 @@ private: DISALLOW_COPY_AND_ASSIGN(Process); }; +//------------------------------------------------------------------ +/// RAII guard that should be aquired when an utility function is called within +/// a given process. +//------------------------------------------------------------------ +class UtilityFunctionScope { + Process *m_process; + +public: + UtilityFunctionScope(Process *p) : m_process(p) { + if (m_process) + m_process->SetRunningUtilityFunction(true); + } + ~UtilityFunctionScope() { + if (m_process) + m_process->SetRunningUtilityFunction(false); + } +}; + } // namespace lldb_private #endif // liblldb_Process_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ProcessLaunchInfo.h b/contrib/llvm/tools/lldb/include/lldb/Target/ProcessLaunchInfo.h index 92c517a3e460..ef1d63035b18 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ProcessLaunchInfo.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ProcessLaunchInfo.h @@ -52,7 +52,10 @@ public: bool AppendSuppressFileAction(int fd, bool read, bool write); - void FinalizeFileActions(Target *target, bool default_to_use_pty); + // Redirect stdin/stdout/stderr to a pty, if no action for the respective file + // descriptor is specified. (So if stdin and stdout already have file actions, + // but stderr doesn't, then only stderr will be redirected to a pty.) + llvm::Error SetUpPtyRedirection(); size_t GetNumFileActions() const { return m_file_actions.size(); } @@ -131,8 +134,6 @@ public: m_listener_sp = listener_sp; } - lldb::ListenerSP GetListenerForProcess(Debugger &debugger); - lldb::ListenerSP GetHijackListener() const { return m_hijack_listener_sp; } void SetHijackListener(const lldb::ListenerSP &listener_sp) { diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ProcessStructReader.h b/contrib/llvm/tools/lldb/include/lldb/Target/ProcessStructReader.h index 8f1445ae8c1b..79f0b4cccd45 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ProcessStructReader.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ProcessStructReader.h @@ -60,18 +60,20 @@ public: return; auto size = field_type.GetByteSize(nullptr); // no support for things larger than a uint64_t (yet) - if (size > 8) + if (!size || *size > 8) return; ConstString const_name = ConstString(name.c_str()); size_t byte_index = static_cast(bit_offset / 8); m_fields[const_name] = - FieldImpl{field_type, byte_index, static_cast(size)}; + FieldImpl{field_type, byte_index, static_cast(*size)}; } - size_t total_size = struct_type.GetByteSize(nullptr); - lldb::DataBufferSP buffer_sp(new DataBufferHeap(total_size, 0)); + auto total_size = struct_type.GetByteSize(nullptr); + if (!total_size) + return; + lldb::DataBufferSP buffer_sp(new DataBufferHeap(*total_size, 0)); Status error; process->ReadMemoryFromInferior(base_addr, buffer_sp->GetBytes(), - total_size, error); + *total_size, error); if (error.Fail()) return; m_data = DataExtractor(buffer_sp, m_byte_order, m_addr_byte_size); diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/QueueItem.h b/contrib/llvm/tools/lldb/include/lldb/Target/QueueItem.h index 76bcea36a2fa..3fd331ca525a 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/QueueItem.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/QueueItem.h @@ -10,14 +10,10 @@ #ifndef liblldb_QueueItem_h_ #define liblldb_QueueItem_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/RegisterContext.h b/contrib/llvm/tools/lldb/include/lldb/Target/RegisterContext.h index 73a2930fd2b5..a24c270a1e5e 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/RegisterContext.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/RegisterContext.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContext_h_ #define liblldb_RegisterContext_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ExecutionContextScope.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/SectionLoadHistory.h b/contrib/llvm/tools/lldb/include/lldb/Target/SectionLoadHistory.h index 0ed335a9d040..0a14fc05c458 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/SectionLoadHistory.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/SectionLoadHistory.h @@ -10,12 +10,9 @@ #ifndef liblldb_SectionLoadHistory_h_ #define liblldb_SectionLoadHistory_h_ -// C Includes -// C++ Includes #include #include -// Project includes #include "lldb/lldb-public.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/SectionLoadList.h b/contrib/llvm/tools/lldb/include/lldb/Target/SectionLoadList.h index 1156c686df17..2a321e7a2545 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/SectionLoadList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/SectionLoadList.h @@ -11,14 +11,10 @@ #ifndef liblldb_SectionLoadList_h_ #define liblldb_SectionLoadList_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "llvm/ADT/DenseMap.h" -// Project includes #include "lldb/Core/Section.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/StackFrame.h b/contrib/llvm/tools/lldb/include/lldb/Target/StackFrame.h index ce9b16227672..a4e31a567440 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/StackFrame.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/StackFrame.h @@ -10,20 +10,16 @@ #ifndef liblldb_StackFrame_h_ #define liblldb_StackFrame_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Flags.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/StackID.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UserID.h" @@ -35,9 +31,9 @@ namespace lldb_private { /// This base class provides an interface to stack frames. /// /// StackFrames may have a Canonical Frame Address (CFA) or not. -/// A frame may have a plain pc value or it may have a pc value + stop_id -/// to indicate a specific point in the debug session so the correct section -/// load list is used for symbolication. +/// A frame may have a plain pc value or it may indicate a specific point in +/// the debug session so the correct section load list is used for +/// symbolication. /// /// Local variables may be available, or not. A register context may be /// available, or not. @@ -54,14 +50,27 @@ public: eExpressionPathOptionsInspectAnonymousUnions = (1u << 5) }; + enum class Kind { + /// A regular stack frame with access to registers and local variables. + Regular, + + /// A historical stack frame -- possibly without CFA or registers or + /// local variables. + History, + + /// An artificial stack frame (e.g. a synthesized result of inferring + /// missing tail call frames from a backtrace) with limited support for + /// local variables. + Artificial + }; + //------------------------------------------------------------------ /// Construct a StackFrame object without supplying a RegisterContextSP. /// /// This is the one constructor that doesn't take a RegisterContext /// parameter. This ctor may be called when creating a history StackFrame; /// these are used if we've collected a stack trace of pc addresses at some - /// point in the past. We may only have pc values. We may have pc values - /// and the stop_id when the stack trace was recorded. We may have a CFA, + /// point in the past. We may only have pc values. We may have a CFA, /// or more likely, we won't. /// /// @param [in] thread_sp @@ -92,23 +101,7 @@ public: /// @param [in] pc /// The current pc value of this stack frame. /// - /// @param [in] stop_id - /// The stop_id which should be used when looking up symbols for the pc - /// value, - /// if appropriate. This argument is ignored if stop_id_is_valid is false. - /// - /// @param [in] stop_id_is_valid - /// If the stop_id argument provided is not needed for this StackFrame, this - /// should be false. If this is a history stack frame and we know the - /// stop_id - /// when the pc value was collected, that stop_id should be provided and - /// this - /// will be true. - /// - /// @param [in] is_history_frame - /// If this is a historical stack frame -- possibly without CFA or registers - /// or - /// local variables -- then this should be set to true. + /// @param [in] frame_kind /// /// @param [in] sc_ptr /// Optionally seed the StackFrame with the SymbolContext information that @@ -117,8 +110,7 @@ public: //------------------------------------------------------------------ StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, lldb::addr_t cfa, - bool cfa_is_valid, lldb::addr_t pc, uint32_t stop_id, - bool stop_id_is_valid, bool is_history_frame, + bool cfa_is_valid, lldb::addr_t pc, Kind frame_kind, const SymbolContext *sc_ptr); StackFrame(const lldb::ThreadSP &thread_sp, lldb::user_id_t frame_idx, @@ -177,7 +169,7 @@ public: /// A SymbolContext reference which includes the types of information /// requested by resolve_scope, if they are available. //------------------------------------------------------------------ - const SymbolContext &GetSymbolContext(uint32_t resolve_scope); + const SymbolContext &GetSymbolContext(lldb::SymbolContextItem resolve_scope); //------------------------------------------------------------------ /// Return the Canonical Frame Address (DWARF term) for this frame. @@ -402,6 +394,18 @@ public: //------------------------------------------------------------------ bool IsInlined(); + //------------------------------------------------------------------ + /// Query whether this frame is part of a historical backtrace. + //------------------------------------------------------------------ + bool IsHistorical() const; + + //------------------------------------------------------------------ + /// Query whether this frame is artificial (e.g a synthesized result of + /// inferring missing tail call frames from a backtrace). Artificial frames + /// may have limited support for inspecting variables. + //------------------------------------------------------------------ + bool IsArtificial() const; + //------------------------------------------------------------------ /// Query this frame to find what frame it is in this Thread's /// StackFrameList. @@ -412,6 +416,11 @@ public: //------------------------------------------------------------------ uint32_t GetFrameIndex() const; + //------------------------------------------------------------------ + /// Set this frame's synthetic frame index. + //------------------------------------------------------------------ + void SetFrameIndex(uint32_t index) { m_frame_index = index; } + //------------------------------------------------------------------ /// Query this frame to find what frame it is in this Thread's /// StackFrameList, not counting inlined frames. @@ -503,6 +512,21 @@ public: lldb::ValueObjectSP GuessValueForRegisterAndOffset(ConstString reg, int64_t offset); + //------------------------------------------------------------------ + /// Attempt to reconstruct the ValueObject for a variable with a given \a name + /// from within the current StackFrame, within the current block. The search + /// for the variable starts in the deepest block corresponding to the current + /// PC in the stack frame and traverse through all parent blocks stopping at + /// inlined function boundaries. + /// + /// @params [in] name + /// The name of the variable. + /// + /// @return + /// The ValueObject if found. + //------------------------------------------------------------------ + lldb::ValueObjectSP FindVariable(ConstString name); + //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ @@ -516,6 +540,8 @@ public: void CalculateExecutionContext(ExecutionContext &exe_ctx) override; + lldb::RecognizedStackFrameSP GetRecognizedFrame(); + protected: friend class StackFrameList; @@ -545,14 +571,12 @@ private: Status m_frame_base_error; bool m_cfa_is_valid; // Does this frame have a CFA? Different from CFA == // LLDB_INVALID_ADDRESS - uint32_t m_stop_id; - bool m_stop_id_is_valid; // Does this frame have a stop_id? Use it when - // referring to the m_frame_code_addr. - bool m_is_history_frame; + Kind m_stack_frame_kind; lldb::VariableListSP m_variable_list_sp; ValueObjectList m_variable_list_value_objects; // Value objects for each // variable in // m_variable_list_sp + lldb::RecognizedStackFrameSP m_recognized_frame_sp; StreamString m_disassembly; std::recursive_mutex m_mutex; diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/StackFrameList.h b/contrib/llvm/tools/lldb/include/lldb/Target/StackFrameList.h index cb9fb136fb4e..0de90b3ba4ac 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/StackFrameList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/StackFrameList.h @@ -10,14 +10,10 @@ #ifndef liblldb_StackFrameList_h_ #define liblldb_StackFrameList_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/StackFrame.h" namespace lldb_private { @@ -32,22 +28,33 @@ public: ~StackFrameList(); + /// Get the number of visible frames. Frames may be created if \p can_create + /// is true. Synthetic (inline) frames expanded from the concrete frame #0 + /// (aka invisible frames) are not included in this count. uint32_t GetNumFrames(bool can_create = true); + /// Get the frame at index \p idx. Invisible frames cannot be indexed. lldb::StackFrameSP GetFrameAtIndex(uint32_t idx); + /// Get the first concrete frame with index greater than or equal to \p idx. + /// Unlike \ref GetFrameAtIndex, this cannot return a synthetic frame. lldb::StackFrameSP GetFrameWithConcreteFrameIndex(uint32_t unwind_idx); + /// Retrieve the stack frame with the given ID \p stack_id. lldb::StackFrameSP GetFrameWithStackID(const StackID &stack_id); - // Mark a stack frame as the current frame + /// Mark a stack frame as the currently selected frame and return its index. uint32_t SetSelectedFrame(lldb_private::StackFrame *frame); + /// Get the currently selected frame index. uint32_t GetSelectedFrameIndex() const; - // Mark a stack frame as the current frame using the frame index + /// Mark a stack frame as the currently selected frame using the frame index + /// \p idx. Like \ref GetFrameAtIndex, invisible frames cannot be selected. bool SetSelectedFrameByIndex(uint32_t idx); + /// If the current inline depth (i.e the number of invisible frames) is valid, + /// subtract it from \p idx. Otherwise simply return \p idx. uint32_t GetVisibleStackFrameIndex(uint32_t idx) { if (m_current_inlined_depth < UINT32_MAX) return idx - m_current_inlined_depth; @@ -55,16 +62,23 @@ public: return idx; } + /// Calculate and set the current inline depth. This may be used to update + /// the StackFrameList's set of inline frames when execution stops, e.g when + /// a breakpoint is hit. void CalculateCurrentInlinedDepth(); + /// If the currently selected frame comes from the currently selected thread, + /// point the default file and line of the thread's target to the location + /// specified by the frame. void SetDefaultFileAndLineToSelectedFrame(); + /// Clear the cache of frames. void Clear(); - void InvalidateFrames(uint32_t start_idx); - void Dump(Stream *s); + /// If \p stack_frame_ptr is contained in this StackFrameList, return its + /// wrapping shared pointer. lldb::StackFrameSP GetStackFrameSPForStackFramePtr(StackFrame *stack_frame_ptr); @@ -83,6 +97,10 @@ protected: void GetFramesUpTo(uint32_t end_idx); + void GetOnlyConcreteFramesUpTo(uint32_t end_idx, Unwind *unwinder); + + void SynthesizeTailCallFrames(StackFrame &next_frame); + bool GetAllFramesFetched() { return m_concrete_frames_fetched == UINT32_MAX; } void SetAllFramesFetched() { m_concrete_frames_fetched = UINT32_MAX; } @@ -99,15 +117,45 @@ protected: typedef collection::iterator iterator; typedef collection::const_iterator const_iterator; + /// The thread this frame list describes. Thread &m_thread; + + /// The old stack frame list. + // TODO: The old stack frame list is used to fill in missing frame info + // heuristically when it's otherwise unavailable (say, because the unwinder + // fails). We should have stronger checks to make sure that this is a valid + // source of information. lldb::StackFrameListSP m_prev_frames_sp; + + /// A mutex for this frame list. + // TODO: This mutex may not always be held when required. In particular, uses + // of the StackFrameList APIs in lldb_private::Thread look suspect. Consider + // passing around a lock_guard reference to enforce proper locking. mutable std::recursive_mutex m_mutex; + + /// A cache of frames. This may need to be updated when the program counter + /// changes. collection m_frames; + + /// The currently selected frame. uint32_t m_selected_frame_idx; + + /// The number of concrete frames fetched while filling the frame list. This + /// is only used when synthetic frames are enabled. uint32_t m_concrete_frames_fetched; + + /// The number of synthetic function activations (invisible frames) expanded + /// from the concrete frame #0 activation. + // TODO: Use an optional instead of UINT32_MAX to denote invalid values. uint32_t m_current_inlined_depth; + + /// The program counter value at the currently selected synthetic activation. + /// This is only valid if m_current_inlined_depth is valid. + // TODO: Use an optional instead of UINT32_MAX to denote invalid values. lldb::addr_t m_current_inlined_pc; - bool m_show_inlined_frames; + + /// Whether or not to show synthetic (inline) frames. Immutable. + const bool m_show_inlined_frames; private: DISALLOW_COPY_AND_ASSIGN(StackFrameList); diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/StackFrameRecognizer.h b/contrib/llvm/tools/lldb/include/lldb/Target/StackFrameRecognizer.h new file mode 100644 index 000000000000..35ec23b754f3 --- /dev/null +++ b/contrib/llvm/tools/lldb/include/lldb/Target/StackFrameRecognizer.h @@ -0,0 +1,129 @@ +//===-- StackFrameRecognizer.h ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_StackFrameRecognizer_h_ +#define liblldb_StackFrameRecognizer_h_ + +#include "lldb/Core/ValueObjectList.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-private-forward.h" +#include "lldb/lldb-public.h" + +namespace lldb_private { + +/// @class RecognizedStackFrame +/// +/// This class provides extra information about a stack frame that was +/// provided by a specific stack frame recognizer. Right now, this class only +/// holds recognized arguments (via GetRecognizedArguments). + +class RecognizedStackFrame + : public std::enable_shared_from_this { +public: + virtual lldb::ValueObjectListSP GetRecognizedArguments() { + return m_arguments; + } + virtual lldb::ValueObjectSP GetExceptionObject() { + return lldb::ValueObjectSP(); + } + virtual ~RecognizedStackFrame(){}; + +protected: + lldb::ValueObjectListSP m_arguments; +}; + +/// @class StackFrameRecognizer +/// +/// A base class for frame recognizers. Subclasses (actual frame recognizers) +/// should implement RecognizeFrame to provide a RecognizedStackFrame for a +/// given stack frame. + +class StackFrameRecognizer + : public std::enable_shared_from_this { +public: + virtual lldb::RecognizedStackFrameSP RecognizeFrame( + lldb::StackFrameSP frame) { + return lldb::RecognizedStackFrameSP(); + }; + virtual std::string GetName() { + return ""; + } + + virtual ~StackFrameRecognizer(){}; +}; + +#ifndef LLDB_DISABLE_PYTHON + +/// @class ScriptedStackFrameRecognizer +/// +/// Python implementation for frame recognizers. An instance of this class +/// tracks a particular Python classobject, which will be asked to recognize +/// stack frames. + +class ScriptedStackFrameRecognizer : public StackFrameRecognizer { + lldb_private::ScriptInterpreter *m_interpreter; + lldb_private::StructuredData::ObjectSP m_python_object_sp; + std::string m_python_class; + +public: + ScriptedStackFrameRecognizer(lldb_private::ScriptInterpreter *interpreter, + const char *pclass); + ~ScriptedStackFrameRecognizer() {} + + std::string GetName() override { + return GetPythonClassName(); + } + + const char *GetPythonClassName() { return m_python_class.c_str(); } + + lldb::RecognizedStackFrameSP RecognizeFrame( + lldb::StackFrameSP frame) override; + +private: + DISALLOW_COPY_AND_ASSIGN(ScriptedStackFrameRecognizer); +}; + +#endif + +/// @class StackFrameRecognizerManager +/// +/// Static class that provides a registry of known stack frame recognizers. +/// Has static methods to add, enumerate, remove, query and invoke recognizers. + +class StackFrameRecognizerManager { +public: + static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, + const ConstString &module, + const ConstString &symbol, + bool first_instruction_only = true); + + static void AddRecognizer(lldb::StackFrameRecognizerSP recognizer, + lldb::RegularExpressionSP module, + lldb::RegularExpressionSP symbol, + bool first_instruction_only = true); + + static void ForEach( + std::function const &callback); + + static bool RemoveRecognizerWithID(uint32_t recognizer_id); + + static void RemoveAllRecognizers(); + + static lldb::StackFrameRecognizerSP GetRecognizerForFrame( + lldb::StackFrameSP frame); + + static lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame); +}; + +} // namespace lldb_private + +#endif // liblldb_StackFrameRecognizer_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/StackID.h b/contrib/llvm/tools/lldb/include/lldb/Target/StackID.h index 51e51a6c0741..871f39c463a9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/StackID.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/StackID.h @@ -10,10 +10,6 @@ #ifndef liblldb_StackID_h_ #define liblldb_StackID_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/AddressRange.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/StopInfo.h b/contrib/llvm/tools/lldb/include/lldb/Target/StopInfo.h index b25bf7dd3d5d..1a9f5b8480db 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/StopInfo.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/StopInfo.h @@ -10,12 +10,8 @@ #ifndef liblldb_StopInfo_h_ #define liblldb_StopInfo_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/SystemRuntime.h b/contrib/llvm/tools/lldb/include/lldb/Target/SystemRuntime.h index 06cc3ec2d012..328dbe231078 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/SystemRuntime.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/SystemRuntime.h @@ -10,10 +10,6 @@ #ifndef liblldb_SystemRuntime_h_ #define liblldb_SystemRuntime_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include #include "lldb/Core/ModuleList.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/Target.h b/contrib/llvm/tools/lldb/include/lldb/Target/Target.h index 75af8e80d2e5..90df1f4929b7 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/Target.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/Target.h @@ -10,21 +10,16 @@ #ifndef liblldb_Target_h_ #define liblldb_Target_h_ -// C Includes -// C++ Includes #include #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointList.h" #include "lldb/Breakpoint/BreakpointName.h" #include "lldb/Breakpoint/WatchpointList.h" #include "lldb/Core/Architecture.h" -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/UserSettingsController.h" @@ -35,13 +30,14 @@ #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Target/SectionLoadHistory.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Timeout.h" #include "lldb/lldb-public.h" namespace lldb_private { -extern OptionEnumValueElement g_dynamic_value_types[]; +OptionEnumValues GetDynamicValueTypes(); typedef enum InlineStrategy { eInlineBreakpointsNever = 0, @@ -61,6 +57,12 @@ typedef enum LoadCWDlldbinitFile { eLoadCWDlldbinitWarn } LoadCWDlldbinitFile; +typedef enum LoadDependentFiles { + eLoadDependentsDefault, + eLoadDependentsYes, + eLoadDependentsNo, +} LoadDependentFiles; + //---------------------------------------------------------------------- // TargetProperties //---------------------------------------------------------------------- @@ -186,6 +188,10 @@ public: void SetDisplayRuntimeSupportValues(bool b); + bool GetDisplayRecognizedArguments() const; + + void SetDisplayRecognizedArguments(bool b); + const ProcessLaunchInfo &GetProcessLaunchInfo(); void SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info); @@ -196,6 +202,10 @@ public: bool GetUseModernTypeLookup() const; + void SetRequireHardwareBreakpoints(bool b); + + bool GetRequireHardwareBreakpoints() const; + private: //------------------------------------------------------------------ // Callbacks for m_launch_info. @@ -375,6 +385,10 @@ public: bool GetAutoApplyFixIts() const { return m_auto_apply_fixits; } + bool IsForUtilityExpr() const { return m_running_utility_expression; } + + void SetIsForUtilityExpr(bool b) { m_running_utility_expression = b; } + private: ExecutionPolicy m_execution_policy = default_execution_policy; lldb::LanguageType m_language = lldb::eLanguageTypeUnknown; @@ -392,6 +406,10 @@ private: bool m_ansi_color_errors = false; bool m_result_is_internal = false; bool m_auto_apply_fixits = true; + /// True if the executed code should be treated as utility code that is only + /// used by LLDB internally. + bool m_running_utility_expression = false; + lldb::DynamicValueType m_use_dynamic = lldb::eNoDynamicValues; Timeout m_timeout = default_timeout; Timeout m_one_thread_timeout = llvm::None; @@ -515,7 +533,9 @@ public: //------------------------------------------------------------------ void Dump(Stream *s, lldb::DescriptionLevel description_level); - const lldb::ProcessSP &CreateProcess(lldb::ListenerSP listener, + // If listener_sp is null, the listener of the owning Debugger object will be + // used. + const lldb::ProcessSP &CreateProcess(lldb::ListenerSP listener_sp, llvm::StringRef plugin_name, const FileSpec *crash_file); @@ -549,7 +569,7 @@ public: // module it is nullptr lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, - lldb::addr_t offset, + uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool request_hardware, @@ -594,14 +614,12 @@ public: // eLazyBoolCalculate, we use the current target setting, else we use the // values passed in. func_name_type_mask is or'ed values from the // FunctionNameType enum. - lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, - const FileSpecList *containingSourceFiles, - const char *func_name, - uint32_t func_name_type_mask, - lldb::LanguageType language, - lldb::addr_t offset, - LazyBool skip_prologue, bool internal, - bool request_hardware); + lldb::BreakpointSP CreateBreakpoint( + const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, const char *func_name, + lldb::FunctionNameType func_name_type_mask, lldb::LanguageType language, + lldb::addr_t offset, LazyBool skip_prologue, bool internal, + bool request_hardware); lldb::BreakpointSP CreateExceptionBreakpoint(enum lldb::LanguageType language, bool catch_bp, @@ -609,25 +627,34 @@ public: Args *additional_args = nullptr, Status *additional_args_error = nullptr); + lldb::BreakpointSP + CreateScriptedBreakpoint(const llvm::StringRef class_name, + const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, + bool internal, + bool request_hardware, + StructuredData::ObjectSP extra_args_sp, + Status *creation_error = nullptr); + // This is the same as the func_name breakpoint except that you can specify a // vector of names. This is cheaper than a regular expression breakpoint in // the case where you just want to set a breakpoint on a set of names you // already know. func_name_type_mask is or'ed values from the // FunctionNameType enum. - lldb::BreakpointSP - CreateBreakpoint(const FileSpecList *containingModules, - const FileSpecList *containingSourceFiles, - const char *func_names[], size_t num_names, - uint32_t func_name_type_mask, lldb::LanguageType language, - lldb::addr_t offset, LazyBool skip_prologue, bool internal, - bool request_hardware); + lldb::BreakpointSP CreateBreakpoint( + const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, const char *func_names[], + size_t num_names, lldb::FunctionNameType func_name_type_mask, + lldb::LanguageType language, lldb::addr_t offset, LazyBool skip_prologue, + bool internal, bool request_hardware); lldb::BreakpointSP CreateBreakpoint(const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, const std::vector &func_names, - uint32_t func_name_type_mask, lldb::LanguageType language, - lldb::addr_t m_offset, LazyBool skip_prologue, bool internal, + lldb::FunctionNameType func_name_type_mask, + lldb::LanguageType language, lldb::addr_t m_offset, + LazyBool skip_prologue, bool internal, bool request_hardware); // Use this to create a general breakpoint: @@ -665,7 +692,6 @@ public: const BreakpointOptions &options, const BreakpointName::Permissions &permissions); void ApplyNameToBreakpoints(BreakpointName &bp_name); - // This takes ownership of the name obj passed in. void AddBreakpointName(BreakpointName *bp_name); @@ -753,9 +779,9 @@ public: /// that doesn't have code in it, LLDB_INVALID_ADDRESS will be /// returned. //------------------------------------------------------------------ - lldb::addr_t GetOpcodeLoadAddress( - lldb::addr_t load_addr, - AddressClass addr_class = AddressClass::eInvalid) const; + lldb::addr_t + GetOpcodeLoadAddress(lldb::addr_t load_addr, + AddressClass addr_class = AddressClass::eInvalid) const; // Get load_addr as breakable load address for this target. Take a addr and // check if for any reason there is a better address than this to put a @@ -826,14 +852,16 @@ public: /// A shared pointer reference to the module that will become /// the main executable for this process. /// - /// @param[in] get_dependent_files + /// @param[in] load_dependent_files /// If \b true then ask the object files to track down any /// known dependent files. /// /// @see ObjectFile::GetDependentModules (FileSpecList&) /// @see Process::GetImages() //------------------------------------------------------------------ - void SetExecutableModule(lldb::ModuleSP &module_sp, bool get_dependent_files); + void SetExecutableModule( + lldb::ModuleSP &module_sp, + LoadDependentFiles load_dependent_files = eLoadDependentsDefault); bool LoadScriptingResources(std::list &errors, Stream *feedback_stream = nullptr, @@ -913,28 +941,30 @@ public: /// Set the architecture for this target. /// /// If the current target has no Images read in, then this just sets the - /// architecture, which will - /// be used to select the architecture of the ExecutableModule when that is - /// set. - /// If the current target has an ExecutableModule, then calling - /// SetArchitecture with a different + /// architecture, which will be used to select the architecture of the + /// ExecutableModule when that is set. If the current target has an + /// ExecutableModule, then calling SetArchitecture with a different /// architecture from the currently selected one will reset the - /// ExecutableModule to that slice - /// of the file backing the ExecutableModule. If the file backing the - /// ExecutableModule does not - /// contain a fork of this architecture, then this code will return false, and - /// the architecture - /// won't be changed. - /// If the input arch_spec is the same as the already set architecture, this - /// is a no-op. + /// ExecutableModule to that slice of the file backing the ExecutableModule. + /// If the file backing the ExecutableModule does not contain a fork of this + /// architecture, then this code will return false, and the architecture + /// won't be changed. If the input arch_spec is the same as the already set + /// architecture, this is a no-op. /// /// @param[in] arch_spec /// The new architecture. /// + /// @param[in] set_platform + /// If \b true, then the platform will be adjusted if the currently + /// selected platform is not compatible with the archicture being set. + /// If \b false, then just the architecture will be set even if the + /// currently selected platform isn't compatible (in case it might be + /// manually set following this function call). + /// /// @return /// \b true if the architecture was successfully set, \bfalse otherwise. //------------------------------------------------------------------ - bool SetArchitecture(const ArchSpec &arch_spec); + bool SetArchitecture(const ArchSpec &arch_spec, bool set_platform = false); bool MergeArchitecture(const ArchSpec &arch_spec); @@ -1324,6 +1354,8 @@ private: void AddBreakpoint(lldb::BreakpointSP breakpoint_sp, bool internal); + void FinalizeFileActions(ProcessLaunchInfo &info); + DISALLOW_COPY_AND_ASSIGN(Target); }; diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/TargetList.h b/contrib/llvm/tools/lldb/include/lldb/Target/TargetList.h index 43f4520369b6..90c480745a0c 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/TargetList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/TargetList.h @@ -10,15 +10,11 @@ #ifndef liblldb_TargetList_h_ #define liblldb_TargetList_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Broadcaster.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Broadcaster.h" namespace lldb_private { @@ -92,7 +88,8 @@ public: /// An error object that indicates success or failure //------------------------------------------------------------------ Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, - llvm::StringRef triple_str, bool get_dependent_modules, + llvm::StringRef triple_str, + LoadDependentFiles get_dependent_modules, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp); @@ -103,7 +100,8 @@ public: /// platform you will be using //------------------------------------------------------------------ Status CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, - const ArchSpec &arch, bool get_dependent_modules, + const ArchSpec &arch, + LoadDependentFiles get_dependent_modules, lldb::PlatformSP &platform_sp, lldb::TargetSP &target_sp); //------------------------------------------------------------------ @@ -217,12 +215,13 @@ private: Status CreateTargetInternal(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, - bool get_dependent_files, + LoadDependentFiles load_dependent_files, const OptionGroupPlatform *platform_options, lldb::TargetSP &target_sp, bool is_dummy_target); Status CreateTargetInternal(Debugger &debugger, llvm::StringRef user_exe_path, - const ArchSpec &arch, bool get_dependent_modules, + const ArchSpec &arch, + LoadDependentFiles get_dependent_modules, lldb::PlatformSP &platform_sp, lldb::TargetSP &target_sp, bool is_dummy_target); diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/Thread.h b/contrib/llvm/tools/lldb/include/lldb/Target/Thread.h index 9ce73e0cbeff..0d14b10c651f 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/Thread.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/Thread.h @@ -10,21 +10,17 @@ #ifndef liblldb_Thread_h_ #define liblldb_Thread_h_ -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Broadcaster.h" -#include "lldb/Core/Event.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/RegisterCheckpoint.h" #include "lldb/Target/StackFrameList.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" @@ -57,6 +53,8 @@ public: bool GetStepInAvoidsNoDebug() const; bool GetStepOutAvoidsNoDebug() const; + + uint64_t GetMaxBacktraceDepth() const; }; typedef std::shared_ptr ThreadPropertiesSP; @@ -282,7 +280,7 @@ public: /// message). //------------------------------------------------------------------ StructuredData::ObjectSP GetExtendedInfo() { - if (m_extended_info_fetched == false) { + if (!m_extended_info_fetched) { m_extended_info = FetchThreadExtendedInfo(); m_extended_info_fetched = true; } @@ -496,9 +494,9 @@ public: // If stop_format is true, this will be the form used when we print stop // info. If false, it will be the form we use for thread list and co. - void DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx, + void DumpUsingSettingsFormat(Stream &strm, uint32_t frame_idx, bool stop_format); - + bool GetDescription(Stream &s, lldb::DescriptionLevel level, bool print_json_thread, bool print_json_stopinfo); @@ -655,12 +653,16 @@ public: /// @param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// + /// @param[out] status + /// A status with an error if queuing failed. + /// /// @return /// A shared pointer to the newly queued thread plan, or nullptr if the /// plan could not be queued. //------------------------------------------------------------------ virtual lldb::ThreadPlanSP QueueThreadPlanForStepSingleInstruction( - bool step_over, bool abort_other_plans, bool stop_other_threads); + bool step_over, bool abort_other_plans, bool stop_other_threads, + Status &status); //------------------------------------------------------------------ /// Queues the plan used to step through an address range, stepping over @@ -690,6 +692,9 @@ public: /// @param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// + /// @param[out] status + /// A status with an error if queuing failed. + /// /// @param[in] step_out_avoids_code_without_debug_info /// If eLazyBoolYes, if the step over steps out it will continue to step /// out till it comes to a frame with debug info. @@ -702,6 +707,7 @@ public: virtual lldb::ThreadPlanSP QueueThreadPlanForStepOverRange( bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, lldb::RunMode stop_other_threads, + Status &status, LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); // Helper function that takes a LineEntry to step, insted of an AddressRange. @@ -710,6 +716,7 @@ public: virtual lldb::ThreadPlanSP QueueThreadPlanForStepOverRange( bool abort_other_plans, const LineEntry &line_entry, const SymbolContext &addr_context, lldb::RunMode stop_other_threads, + Status &status, LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); //------------------------------------------------------------------ @@ -744,6 +751,9 @@ public: /// @param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// + /// @param[out] status + /// A status with an error if queuing failed. + /// /// @param[in] step_in_avoids_code_without_debug_info /// If eLazyBoolYes we will step out if we step into code with no debug /// info. @@ -761,7 +771,7 @@ public: virtual lldb::ThreadPlanSP QueueThreadPlanForStepInRange( bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, const char *step_in_target, - lldb::RunMode stop_other_threads, + lldb::RunMode stop_other_threads, Status &status, LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate, LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); @@ -771,7 +781,7 @@ public: virtual lldb::ThreadPlanSP QueueThreadPlanForStepInRange( bool abort_other_plans, const LineEntry &line_entry, const SymbolContext &addr_context, const char *step_in_target, - lldb::RunMode stop_other_threads, + lldb::RunMode stop_other_threads, Status &status, LazyBool step_in_avoids_code_without_debug_info = eLazyBoolCalculate, LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); @@ -803,6 +813,9 @@ public: /// @param[in] run_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// + /// @param[out] status + /// A status with an error if queuing failed. + /// /// @param[in] step_out_avoids_code_without_debug_info /// If eLazyBoolYes, if the step over steps out it will continue to step /// out till it comes to a frame with debug info. @@ -814,10 +827,8 @@ public: //------------------------------------------------------------------ virtual lldb::ThreadPlanSP QueueThreadPlanForStepOut( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, - Vote stop_vote, // = eVoteYes, - Vote run_vote, // = eVoteNoOpinion); - uint32_t frame_idx, + bool stop_other_threads, Vote stop_vote, Vote run_vote, + uint32_t frame_idx, Status &status, LazyBool step_out_avoids_code_without_debug_info = eLazyBoolCalculate); //------------------------------------------------------------------ @@ -848,9 +859,15 @@ public: /// \b true if we will stop other threads while we single step this one. /// /// @param[in] stop_vote + /// /// @param[in] run_vote /// See standard meanings for the stop & run votes in ThreadPlan.h. /// + /// @param[in] frame_idx + /// + /// @param[out] status + /// A status with an error if queuing failed. + /// /// @param[in] continue_to_next_branch /// Normally this will enqueue a plan that will put a breakpoint on the /// return address and continue @@ -874,16 +891,13 @@ public: //------------------------------------------------------------------ virtual lldb::ThreadPlanSP QueueThreadPlanForStepOutNoShouldStop( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, - bool stop_other_threads, - Vote stop_vote, // = eVoteYes, - Vote run_vote, // = eVoteNoOpinion); - uint32_t frame_idx, bool continue_to_next_branch = false); + bool stop_other_threads, Vote stop_vote, Vote run_vote, + uint32_t frame_idx, Status &status, bool continue_to_next_branch = false); //------------------------------------------------------------------ /// Gets the plan used to step through the code that steps from a function /// call site at the current PC into the actual function call. /// - /// /// @param[in] return_stack_id /// The stack id that we will return to (by setting backstop breakpoints on /// the return @@ -897,14 +911,17 @@ public: /// @param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// + /// @param[out] status + /// A status with an error if queuing failed. + /// /// @return /// A shared pointer to the newly queued thread plan, or nullptr if the /// plan could not be queued. //------------------------------------------------------------------ virtual lldb::ThreadPlanSP QueueThreadPlanForStepThrough(StackID &return_stack_id, - bool abort_other_plans, - bool stop_other_threads); + bool abort_other_plans, bool stop_other_threads, + Status &status); //------------------------------------------------------------------ /// Gets the plan used to continue from the current PC. @@ -922,22 +939,24 @@ public: /// @param[in] stop_other_threads /// \b true if we will stop other threads while we single step this one. /// + /// @param[out] status + /// A status with an error if queuing failed. + /// /// @return /// A shared pointer to the newly queued thread plan, or nullptr if the /// plan could not be queued. //------------------------------------------------------------------ virtual lldb::ThreadPlanSP QueueThreadPlanForRunToAddress(bool abort_other_plans, Address &target_addr, - bool stop_other_threads); + bool stop_other_threads, Status &status); - virtual lldb::ThreadPlanSP - QueueThreadPlanForStepUntil(bool abort_other_plans, - lldb::addr_t *address_list, size_t num_addresses, - bool stop_others, uint32_t frame_idx); + virtual lldb::ThreadPlanSP QueueThreadPlanForStepUntil( + bool abort_other_plans, lldb::addr_t *address_list, size_t num_addresses, + bool stop_others, uint32_t frame_idx, Status &status); virtual lldb::ThreadPlanSP QueueThreadPlanForStepScripted(bool abort_other_plans, const char *class_name, - bool stop_other_threads); + bool stop_other_threads, Status &status); //------------------------------------------------------------------ // Thread Plan accessors: @@ -1023,7 +1042,7 @@ public: /// false otherwise. //------------------------------------------------------------------ bool CompletedPlanOverridesBreakpoint(); - + //------------------------------------------------------------------ /// Queues a generic thread plan. /// @@ -1038,7 +1057,7 @@ public: /// @return /// A pointer to the last completed plan. //------------------------------------------------------------------ - void QueueThreadPlan(lldb::ThreadPlanSP &plan_sp, bool abort_other_plans); + Status QueueThreadPlan(lldb::ThreadPlanSP &plan_sp, bool abort_other_plans); //------------------------------------------------------------------ /// Discards the plans queued on the plan stack of the current thread. This @@ -1234,6 +1253,10 @@ public: //---------------------------------------------------------------------- virtual uint64_t GetExtendedBacktraceToken() { return LLDB_INVALID_ADDRESS; } + lldb::ValueObjectSP GetCurrentException(); + + lldb::ThreadSP GetCurrentExceptionBacktrace(); + protected: friend class ThreadPlan; friend class ThreadList; diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlan.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlan.h index 7591fa9c9d07..15bc4c7656c3 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlan.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlan.h @@ -10,13 +10,9 @@ #ifndef liblldb_ThreadPlan_h_ #define liblldb_ThreadPlan_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" @@ -600,10 +596,12 @@ protected: bool IsUsuallyUnexplainedStopReason(lldb::StopReason); + Status m_status; Thread &m_thread; Vote m_stop_vote; Vote m_run_vote; - bool m_takes_iteration_count = false; + bool m_takes_iteration_count; + bool m_could_not_resolve_hw_bp; int32_t m_iteration_count = 1; private: @@ -655,6 +653,8 @@ public: bool OkayToDiscard() override { return false; } + const Status &GetStatus() { return m_status; } + protected: bool DoPlanExplainsStop(Event *event_ptr) override; diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanBase.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanBase.h index 7a8b7eb20bb2..bcf20c5544bc 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanBase.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanBase.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanFundamental_h_ #define liblldb_ThreadPlanFundamental_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallFunction.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallFunction.h index 56bfc819320c..3bec86e370d1 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallFunction.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallFunction.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanCallFunction_h_ #define liblldb_ThreadPlanCallFunction_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h index d58f7f050dbe..9b75da5fd2f8 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallFunctionUsingABI.h @@ -11,10 +11,6 @@ #ifndef liblldb_ThreadPlanCallFunctionUsingABI_h_ #define liblldb_ThreadPlanCallFunctionUsingABI_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlanCallFunction.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h index 5fe80927ca21..ba1001ce5e91 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanCallUserExpression.h @@ -11,10 +11,6 @@ #ifndef liblldb_ThreadPlanCallUserExpression_h_ #define liblldb_ThreadPlanCallUserExpression_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanCallFunction.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanPython.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanPython.h index 973c935b7c79..fc4cfb3bf0b4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanPython.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanPython.h @@ -11,12 +11,8 @@ #ifndef liblldb_ThreadPlan_Python_h_ #define liblldb_ThreadPlan_Python_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" @@ -63,6 +59,7 @@ protected: private: std::string m_class_name; StructuredData::ObjectSP m_implementation_sp; + bool m_did_push; DISALLOW_COPY_AND_ASSIGN(ThreadPlanPython); }; diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanRunToAddress.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanRunToAddress.h index 8e91fb9472a7..58608864d463 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanRunToAddress.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanRunToAddress.h @@ -10,12 +10,8 @@ #ifndef liblldb_ThreadPlanRunToAddress_h_ #define liblldb_ThreadPlanRunToAddress_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlan.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h index 030d5e434bd9..d3aca3e6f5c0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanShouldStopHere.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanShouldStopHere_h_ #define liblldb_ThreadPlanShouldStopHere_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlan.h" namespace lldb_private { @@ -101,10 +97,12 @@ public: void ClearShouldStopHereCallbacks() { m_callbacks.Clear(); } - bool InvokeShouldStopHereCallback(lldb::FrameComparison operation); + bool InvokeShouldStopHereCallback(lldb::FrameComparison operation, + Status &status); lldb::ThreadPlanSP - CheckShouldStopHereAndQueueStepOut(lldb::FrameComparison operation); + CheckShouldStopHereAndQueueStepOut(lldb::FrameComparison operation, + Status &status); lldb_private::Flags &GetFlags() { return m_flags; } @@ -114,14 +112,16 @@ protected: static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, - void *baton); + Status &status, void *baton); static lldb::ThreadPlanSP DefaultStepFromHereCallback(ThreadPlan *current_plan, Flags &flags, - lldb::FrameComparison operation, void *baton); + lldb::FrameComparison operation, Status &status, + void *baton); virtual lldb::ThreadPlanSP - QueueStepOutFromHerePlan(Flags &flags, lldb::FrameComparison operation); + QueueStepOutFromHerePlan(Flags &flags, lldb::FrameComparison operation, + Status &status); // Implement this, and call it in the plan's constructor to set the default // flags. diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepInRange.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepInRange.h index c3116eac81b5..c13b3533af1c 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepInRange.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepInRange.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanStepInRange_h_ #define liblldb_ThreadPlanStepInRange_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/AddressRange.h" #include "lldb/Target/StackID.h" #include "lldb/Target/Thread.h" @@ -58,7 +54,7 @@ protected: static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, - void *baton); + Status &status, void *baton); bool DoWillResume(lldb::StateType resume_state, bool current_plan) override; @@ -80,11 +76,11 @@ private: friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepOverRange( bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, lldb::RunMode stop_others, - LazyBool avoid_code_without_debug_info); + Status &status, LazyBool avoid_code_without_debug_info); friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepInRange( bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, const char *step_in_target, - lldb::RunMode stop_others, + lldb::RunMode stop_others, Status &status, LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info); diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepInstruction.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepInstruction.h index 8b56e41ad64f..ea5d93fa4944 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepInstruction.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepInstruction.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanStepInstruction_h_ #define liblldb_ThreadPlanStepInstruction_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/lldb-private.h" @@ -43,7 +39,8 @@ protected: private: friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepSingleInstruction( - bool step_over, bool abort_other_plans, bool stop_other_threads); + bool step_over, bool abort_other_plans, bool stop_other_threads, + Status &status); lldb::addr_t m_instruction_addr; bool m_stop_other_threads; diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOut.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOut.h index 285f4cab13a2..8ef9f95d4f96 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOut.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOut.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanStepOut_h_ #define liblldb_ThreadPlanStepOut_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanShouldStopHere.h" @@ -74,13 +70,14 @@ private: // if ShouldStopHere told us // to. Function *m_immediate_step_from_function; + std::vector m_stepped_past_frames; lldb::ValueObjectSP m_return_valobj_sp; bool m_calculate_return_value; friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepOut( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, bool stop_others, Vote stop_vote, Vote run_vote, uint32_t frame_idx, - LazyBool step_out_avoids_code_without_debug_info); + Status &status, LazyBool step_out_avoids_code_without_debug_info); void SetupAvoidNoDebug(LazyBool step_out_avoids_code_without_debug_info); // Need an appropriate marker for the current stack so we can tell step out diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h index e799ec5a44ff..7aaf56ed7c0b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOverBreakpoint.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanStepOverBreakpoint_h_ #define liblldb_ThreadPlanStepOverBreakpoint_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOverRange.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOverRange.h index 84fdb0ddcf99..2eeb2bb96022 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOverRange.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepOverRange.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanStepOverRange_h_ #define liblldb_ThreadPlanStepOverRange_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/AddressRange.h" #include "lldb/Target/StackID.h" #include "lldb/Target/Thread.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepRange.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepRange.h index 65bc1671cb1e..b3e267a0827b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepRange.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepRange.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanStepRange_h_ #define liblldb_ThreadPlanStepRange_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/AddressRange.h" #include "lldb/Target/StackID.h" #include "lldb/Target/Thread.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepThrough.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepThrough.h index 41aa7b21abe0..1bff541e7df6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepThrough.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepThrough.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanStepThrough_h_ #define liblldb_ThreadPlanStepThrough_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -45,10 +41,9 @@ protected: private: friend lldb::ThreadPlanSP - Thread::QueueThreadPlanForStepThrough(StackID &return_stack_id, bool abort_other_plans, - bool stop_others); + bool stop_others, Status &status); void ClearBackstopBreakpoint(); diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepUntil.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepUntil.h index bdc630bcf8de..33ccc0fa0d54 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepUntil.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanStepUntil.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadPlanStepUntil_h_ #define liblldb_ThreadPlanStepUntil_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadPlan.h" @@ -59,7 +55,7 @@ private: friend lldb::ThreadPlanSP Thread::QueueThreadPlanForStepUntil( bool abort_other_plans, lldb::addr_t *address_list, size_t num_addresses, - bool stop_others, uint32_t frame_idx); + bool stop_others, uint32_t frame_idx, Status &status); // Need an appropriate marker for the current stack so we can tell step out // from step in. diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanTracer.h b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanTracer.h index 65115383efaa..21f9023f8d57 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanTracer.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/ThreadPlanTracer.h @@ -11,13 +11,9 @@ #ifndef liblldb_ThreadPlanTracer_h_ #define liblldb_ThreadPlanTracer_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/TaggedASTType.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/UnixSignals.h b/contrib/llvm/tools/lldb/include/lldb/Target/UnixSignals.h index 7ec683585f8e..8774139371f0 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/UnixSignals.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/UnixSignals.h @@ -10,14 +10,10 @@ #ifndef lldb_UnixSignals_h_ #define lldb_UnixSignals_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" #include "llvm/ADT/Optional.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Target/Unwind.h b/contrib/llvm/tools/lldb/include/lldb/Target/Unwind.h index a50e8d4a7bdd..9e0da9ed553b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Target/Unwind.h +++ b/contrib/llvm/tools/lldb/include/lldb/Target/Unwind.h @@ -10,12 +10,8 @@ #ifndef liblldb_Unwind_h_ #define liblldb_Unwind_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h b/contrib/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h index 680e9b1b9ea6..e84cbbbe5efa 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/ArchSpec.h @@ -15,11 +15,11 @@ #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" #include "lldb/lldb-private-enumerations.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" -#include // for size_t -#include // for uint32_t -#include // for string +#include +#include +#include namespace lldb_private { @@ -371,6 +371,7 @@ public: bool IsValid() const { return m_core >= eCore_arm_generic && m_core < kNumCores; } + explicit operator bool() const { return IsValid(); } bool TripleVendorWasSpecified() const { return !m_triple.getVendorName().empty(); diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Baton.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Baton.h index 59999e4697fa..7477846be48b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Baton.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Baton.h @@ -10,10 +10,10 @@ #ifndef lldb_Baton_h_ #define lldb_Baton_h_ -#include "lldb/lldb-enumerations.h" // for DescriptionLevel +#include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" -#include // for unique_ptr +#include namespace lldb_private { class Stream; diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Broadcaster.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Broadcaster.h similarity index 97% rename from contrib/llvm/tools/lldb/include/lldb/Core/Broadcaster.h rename to contrib/llvm/tools/lldb/include/lldb/Utility/Broadcaster.h index 4851007c9a2a..8763a63b0d5e 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Broadcaster.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Broadcaster.h @@ -7,22 +7,22 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Broadcaster_h_ -#define liblldb_Broadcaster_h_ +#ifndef LLDB_UTILITY_BROADCASTER_H +#define LLDB_UTILITY_BROADCASTER_H #include "lldb/Utility/ConstString.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-forward.h" // for ListenerSP, EventSP, Broadcast... +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" #include "llvm/ADT/SmallVector.h" -#include // for uint32_t, UINT32_MAX +#include #include -#include // for shared_ptr, operator==, enable... +#include #include -#include // for set +#include #include -#include // for pair +#include #include namespace lldb_private { @@ -223,7 +223,7 @@ private: }; //---------------------------------------------------------------------- -/// @class Broadcaster Broadcaster.h "lldb/Core/Broadcaster.h" An event +/// @class Broadcaster Broadcaster.h "lldb/Utility/Broadcaster.h" An event /// broadcasting class. /// /// The Broadcaster class is designed to be subclassed by objects that wish to @@ -595,4 +595,4 @@ private: } // namespace lldb_private -#endif // liblldb_Broadcaster_h_ +#endif // LLDB_UTILITY_BROADCASTER_H diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/CompletionRequest.h b/contrib/llvm/tools/lldb/include/lldb/Utility/CompletionRequest.h index ef75474813e0..38d8d5c587e2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/CompletionRequest.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/CompletionRequest.h @@ -11,11 +11,50 @@ #define LLDB_UTILITY_COMPLETIONREQUEST_H #include "lldb/Utility/Args.h" +#include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/StringList.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" namespace lldb_private { +class CompletionResult { + //---------------------------------------------------------- + /// A single completion and all associated data. + //---------------------------------------------------------- + struct Completion { + Completion(llvm::StringRef completion, llvm::StringRef description) + : m_completion(completion.str()), m_descripton(description.str()) {} + + std::string m_completion; + std::string m_descripton; + + /// Generates a string that uniquely identifies this completion result. + std::string GetUniqueKey() const; + }; + std::vector m_results; + + /// List of added completions so far. Used to filter out duplicates. + llvm::StringSet<> m_added_values; + +public: + void AddResult(llvm::StringRef completion, llvm::StringRef description); + + //---------------------------------------------------------- + /// Adds all collected completion matches to the given list. + /// The list will be cleared before the results are added. The number of + /// results here is guaranteed to be equal to GetNumberOfResults(). + //---------------------------------------------------------- + void GetMatches(StringList &matches) const; + + //---------------------------------------------------------- + /// Adds all collected completion descriptions to the given list. + /// The list will be cleared before the results are added. The number of + /// results here is guaranteed to be equal to GetNumberOfResults(). + //---------------------------------------------------------- + void GetDescriptions(StringList &descriptions) const; + + std::size_t GetNumberOfResults() const { return m_results.size(); } +}; //---------------------------------------------------------------------- /// @class CompletionRequest CompletionRequest.h @@ -46,13 +85,13 @@ public: /// completion from match_start_point, and return match_return_elements /// elements. /// - /// @param [out] matches - /// A list of matches that will be filled by the different completion - /// handlers. + /// @param [out] result + /// The CompletionResult that will be filled with the results after this + /// request has been handled. //---------------------------------------------------------- CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, int match_start_point, int max_return_elements, - StringList &matches); + CompletionResult &result); llvm::StringRef GetRawLine() const { return m_command; } @@ -84,10 +123,11 @@ public: /// afterwards. /// /// @param match The suggested completion. - void AddCompletion(llvm::StringRef completion) { - // Add the completion if we haven't seen the same value before. - if (m_match_set.insert(completion).second) - m_matches->AppendString(completion); + /// @param match An optional description of the completion string. The + /// description will be displayed to the user alongside the completion. + void AddCompletion(llvm::StringRef completion, + llvm::StringRef description = "") { + m_result.AddResult(completion, description); } /// Adds multiple possible completion strings. @@ -100,7 +140,25 @@ public: AddCompletion(completions.GetStringAtIndex(i)); } - std::size_t GetNumberOfMatches() const { return m_matches->GetSize(); } + /// Adds multiple possible completion strings alongside their descriptions. + /// + /// The number of completions and descriptions must be identical. + /// + /// \param completions The list of completions. + /// \param completions The list of descriptions. + /// + /// @see AddCompletion + void AddCompletions(const StringList &completions, + const StringList &descriptions) { + lldbassert(completions.GetSize() == descriptions.GetSize()); + for (std::size_t i = 0; i < completions.GetSize(); ++i) + AddCompletion(completions.GetStringAtIndex(i), + descriptions.GetStringAtIndex(i)); + } + + std::size_t GetNumberOfMatches() const { + return m_result.GetNumberOfResults(); + } llvm::StringRef GetCursorArgument() const { return GetParsedLine().GetArgumentAtIndex(GetCursorIndex()); @@ -134,14 +192,11 @@ private: /// after the completion.) \bfalse otherwise. bool m_word_complete = false; - // Note: This list is kept private. This is by design to prevent that any - // completion depends on any already computed completion from another backend. - // Note: We don't own the list. It's owned by the creator of the - // CompletionRequest object. - StringList *m_matches; - - /// List of added completions so far. Used to filter out duplicates. - llvm::StringSet<> m_match_set; + /// The result this request is supposed to fill out. + /// We keep this object private to ensure that no backend can in any way + /// depend on already calculated completions (which would make debugging and + /// testing them much more complicated). + CompletionResult &m_result; }; } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Connection.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Connection.h index 1b0801378f84..074b44b36865 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Connection.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Connection.h @@ -10,16 +10,16 @@ #ifndef liblldb_Connection_h_ #define liblldb_Connection_h_ -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ConnectionStatus -#include "lldb/lldb-forward.h" // for IOObjectSP +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" -#include // for micro +#include #include -#include // for size_t +#include namespace lldb_private { class Status; diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/ConstString.h b/contrib/llvm/tools/lldb/include/lldb/Utility/ConstString.h index 98b3447abe3e..41f6717edee9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/ConstString.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/ConstString.h @@ -11,9 +11,9 @@ #define liblldb_ConstString_h_ #include "llvm/ADT/StringRef.h" -#include "llvm/Support/FormatVariadic.h" // for format_provider +#include "llvm/Support/FormatVariadic.h" -#include // for size_t +#include namespace lldb_private { class Stream; @@ -253,7 +253,7 @@ public: //------------------------------------------------------------------ /// Clear this object's state. /// - /// Clear any contained string and reset the value to the an empty string + /// Clear any contained string and reset the value to the empty string /// value. //------------------------------------------------------------------ void Clear() { m_string = nullptr; } @@ -345,6 +345,15 @@ public: //------------------------------------------------------------------ bool IsEmpty() const { return m_string == nullptr || m_string[0] == '\0'; } + //------------------------------------------------------------------ + /// Test for null string. + /// + /// @return + /// @li \b true if there is no string associated with this instance. + /// @li \b false if there is a string associated with this instance. + //------------------------------------------------------------------ + bool IsNull() const { return m_string == nullptr; } + //------------------------------------------------------------------ /// Set the C string value. /// @@ -373,15 +382,14 @@ public: /// them. /// /// @param[in] demangled - /// The demangled C string to correlate with the \a mangled - /// name. + /// The demangled string to correlate with the \a mangled name. /// /// @param[in] mangled /// The already uniqued mangled ConstString to correlate the /// soon to be uniqued version of \a demangled. //------------------------------------------------------------------ - void SetCStringWithMangledCounterpart(const char *demangled, - const ConstString &mangled); + void SetStringWithMangledCounterpart(llvm::StringRef demangled, + const ConstString &mangled); //------------------------------------------------------------------ /// Retrieve the mangled or demangled counterpart for a mangled or demangled diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/DataBufferHeap.h b/contrib/llvm/tools/lldb/include/lldb/Utility/DataBufferHeap.h index d64e5b7563a9..5a1e98803f0a 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/DataBufferHeap.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/DataBufferHeap.h @@ -11,10 +11,10 @@ #define liblldb_DataBufferHeap_h_ #include "lldb/Utility/DataBuffer.h" -#include "lldb/lldb-types.h" // for offset_t -#include "llvm/ADT/StringRef.h" // for StringRef +#include "lldb/lldb-types.h" +#include "llvm/ADT/StringRef.h" -#include // for uint8_t, uint64_t +#include #include namespace lldb_private { @@ -90,7 +90,8 @@ public: /// Set the number of bytes in the data buffer. /// /// Sets the number of bytes that this object should be able to contain. - /// This can be used prior to copying data into the buffer. + /// This can be used prior to copying data into the buffer. Note that this + /// zero-initializes up to \p byte_size bytes. /// /// @param[in] byte_size /// The new size in bytes that this data buffer should attempt diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/DataBufferLLVM.h b/contrib/llvm/tools/lldb/include/lldb/Utility/DataBufferLLVM.h index d76582cbf47c..947ddb54da4a 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/DataBufferLLVM.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/DataBufferLLVM.h @@ -11,10 +11,10 @@ #define LLDB_CORE_DATABUFFERLLVM_H #include "lldb/Utility/DataBuffer.h" -#include "lldb/lldb-types.h" // for offset_t +#include "lldb/lldb-types.h" #include -#include // for uint8_t, uint64_t +#include namespace llvm { class WritableMemoryBuffer; @@ -23,16 +23,11 @@ class Twine; namespace lldb_private { +class FileSystem; class DataBufferLLVM : public DataBuffer { public: ~DataBufferLLVM(); - static std::shared_ptr - CreateSliceFromPath(const llvm::Twine &Path, uint64_t Size, uint64_t Offset); - - static std::shared_ptr - CreateFromPath(const llvm::Twine &Path); - uint8_t *GetBytes() override; const uint8_t *GetBytes() const override; lldb::offset_t GetByteSize() const override; @@ -40,6 +35,7 @@ public: char *GetChars() { return reinterpret_cast(GetBytes()); } private: + friend FileSystem; /// Construct a DataBufferLLVM from \p Buffer. \p Buffer must be a valid /// pointer. explicit DataBufferLLVM(std::unique_ptr Buffer); diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/DataEncoder.h b/contrib/llvm/tools/lldb/include/lldb/Utility/DataEncoder.h index c1214705c726..b1ee5a599983 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/DataEncoder.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/DataEncoder.h @@ -12,12 +12,12 @@ #if defined(__cplusplus) -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-enumerations.h" // for ByteOrder -#include "lldb/lldb-forward.h" // for DataBufferSP -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" -#include // for size_t +#include #include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/DataExtractor.h b/contrib/llvm/tools/lldb/include/lldb/Utility/DataExtractor.h index 50c88db8e358..f1e15e6d00e3 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/DataExtractor.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/DataExtractor.h @@ -11,9 +11,10 @@ #define LLDB_UTILITY_DATAEXTRACTOR_H #include "lldb/lldb-defines.h" -#include "lldb/lldb-enumerations.h" // for ByteOrder -#include "lldb/lldb-forward.h" // for DataBufferSP +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" #include "lldb/lldb-types.h" +#include "llvm/ADT/ArrayRef.h" #include #include @@ -29,7 +30,6 @@ namespace llvm { template class SmallVectorImpl; } -// C++ Includes namespace lldb_private { @@ -1095,6 +1095,10 @@ public: void Checksum(llvm::SmallVectorImpl &dest, uint64_t max_data = 0); + llvm::ArrayRef GetData() const { + return {GetDataStart(), size_t(GetByteSize())}; + } + protected: //------------------------------------------------------------------ // Member variables diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Either.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Either.h deleted file mode 100644 index 0dc340b64e86..000000000000 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Either.h +++ /dev/null @@ -1,126 +0,0 @@ -//===-- Either.h -----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_Either_h_ -#define liblldb_Either_h_ - -#include "llvm/ADT/Optional.h" - -#include - -namespace lldb_utility { -template class Either { -private: - enum class Selected { One, Two }; - - Selected m_selected; - union { - T1 m_t1; - T2 m_t2; - }; - -public: - Either(const T1 &t1) { - m_t1 = t1; - m_selected = Selected::One; - } - - Either(const T2 &t2) { - m_t2 = t2; - m_selected = Selected::Two; - } - - Either(const Either &rhs) { - switch (rhs.m_selected) { - case Selected::One: - m_t1 = rhs.GetAs().getValue(); - m_selected = Selected::One; - break; - case Selected::Two: - m_t2 = rhs.GetAs().getValue(); - m_selected = Selected::Two; - break; - } - } - - template ::value>::type - * = nullptr> - llvm::Optional GetAs() const { - switch (m_selected) { - case Selected::One: - return m_t1; - default: - return llvm::Optional(); - } - } - - template ::value>::type - * = nullptr> - llvm::Optional GetAs() const { - switch (m_selected) { - case Selected::Two: - return m_t2; - default: - return llvm::Optional(); - } - } - - template - ResultType Apply(std::function if_T1, - std::function if_T2) const { - switch (m_selected) { - case Selected::One: - return if_T1(m_t1); - case Selected::Two: - return if_T2(m_t2); - } - } - - bool operator==(const Either &rhs) { - return (GetAs() == rhs.GetAs()) && (GetAs() == rhs.GetAs()); - } - - explicit operator bool() { - switch (m_selected) { - case Selected::One: - return (bool)m_t1; - case Selected::Two: - return (bool)m_t2; - } - } - - Either &operator=(const Either &rhs) { - switch (rhs.m_selected) { - case Selected::One: - m_t1 = rhs.GetAs().getValue(); - m_selected = Selected::One; - break; - case Selected::Two: - m_t2 = rhs.GetAs().getValue(); - m_selected = Selected::Two; - break; - } - return *this; - } - - ~Either() { - switch (m_selected) { - case Selected::One: - m_t1.T1::~T1(); - break; - case Selected::Two: - m_t2.T2::~T2(); - break; - } - } -}; - -} // namespace lldb_utility - -#endif // #ifndef liblldb_Either_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Event.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Event.h similarity index 95% rename from contrib/llvm/tools/lldb/include/lldb/Core/Event.h rename to contrib/llvm/tools/lldb/include/lldb/Utility/Event.h index fa3017057675..d65043f564fb 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Event.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Event.h @@ -7,24 +7,24 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Event_h_ -#define liblldb_Event_h_ +#ifndef LLDB_UTILITY_EVENT_H +#define LLDB_UTILITY_EVENT_H -#include "lldb/Core/Broadcaster.h" -#include "lldb/Host/Predicate.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Predicate.h" #include "lldb/Utility/StructuredData.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-forward.h" // for EventDataSP, ProcessSP, Struct... +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" #include #include #include -#include // for size_t -#include // for uint32_t +#include +#include namespace lldb_private { class Event; @@ -271,4 +271,4 @@ private: } // namespace lldb_private -#endif // liblldb_Event_h_ +#endif // LLDB_UTILITY_EVENT_H diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/FastDemangle.h b/contrib/llvm/tools/lldb/include/lldb/Utility/FastDemangle.h deleted file mode 100644 index f779aaa04606..000000000000 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/FastDemangle.h +++ /dev/null @@ -1,26 +0,0 @@ -//===-- FastDemangle.h ------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_FastDemangle_h_ -#define liblldb_FastDemangle_h_ - -#include - -#include - -namespace lldb_private { - -char *FastDemangle(const char *mangled_name); - -char * -FastDemangle(const char *mangled_name, size_t mangled_name_length, - std::function primitive_type_hook = nullptr); -} - -#endif diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/FileSpec.h b/contrib/llvm/tools/lldb/include/lldb/Utility/FileSpec.h index d062ba598ccc..0699ab7b5c90 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/FileSpec.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/FileSpec.h @@ -10,13 +10,9 @@ #ifndef liblldb_FileSpec_h_ #define liblldb_FileSpec_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/ConstString.h" #include "llvm/ADT/StringRef.h" @@ -24,8 +20,8 @@ #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" -#include // for size_t -#include // for uint32_t, uint64_t +#include +#include namespace lldb_private { class Stream; @@ -70,23 +66,19 @@ public: /// /// Takes a path to a file which can be just a filename, or a full path. If /// \a path is not nullptr or empty, this function will call - /// FileSpec::SetFile (const char *path, bool resolve). + /// FileSpec::SetFile (const char *path). /// /// @param[in] path /// The full or partial path to a file. /// - /// @param[in] resolve_path - /// If \b true, then we resolve the path, removing stray ../.. and so - /// forth, - /// if \b false we trust the path is in canonical form already. + /// @param[in] style + /// The style of the path /// - /// @see FileSpec::SetFile (const char *path, bool resolve) + /// @see FileSpec::SetFile (const char *path) //------------------------------------------------------------------ - explicit FileSpec(llvm::StringRef path, bool resolve_path, - Style style = Style::native); + explicit FileSpec(llvm::StringRef path, Style style = Style::native); - explicit FileSpec(llvm::StringRef path, bool resolve_path, - const llvm::Triple &Triple); + explicit FileSpec(llvm::StringRef path, const llvm::Triple &Triple); //------------------------------------------------------------------ /// Copy constructor @@ -272,47 +264,6 @@ public: //------------------------------------------------------------------ void Dump(Stream *s) const; - //------------------------------------------------------------------ - /// Existence test. - /// - /// @return - /// \b true if the file exists on disk, \b false otherwise. - //------------------------------------------------------------------ - bool Exists() const; - - //------------------------------------------------------------------ - /// Check if a file is readable by the current user - /// - /// @return - /// \b true if the file exists on disk and is readable, \b false - /// otherwise. - //------------------------------------------------------------------ - bool Readable() const; - - //------------------------------------------------------------------ - /// Expanded existence test. - /// - /// Call into the Host to see if it can help find the file (e.g. by - /// searching paths set in the environment, etc.). - /// - /// If found, sets the value of m_directory to the directory where the file - /// was found. - /// - /// @return - /// \b true if was able to find the file using expanded search - /// methods, \b false otherwise. - //------------------------------------------------------------------ - bool ResolveExecutableLocation(); - - //------------------------------------------------------------------ - /// Canonicalize this file path (basically running the static - /// FileSpec::Resolve method on it). Useful if you asked us not to resolve - /// the file path when you set the file. - //------------------------------------------------------------------ - bool ResolvePath(); - - uint64_t GetByteSize() const; - Style GetPathStyle() const; //------------------------------------------------------------------ @@ -375,6 +326,9 @@ public: //------------------------------------------------------------------ bool IsAbsolute() const; + /// Temporary helper for FileSystem change. + void SetPath(llvm::StringRef p) { SetFile(p); } + //------------------------------------------------------------------ /// Extract the full path to the file. /// @@ -449,19 +403,6 @@ public: //------------------------------------------------------------------ ConstString GetFileNameStrippingExtension() const; - //------------------------------------------------------------------ - /// Return the current permissions of the path. - /// - /// Returns a bitmask for the current permissions of the file ( zero or more - /// of the permission bits defined in File::Permissions). - /// - /// @return - /// Zero if the file doesn't exist or we are unable to get - /// information for the file, otherwise one or more permission - /// bits from the File::Permissions enumeration. - //------------------------------------------------------------------ - uint32_t GetPermissions() const; - //------------------------------------------------------------------ /// Get the memory cost of this object. /// @@ -490,10 +431,9 @@ public: /// If \b true, then we will try to resolve links the path using /// the static FileSpec::Resolve. //------------------------------------------------------------------ - void SetFile(llvm::StringRef path, bool resolve_path, Style style); + void SetFile(llvm::StringRef path, Style style); - void SetFile(llvm::StringRef path, bool resolve_path, - const llvm::Triple &Triple); + void SetFile(llvm::StringRef path, const llvm::Triple &Triple); bool IsResolved() const { return m_is_resolved; } @@ -512,16 +452,6 @@ public: //------------------------------------------------------------------ void SetIsResolved(bool is_resolved) { m_is_resolved = is_resolved; } - //------------------------------------------------------------------ - /// Resolves user name and links in \a path, and overwrites the input - /// argument with the resolved path. - /// - /// @param[in] path - /// Input path to be resolved, in the form of a llvm::SmallString or - /// similar. - //------------------------------------------------------------------ - static void Resolve(llvm::SmallVectorImpl &path); - FileSpec CopyByAppendingPathComponent(llvm::StringRef component) const; FileSpec CopyByRemovingLastPathComponent() const; @@ -542,32 +472,11 @@ public: ConstString GetLastPathComponent() const; - enum EnumerateDirectoryResult { - eEnumerateDirectoryResultNext, // Enumerate next entry in the current - // directory - eEnumerateDirectoryResultEnter, // Recurse into the current entry if it is a - // directory or symlink, or next if not - eEnumerateDirectoryResultQuit // Stop directory enumerations at any level - }; - - typedef EnumerateDirectoryResult (*EnumerateDirectoryCallbackType)( - void *baton, llvm::sys::fs::file_type file_type, const FileSpec &spec); - - static void EnumerateDirectory(llvm::StringRef dir_path, - bool find_directories, bool find_files, - bool find_other, - EnumerateDirectoryCallbackType callback, - void *callback_baton); - - typedef std::function - DirectoryCallback; - protected: //------------------------------------------------------------------ // Convenience method for setting the file without changing the style. //------------------------------------------------------------------ - void SetFile(llvm::StringRef path, bool resolve_path); + void SetFile(llvm::StringRef path); //------------------------------------------------------------------ // Member variables diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Iterable.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Iterable.h index dcb340a05ef1..1b7ec89d6cf5 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Iterable.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Iterable.h @@ -10,12 +10,8 @@ #ifndef liblldb_Iterable_h_ #define liblldb_Iterable_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/LLDBAssert.h b/contrib/llvm/tools/lldb/include/lldb/Utility/LLDBAssert.h index 9d9f3ceefab0..e7448cdac545 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/LLDBAssert.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/LLDBAssert.h @@ -14,7 +14,8 @@ #define lldbassert(x) assert(x) #else #define lldbassert(x) \ - lldb_private::lldb_assert(x, #x, __FUNCTION__, __FILE__, __LINE__) + lldb_private::lldb_assert(static_cast(x), #x, __FUNCTION__, __FILE__, \ + __LINE__) #endif namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Listener.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Listener.h similarity index 92% rename from contrib/llvm/tools/lldb/include/lldb/Core/Listener.h rename to contrib/llvm/tools/lldb/include/lldb/Utility/Listener.h index 3d12f8fb3391..11f89d7aeec2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Listener.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Listener.h @@ -7,25 +7,25 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Select_h_ -#define liblldb_Select_h_ +#ifndef LLDB_UTILITY_LISTENER_H +#define LLDB_UTILITY_LISTENER_H -#include "lldb/Core/Broadcaster.h" // for Broadcaster::BroadcasterImplWP +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Timeout.h" -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN -#include "lldb/lldb-forward.h" // for BroadcasterManagerWP, EventSP +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" #include #include #include -#include // for owner_less, enable_shared_from_this +#include #include -#include // for micro +#include #include #include -#include // for size_t -#include // for uint32_t +#include +#include namespace lldb_private { class ConstString; @@ -158,4 +158,4 @@ private: } // namespace lldb_private -#endif // liblldb_Select_h_ +#endif // LLDB_UTILITY_LISTENER_H diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Log.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Log.h index 62776bdb281b..30b97f0137ef 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Log.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Log.h @@ -15,8 +15,8 @@ #include "lldb/lldb-defines.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringMap.h" // for StringMap -#include "llvm/ADT/StringRef.h" // for StringRef, StringLiteral +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/ManagedStatic.h" @@ -25,9 +25,9 @@ #include #include #include -#include // for shared_ptr -#include // for string -#include // for forward +#include +#include +#include namespace llvm { class raw_ostream; diff --git a/contrib/llvm/tools/lldb/include/lldb/Host/Predicate.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Predicate.h similarity index 96% rename from contrib/llvm/tools/lldb/include/lldb/Host/Predicate.h rename to contrib/llvm/tools/lldb/include/lldb/Utility/Predicate.h index d8128e71c53e..d05f17131c68 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Host/Predicate.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Predicate.h @@ -10,16 +10,12 @@ #ifndef liblldb_Predicate_h_ #define liblldb_Predicate_h_ -// C Includes #include #include -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Timeout.h" #include "lldb/lldb-defines.h" @@ -34,11 +30,11 @@ typedef enum { eBroadcastNever, ///< No broadcast will be sent when the value is modified. eBroadcastAlways, ///< Always send a broadcast when the value is modified. eBroadcastOnChange ///< Only broadcast if the value changes when the value is - ///modified. + /// modified. } PredicateBroadcastType; //---------------------------------------------------------------------- -/// @class Predicate Predicate.h "lldb/Host/Predicate.h" +/// @class Predicate Predicate.h "lldb/Utility/Predicate.h" /// A C++ wrapper class for providing threaded access to a value of /// type T. /// @@ -220,8 +216,8 @@ protected: T m_value; ///< The templatized value T that we are protecting access to mutable std::mutex m_mutex; ///< The mutex to use when accessing the data std::condition_variable m_condition; ///< The pthread condition variable to - ///use for signaling that data available - ///or changed. + /// use for signaling that data available + /// or changed. private: //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Range.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Range.h deleted file mode 100644 index 60880dbdbc87..000000000000 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Range.h +++ /dev/null @@ -1,60 +0,0 @@ -//===--------------------- Range.h ------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef utility_Range_h_ -#define utility_Range_h_ - -#include - -namespace lldb_utility { - -class Range { -public: - typedef uint64_t ValueType; - - static const ValueType OPEN_END = UINT64_MAX; - - Range(const Range &rng); - - Range(ValueType low = 0, ValueType high = OPEN_END); - - Range &operator=(const Range &rhs); - - ValueType GetLow() { return m_low; } - - ValueType GetHigh() { return m_high; } - - void SetLow(ValueType low) { m_low = low; } - - void SetHigh(ValueType high) { m_high = high; } - - void Flip(); - - void Intersection(const Range &other); - - void Union(const Range &other); - - typedef bool (*RangeCallback)(ValueType index); - - void Iterate(RangeCallback callback); - - ValueType GetSize(); - - bool IsEmpty(); - -private: - void InitRange(); - - ValueType m_low; - ValueType m_high; -}; - -} // namespace lldb_private - -#endif // #ifndef utility_Range_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/RegisterValue.h b/contrib/llvm/tools/lldb/include/lldb/Utility/RegisterValue.h similarity index 93% rename from contrib/llvm/tools/lldb/include/lldb/Core/RegisterValue.h rename to contrib/llvm/tools/lldb/include/lldb/Utility/RegisterValue.h index b369c3dff9a9..c025a26fb25a 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/RegisterValue.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/RegisterValue.h @@ -7,31 +7,23 @@ // //===----------------------------------------------------------------------===// -#ifndef lldb_RegisterValue_h -#define lldb_RegisterValue_h +#ifndef LLDB_UTILITY_REGISTERVALUE_H +#define LLDB_UTILITY_REGISTERVALUE_H -#include "lldb/Core/Scalar.h" #include "lldb/Utility/Endian.h" -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-enumerations.h" // for ByteOrder, Format -#include "lldb/lldb-types.h" // for offset_t - +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-types.h" #include "llvm/ADT/APInt.h" -#include "llvm/ADT/StringRef.h" // for StringRef - -#include // for uint32_t, uint8_t, uint64_t, uin... -#include +#include "llvm/ADT/StringRef.h" +#include +#include namespace lldb_private { class DataExtractor; -} -namespace lldb_private { class Stream; -} -namespace lldb_private { struct RegisterInfo; -} -namespace lldb_private { class RegisterValue { public: @@ -276,4 +268,4 @@ protected: } // namespace lldb_private -#endif // lldb_RegisterValue_h +#endif // LLDB_UTILITY_REGISTERVALUE_H diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/RegularExpression.h b/contrib/llvm/tools/lldb/include/lldb/Utility/RegularExpression.h index 6048fcc610a3..b379c6e8bea1 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/RegularExpression.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/RegularExpression.h @@ -40,7 +40,7 @@ inline void regfree(llvm_regex_t *a) { llvm_regfree(a); } #include #include -#include // for size_t +#include #include namespace llvm { diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Reproducer.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Reproducer.h new file mode 100644 index 000000000000..ea315ad771a6 --- /dev/null +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Reproducer.h @@ -0,0 +1,215 @@ +//===-- Reproducer.h --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_UTILITY_REPRODUCER_H +#define LLDB_UTILITY_REPRODUCER_H + +#include "lldb/Utility/FileSpec.h" + +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/YAMLTraits.h" + +#include +#include +#include + +namespace lldb_private { +namespace repro { + +class Reproducer; + +enum class ReproducerMode { + Capture, + Replay, + Off, +}; + +/// Abstraction for information associated with a provider. This information +/// is serialized into an index which is used by the loader. +struct ProviderInfo { + std::string name; + std::vector files; +}; + +/// The provider defines an interface for generating files needed for +/// reproducing. The provider must populate its ProviderInfo to communicate +/// its name and files to the index, before registering with the generator, +/// i.e. in the constructor. +/// +/// Different components will implement different providers. +class ProviderBase { +public: + virtual ~ProviderBase() = default; + + const ProviderInfo &GetInfo() const { return m_info; } + const FileSpec &GetRoot() const { return m_root; } + + /// The Keep method is called when it is decided that we need to keep the + /// data in order to provide a reproducer. + virtual void Keep(){}; + + /// The Discard method is called when it is decided that we do not need to + /// keep any information and will not generate a reproducer. + virtual void Discard(){}; + + // Returns the class ID for this type. + static const void *ClassID() { return &ID; } + + // Returns the class ID for the dynamic type of this Provider instance. + virtual const void *DynamicClassID() const = 0; + +protected: + ProviderBase(const FileSpec &root) : m_root(root) {} + + /// Every provider keeps track of its own files. + ProviderInfo m_info; +private: + /// Every provider knows where to dump its potential files. + FileSpec m_root; + + virtual void anchor(); + static char ID; +}; + +template class Provider : public ProviderBase { +public: + static const void *ClassID() { return &ThisProviderT::ID; } + + const void *DynamicClassID() const override { return &ThisProviderT::ID; } + +protected: + using ProviderBase::ProviderBase; // Inherit constructor. +}; + +/// The generator is responsible for the logic needed to generate a +/// reproducer. For doing so it relies on providers, who serialize data that +/// is necessary for reproducing a failure. +class Generator final { +public: + Generator(const FileSpec &root); + ~Generator(); + + /// Method to indicate we want to keep the reproducer. If reproducer + /// generation is disabled, this does nothing. + void Keep(); + + /// Method to indicate we do not want to keep the reproducer. This is + /// unaffected by whether or not generation reproduction is enabled, as we + /// might need to clean up files already written to disk. + void Discard(); + + /// Create and register a new provider. + template T *Create() { + std::unique_ptr provider = llvm::make_unique(m_root); + return static_cast(Register(std::move(provider))); + } + + /// Get an existing provider. + template T *Get() { + auto it = m_providers.find(T::ClassID()); + if (it == m_providers.end()) + return nullptr; + return static_cast(it->second.get()); + } + + /// Get a provider if it exists, otherwise create it. + template T &GetOrCreate() { + auto *provider = Get(); + if (provider) + return *provider; + return *Create(); + } + + const FileSpec &GetRoot() const; + +private: + friend Reproducer; + + ProviderBase *Register(std::unique_ptr provider); + + /// Builds and index with provider info. + void AddProvidersToIndex(); + + /// Map of provider IDs to provider instances. + llvm::DenseMap> m_providers; + std::mutex m_providers_mutex; + + /// The reproducer root directory. + FileSpec m_root; + + /// Flag to ensure that we never call both keep and discard. + bool m_done; +}; + +class Loader final { +public: + Loader(const FileSpec &root); + + llvm::Optional GetProviderInfo(llvm::StringRef name); + llvm::Error LoadIndex(); + + const FileSpec &GetRoot() const { return m_root; } + +private: + llvm::StringMap m_provider_info; + FileSpec m_root; + bool m_loaded; +}; + +/// The reproducer enables clients to obtain access to the Generator and +/// Loader. +class Reproducer { +public: + static Reproducer &Instance(); + static llvm::Error Initialize(ReproducerMode mode, + llvm::Optional root); + static void Terminate(); + + Reproducer() = default; + + Generator *GetGenerator(); + Loader *GetLoader(); + + const Generator *GetGenerator() const; + const Loader *GetLoader() const; + + FileSpec GetReproducerPath() const; + +protected: + llvm::Error SetCapture(llvm::Optional root); + llvm::Error SetReplay(llvm::Optional root); + +private: + static llvm::Optional &InstanceImpl(); + + llvm::Optional m_generator; + llvm::Optional m_loader; + + mutable std::mutex m_mutex; +}; + +} // namespace repro +} // namespace lldb_private + +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(lldb_private::repro::ProviderInfo) + +namespace llvm { +namespace yaml { + +template <> struct MappingTraits { + static void mapping(IO &io, lldb_private::repro::ProviderInfo &info) { + io.mapRequired("name", info.name); + io.mapOptional("files", info.files); + } +}; +} // namespace yaml +} // namespace llvm + +#endif // LLDB_UTILITY_REPRODUCER_H diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/Scalar.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Scalar.h similarity index 97% rename from contrib/llvm/tools/lldb/include/lldb/Core/Scalar.h rename to contrib/llvm/tools/lldb/include/lldb/Utility/Scalar.h index 40671a242ec3..c23b2f8be25e 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/Scalar.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Scalar.h @@ -7,25 +7,21 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_Scalar_h_ -#define liblldb_Scalar_h_ - -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-enumerations.h" // for Encoding, ByteOrder -#include "lldb/lldb-private-types.h" // for type128 +#ifndef LLDB_UTILITY_SCALAR_H +#define LLDB_UTILITY_SCALAR_H +#include "lldb/Utility/Status.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private-types.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" - -#include // for size_t -#include // for uint32_t, uint64_t, int64_t +#include +#include namespace lldb_private { class DataExtractor; -} -namespace lldb_private { class Stream; -} +} // namespace lldb_private #define NUM_OF_WORDS_INT128 2 #define BITWIDTH_INT128 128 @@ -375,4 +371,4 @@ bool operator>=(const Scalar &lhs, const Scalar &rhs); } // namespace lldb_private -#endif // liblldb_Scalar_h_ +#endif // LLDB_UTILITY_SCALAR_H diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/SelectHelper.h b/contrib/llvm/tools/lldb/include/lldb/Utility/SelectHelper.h index 004952f1c598..f2dac7cf53da 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/SelectHelper.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/SelectHelper.h @@ -10,8 +10,8 @@ #ifndef liblldb_SelectHelper_h_ #define liblldb_SelectHelper_h_ -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-types.h" // for socket_t +#include "lldb/Utility/Status.h" +#include "lldb/lldb-types.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/SharingPtr.h b/contrib/llvm/tools/lldb/include/lldb/Utility/SharingPtr.h index 691c92afaaae..7eaa049f4d18 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/SharingPtr.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/SharingPtr.h @@ -10,8 +10,6 @@ #ifndef utility_SharingPtr_h_ #define utility_SharingPtr_h_ -// C Includes -// C++ Includes #include // Microsoft Visual C++ currently does not enable std::atomic to work in CLR @@ -25,8 +23,6 @@ #include -// Other libraries and framework includes -// Project includes //#define ENABLE_SP_LOGGING 1 // DON'T CHECK THIS LINE IN UNLESS COMMENTED OUT #if defined(ENABLE_SP_LOGGING) diff --git a/contrib/llvm/tools/lldb/include/lldb/Core/State.h b/contrib/llvm/tools/lldb/include/lldb/Utility/State.h similarity index 90% rename from contrib/llvm/tools/lldb/include/lldb/Core/State.h rename to contrib/llvm/tools/lldb/include/lldb/Utility/State.h index 68f0fee254b3..7b3c0f1c17ab 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Core/State.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/State.h @@ -7,16 +7,14 @@ // //===----------------------------------------------------------------------===// -#ifndef liblldb_State_h_ -#define liblldb_State_h_ +#ifndef LLDB_UTILITY_STATE_H +#define LLDB_UTILITY_STATE_H +#include "lldb/lldb-enumerations.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/FormatProviders.h" - -#include "lldb/lldb-enumerations.h" // for StateType -#include "llvm/ADT/StringRef.h" // for StringRef -#include "llvm/Support/raw_ostream.h" // for raw_ostream - -#include // for uint32_t +#include "llvm/Support/raw_ostream.h" +#include namespace lldb_private { @@ -80,6 +78,6 @@ template <> struct format_provider { Stream << lldb_private::StateAsCString(state); } }; -} +} // namespace llvm -#endif // liblldb_State_h_ +#endif // LLDB_UTILITY_STATE_H diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Status.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Status.h index 3bd2cd5b3b41..9395ea86090b 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Status.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Status.h @@ -11,15 +11,15 @@ #define LLDB_UTILITY_STATUS_H #include "lldb/lldb-defines.h" -#include "lldb/lldb-enumerations.h" // for ErrorType, ErrorType... -#include "llvm/ADT/StringRef.h" // for StringRef +#include "lldb/lldb-enumerations.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include -#include // for uint32_t +#include #include -#include // for error_code -#include // for forward +#include +#include namespace llvm { class raw_ostream; diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Stream.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Stream.h index 4930521d9497..bd4283edf8a9 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Stream.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Stream.h @@ -12,14 +12,15 @@ #include "lldb/Utility/Flags.h" #include "lldb/lldb-defines.h" -#include "lldb/lldb-enumerations.h" // for ByteOrder::eByteOrderInvalid -#include "llvm/ADT/StringRef.h" // for StringRef +#include "lldb/lldb-enumerations.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" #include -#include // for size_t -#include // for uint32_t, uint64_t, uint8_t -#include // for forward +#include +#include +#include namespace lldb_private { @@ -37,6 +38,25 @@ public: /// string mode. }; + /// Utility class for counting the bytes that were written to a stream in a + /// certain time span. + /// @example + /// ByteDelta delta(*this); + /// WriteDataToStream("foo"); + /// return *delta; + /// @endcode + class ByteDelta { + Stream *m_stream; + /// Bytes we have written so far when ByteDelta was created. + size_t m_start; + + public: + ByteDelta(Stream &s) : m_stream(&s), m_start(s.GetWrittenBytes()) {} + /// Returns the number of bytes written to the given Stream since this + /// ByteDelta object was created. + size_t operator*() const { return m_stream->GetWrittenBytes() - m_start; } + }; + //------------------------------------------------------------------ /// Construct with flags and address size and byte order. /// @@ -52,6 +72,17 @@ public: //------------------------------------------------------------------ Stream(); + // FIXME: Streams should not be copyable. + Stream(const Stream &other) : m_forwarder(*this) { (*this) = other; } + + Stream &operator=(const Stream &rhs) { + m_flags = rhs.m_flags; + m_addr_size = rhs.m_addr_size; + m_byte_order = rhs.m_byte_order; + m_indent_level = rhs.m_indent_level; + return *this; + } + //------------------------------------------------------------------ /// Destructor //------------------------------------------------------------------ @@ -83,7 +114,13 @@ public: /// @return /// The number of bytes that were appended to the stream. //------------------------------------------------------------------ - virtual size_t Write(const void *src, size_t src_len) = 0; + size_t Write(const void *src, size_t src_len) { + size_t appended_byte_count = WriteImpl(src, src_len); + m_bytes_written += appended_byte_count; + return appended_byte_count; + } + + size_t GetWrittenBytes() const { return m_bytes_written; } //------------------------------------------------------------------ // Member functions @@ -121,14 +158,10 @@ public: __attribute__((__format__(__printf__, 2, 3))); //------------------------------------------------------------------ - /// Format a C string from a printf style format and variable arguments and - /// encode and append the resulting C string as hex bytes. + /// Append an uint8_t value in the hexadecimal format to the stream. /// - /// @param[in] format - /// A printf style format string. - /// - /// @param[in] ... - /// Any additional arguments needed for the printf format string. + /// @param[in] uvalue + /// The value to append. /// /// @return /// The number of bytes that were appended to the stream. @@ -504,9 +537,6 @@ public: /// /// @param[in] uval /// A uint64_t value that was extracted as a SLEB128 value. - /// - /// @param[in] format - /// The optional printf format that can be overridden. //------------------------------------------------------------------ size_t PutSLEB128(int64_t uval); @@ -518,12 +548,16 @@ public: /// /// @param[in] uval /// A uint64_t value that was extracted as a ULEB128 value. - /// - /// @param[in] format - /// The optional printf format that can be overridden. //------------------------------------------------------------------ size_t PutULEB128(uint64_t uval); + //------------------------------------------------------------------ + /// Returns a raw_ostream that forwards the data to this Stream object. + //------------------------------------------------------------------ + llvm::raw_ostream &AsRawOstream() { + return m_forwarder; + } + protected: //------------------------------------------------------------------ // Member variables @@ -533,8 +567,53 @@ protected: lldb::ByteOrder m_byte_order; ///< Byte order to use when encoding scalar types. int m_indent_level; ///< Indention level. + std::size_t m_bytes_written = 0; ///< Number of bytes written so far. - size_t _PutHex8(uint8_t uvalue, bool add_prefix); + void _PutHex8(uint8_t uvalue, bool add_prefix); + + //------------------------------------------------------------------ + /// Output character bytes to the stream. + /// + /// Appends \a src_len characters from the buffer \a src to the stream. + /// + /// @param[in] src + /// A buffer containing at least \a src_len bytes of data. + /// + /// @param[in] src_len + /// A number of bytes to append to the stream. + /// + /// @return + /// The number of bytes that were appended to the stream. + //------------------------------------------------------------------ + virtual size_t WriteImpl(const void *src, size_t src_len) = 0; + + //---------------------------------------------------------------------- + /// @class RawOstreamForward Stream.h "lldb/Utility/Stream.h" + /// This is a wrapper class that exposes a raw_ostream interface that just + /// forwards to an LLDB stream, allowing to reuse LLVM algorithms that take + /// a raw_ostream within the LLDB code base. + //---------------------------------------------------------------------- + class RawOstreamForward : public llvm::raw_ostream { + // Note: This stream must *not* maintain its own buffer, but instead + // directly write everything to the internal Stream class. Without this, + // we would run into the problem that the Stream written byte count would + // differ from the actually written bytes by the size of the internal + // raw_ostream buffer. + + Stream &m_target; + void write_impl(const char *Ptr, size_t Size) override { + m_target.Write(Ptr, Size); + } + + uint64_t current_pos() const override { + return m_target.GetWrittenBytes(); + } + + public: + RawOstreamForward(Stream &target) + : llvm::raw_ostream(/*unbuffered*/ true), m_target(target) {} + }; + RawOstreamForward m_forwarder; }; } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StreamCallback.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StreamCallback.h index 0aa9d5d57b2f..63a86eeece73 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StreamCallback.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StreamCallback.h @@ -13,8 +13,8 @@ #include "lldb/lldb-types.h" #include "llvm/Support/raw_ostream.h" -#include // for size_t -#include // for uint64_t +#include +#include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StreamGDBRemote.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StreamGDBRemote.h index 79234cc03d86..dfc4a39de791 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StreamGDBRemote.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StreamGDBRemote.h @@ -10,11 +10,11 @@ #ifndef liblldb_StreamGDBRemote_h_ #define liblldb_StreamGDBRemote_h_ -#include "lldb/Utility/StreamString.h" // for StreamString -#include "lldb/lldb-enumerations.h" // for ByteOrder +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-enumerations.h" -#include // for size_t -#include // for uint32_t +#include +#include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StreamString.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StreamString.h index 0ae3e82a3498..dd2f9f67466e 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StreamString.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StreamString.h @@ -10,14 +10,14 @@ #ifndef liblldb_StreamString_h_ #define liblldb_StreamString_h_ -#include "lldb/Utility/Stream.h" // for Stream -#include "lldb/lldb-enumerations.h" // for ByteOrder -#include "llvm/ADT/StringRef.h" // for StringRef +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-enumerations.h" +#include "llvm/ADT/StringRef.h" -#include // for string +#include -#include // for size_t -#include // for uint32_t +#include +#include namespace lldb_private { @@ -31,8 +31,6 @@ public: void Flush() override; - size_t Write(const void *s, size_t length) override; - void Clear(); bool Empty() const; @@ -49,6 +47,7 @@ public: protected: std::string m_packet; + size_t WriteImpl(const void *s, size_t length) override; }; } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StreamTee.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StreamTee.h index 569ba1979978..4f8e6ab1f002 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StreamTee.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StreamTee.h @@ -70,29 +70,6 @@ public: } } - size_t Write(const void *s, size_t length) override { - std::lock_guard guard(m_streams_mutex); - if (m_streams.empty()) - return 0; - - size_t min_bytes_written = SIZE_MAX; - collection::iterator pos, end; - for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos) { - // Allow for our collection to contain NULL streams. This allows the - // StreamTee to be used with hard coded indexes for clients that might - // want N total streams with only a few that are set to valid values. - Stream *strm = pos->get(); - if (strm) { - const size_t bytes_written = strm->Write(s, length); - if (min_bytes_written > bytes_written) - min_bytes_written = bytes_written; - } - } - if (min_bytes_written == SIZE_MAX) - return 0; - return min_bytes_written; - } - size_t AppendStream(const lldb::StreamSP &stream_sp) { size_t new_idx = m_streams.size(); std::lock_guard guard(m_streams_mutex); @@ -131,6 +108,29 @@ protected: typedef std::vector collection; mutable std::recursive_mutex m_streams_mutex; collection m_streams; + + size_t WriteImpl(const void *s, size_t length) override { + std::lock_guard guard(m_streams_mutex); + if (m_streams.empty()) + return 0; + + size_t min_bytes_written = SIZE_MAX; + collection::iterator pos, end; + for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos) { + // Allow for our collection to contain NULL streams. This allows the + // StreamTee to be used with hard coded indexes for clients that might + // want N total streams with only a few that are set to valid values. + Stream *strm = pos->get(); + if (strm) { + const size_t bytes_written = strm->Write(s, length); + if (min_bytes_written > bytes_written) + min_bytes_written = bytes_written; + } + } + if (min_bytes_written == SIZE_MAX) + return 0; + return min_bytes_written; + } }; } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StringExtractor.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StringExtractor.h index 4b75d5c5484d..bc24c153bae6 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StringExtractor.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StringExtractor.h @@ -10,12 +10,10 @@ #ifndef utility_StringExtractor_h_ #define utility_StringExtractor_h_ -// Other libraries and framework includes -// Project includes #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -#include // for size_t +#include #include #include diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StringExtractorGDBRemote.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StringExtractorGDBRemote.h index 93e760b88112..8c2eca898e64 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StringExtractorGDBRemote.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StringExtractorGDBRemote.h @@ -12,12 +12,12 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/StringExtractor.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" #include -#include // for size_t -#include // for uint8_t +#include +#include class StringExtractorGDBRemote : public StringExtractor { public: diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StringLexer.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StringLexer.h index e4fc81a85e0d..32cfa4e3f6f2 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StringLexer.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StringLexer.h @@ -1,5 +1,4 @@ -//===--------------------- StringLexer.h -------------------------*- C++ -//-*-===// +//===--------------------- StringLexer.h ------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,9 +10,9 @@ #ifndef utility_StringLexer_h_ #define utility_StringLexer_h_ -#include // for initializer_list -#include // for string -#include // for pair +#include +#include +#include namespace lldb_utility { diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StringList.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StringList.h index 1cb68885e771..c080230249dd 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StringList.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StringList.h @@ -12,7 +12,7 @@ #include "llvm/ADT/StringRef.h" -#include // for size_t +#include #include #include diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/StructuredData.h b/contrib/llvm/tools/lldb/include/lldb/Utility/StructuredData.h index d3ebab16f51d..100b4fa98ae1 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/StructuredData.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/StructuredData.h @@ -13,17 +13,17 @@ #include "llvm/ADT/StringRef.h" #include "lldb/Utility/ConstString.h" -#include "lldb/Utility/FileSpec.h" // for FileSpec -#include "lldb/lldb-enumerations.h" // for StructuredDataType +#include "lldb/Utility/FileSpec.h" +#include "lldb/lldb-enumerations.h" -#include // for assert -#include // for size_t -#include // for uint64_t +#include +#include +#include #include #include #include #include -#include // for move +#include #include #include @@ -170,7 +170,7 @@ public: bool ForEach(std::function const &foreach_callback) const { for (const auto &object_sp : m_items) { - if (foreach_callback(object_sp.get()) == false) + if (!foreach_callback(object_sp.get())) return false; } return true; @@ -359,7 +359,7 @@ public: void ForEach(std::function const &callback) const { for (const auto &pair : m_dict) { - if (callback(pair.first, pair.second.get()) == false) + if (!callback(pair.first, pair.second.get())) break; } } diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/Timer.h b/contrib/llvm/tools/lldb/include/lldb/Utility/Timer.h index 2c1e984837c2..7c41c6257254 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/Timer.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/Timer.h @@ -10,10 +10,10 @@ #ifndef liblldb_Timer_h_ #define liblldb_Timer_h_ -#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN +#include "lldb/lldb-defines.h" #include "llvm/Support/Chrono.h" #include -#include // for uint32_t +#include namespace lldb_private { class Stream; diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/UUID.h b/contrib/llvm/tools/lldb/include/lldb/Utility/UUID.h index d42c88862bfa..e082db572e46 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/UUID.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/UUID.h @@ -10,8 +10,6 @@ #ifndef LLDB_UTILITY_UUID_H #define LLDB_UTILITY_UUID_H -// C Includes -// C++ Includes #include #include #include diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/UserID.h b/contrib/llvm/tools/lldb/include/lldb/Utility/UserID.h index 9e15e6a43c6c..8560274bdeac 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/UserID.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/UserID.h @@ -10,8 +10,8 @@ #ifndef liblldb_UserID_h_ #define liblldb_UserID_h_ -#include "lldb/lldb-defines.h" // for LLDB_INVALID_UID -#include "lldb/lldb-types.h" // for user_id_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-types.h" namespace lldb_private { class Stream; } diff --git a/contrib/llvm/tools/lldb/include/lldb/Utility/VMRange.h b/contrib/llvm/tools/lldb/include/lldb/Utility/VMRange.h index 0e696907baa7..a70b0cb6118c 100644 --- a/contrib/llvm/tools/lldb/include/lldb/Utility/VMRange.h +++ b/contrib/llvm/tools/lldb/include/lldb/Utility/VMRange.h @@ -10,10 +10,10 @@ #ifndef liblldb_VMRange_h_ #define liblldb_VMRange_h_ -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/lldb-types.h" -#include // for size_t -#include // for uint32_t +#include +#include #include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/include/lldb/lldb-defines.h b/contrib/llvm/tools/lldb/include/lldb/lldb-defines.h index edb70be09fd9..8a54b4c44364 100644 --- a/contrib/llvm/tools/lldb/include/lldb/lldb-defines.h +++ b/contrib/llvm/tools/lldb/include/lldb/lldb-defines.h @@ -135,6 +135,7 @@ #define LLDB_OPT_SET_8 (1U << 7) #define LLDB_OPT_SET_9 (1U << 8) #define LLDB_OPT_SET_10 (1U << 9) +#define LLDB_OPT_SET_11 (1U << 10) #define LLDB_OPT_SET_FROM_TO(A, B) \ (((1U << (B)) - 1) ^ (((1U << (A)) - 1) >> 1)) diff --git a/contrib/llvm/tools/lldb/include/lldb/lldb-enumerations.h b/contrib/llvm/tools/lldb/include/lldb/lldb-enumerations.h index a1f730379534..1c4d6f509a2a 100644 --- a/contrib/llvm/tools/lldb/include/lldb/lldb-enumerations.h +++ b/contrib/llvm/tools/lldb/include/lldb/lldb-enumerations.h @@ -10,6 +10,42 @@ #ifndef LLDB_lldb_enumerations_h_ #define LLDB_lldb_enumerations_h_ +#include + +#ifndef SWIG +// Macro to enable bitmask operations on an enum. Without this, Enum | Enum +// gets promoted to an int, so you have to say Enum a = Enum(eFoo | eBar). If +// you mark Enum with LLDB_MARK_AS_BITMASK_ENUM(Enum), however, you can simply +// write Enum a = eFoo | eBar. +// Unfortunately, swig<3.0 doesn't recognise the constexpr keyword, so remove +// this entire block, as it is not necessary for swig processing. +#define LLDB_MARK_AS_BITMASK_ENUM(Enum) \ + constexpr Enum operator|(Enum a, Enum b) { \ + return static_cast( \ + static_cast::type>(a) | \ + static_cast::type>(b)); \ + } \ + constexpr Enum operator&(Enum a, Enum b) { \ + return static_cast( \ + static_cast::type>(a) & \ + static_cast::type>(b)); \ + } \ + constexpr Enum operator~(Enum a) { \ + return static_cast( \ + ~static_cast::type>(a)); \ + } \ + inline Enum &operator|=(Enum &a, Enum b) { \ + a = a | b; \ + return a; \ + } \ + inline Enum &operator&=(Enum &a, Enum b) { \ + a = a & b; \ + return a; \ + } +#else +#define LLDB_MARK_AS_BITMASK_ENUM(Enum) +#endif + #ifndef SWIG // With MSVC, the default type of an enum is always signed, even if one of the // enumerator values is too large to fit into a signed integer but would @@ -54,9 +90,10 @@ enum StateType { eStateCrashed, ///< Process or thread has crashed and can be examined. eStateDetached, ///< Process has been detached and can't be examined. eStateExited, ///< Process has exited and can't be examined. - eStateSuspended ///< Process or thread is in a suspended state as far + eStateSuspended, ///< Process or thread is in a suspended state as far ///< as the debugger is concerned while other processes ///< or threads get the chance to run. + kLastStateType = eStateSuspended }; //---------------------------------------------------------------------- @@ -256,6 +293,17 @@ enum ExpressionResults { eExpressionStoppedForDebug }; +enum SearchDepth { + eSearchDepthInvalid = 0, + eSearchDepthTarget, + eSearchDepthModule, + eSearchDepthCompUnit, + eSearchDepthFunction, + eSearchDepthBlock, + eSearchDepthAddress, + kLastSearchDepthKind = eSearchDepthAddress +}; + //---------------------------------------------------------------------- // Connection Status Types //---------------------------------------------------------------------- @@ -315,43 +363,45 @@ enum InputReaderGranularity { //------------------------------------------------------------------ FLAGS_ENUM(SymbolContextItem){ eSymbolContextTarget = (1u << 0), ///< Set when \a target is requested from - ///a query, or was located in query - ///results + /// a query, or was located in query + /// results eSymbolContextModule = (1u << 1), ///< Set when \a module is requested from - ///a query, or was located in query - ///results + /// a query, or was located in query + /// results eSymbolContextCompUnit = (1u << 2), ///< Set when \a comp_unit is requested - ///from a query, or was located in query - ///results + /// from a query, or was located in + /// query results eSymbolContextFunction = (1u << 3), ///< Set when \a function is requested - ///from a query, or was located in query - ///results + /// from a query, or was located in + /// query results eSymbolContextBlock = (1u << 4), ///< Set when the deepest \a block is - ///requested from a query, or was located - ///in query results + /// requested from a query, or was located + /// in query results eSymbolContextLineEntry = (1u << 5), ///< Set when \a line_entry is - ///requested from a query, or was - ///located in query results + /// requested from a query, or was + /// located in query results eSymbolContextSymbol = (1u << 6), ///< Set when \a symbol is requested from - ///a query, or was located in query - ///results + /// a query, or was located in query + /// results eSymbolContextEverything = ((eSymbolContextSymbol << 1) - 1u), ///< Indicates to try and lookup everything - ///up during a routine symbol context - ///query. - eSymbolContextVariable = (1u << 7) ///< Set when \a global or static - ///variable is requested from a query, or - ///was located in query results. + /// up during a routine symbol context + /// query. + eSymbolContextVariable = (1u << 7), ///< Set when \a global or static + /// variable is requested from a query, + /// or was located in query results. ///< eSymbolContextVariable is potentially expensive to lookup so it isn't - ///included in + /// included in ///< eSymbolContextEverything which stops it from being used during frame PC - ///lookups and + /// lookups and ///< many other potential address to symbol context lookups. }; +LLDB_MARK_AS_BITMASK_ENUM(SymbolContextItem) FLAGS_ENUM(Permissions){ePermissionsWritable = (1u << 0), ePermissionsReadable = (1u << 1), ePermissionsExecutable = (1u << 2)}; +LLDB_MARK_AS_BITMASK_ENUM(Permissions) enum InputReaderAction { eInputReaderActivate, // reader is newly pushed onto the reader stack @@ -661,7 +711,14 @@ enum SectionType { eSectionTypeDWARFGNUDebugAltLink, eSectionTypeDWARFDebugTypes, // DWARF .debug_types section eSectionTypeDWARFDebugNames, // DWARF v5 .debug_names - eSectionTypeOther + eSectionTypeOther, + eSectionTypeDWARFDebugLineStr, // DWARF v5 .debug_line_str + eSectionTypeDWARFDebugRngLists, // DWARF v5 .debug_rnglists + eSectionTypeDWARFDebugLocLists, // DWARF v5 .debug_loclists + eSectionTypeDWARFDebugAbbrevDwo, + eSectionTypeDWARFDebugInfoDwo, + eSectionTypeDWARFDebugStrDwo, + eSectionTypeDWARFDebugStrOffsetsDwo, }; FLAGS_ENUM(EmulateInstructionOptions){ @@ -689,6 +746,7 @@ FLAGS_ENUM(FunctionNameType){ eFunctionNameTypeAny = eFunctionNameTypeAuto // DEPRECATED: use eFunctionNameTypeAuto }; +LLDB_MARK_AS_BITMASK_ENUM(FunctionNameType) //---------------------------------------------------------------------- // Basic types enumeration for the public API SBType::GetBasicType() @@ -763,6 +821,7 @@ FLAGS_ENUM(TypeClass){ eTypeClassOther = (1u << 31), // Define a mask that can be used for any type when finding types eTypeClassAny = (0xffffffffu)}; +LLDB_MARK_AS_BITMASK_ENUM(TypeClass) enum TemplateArgumentKind { eTemplateArgumentKindNull = 0, @@ -1071,7 +1130,6 @@ enum TypeSummaryCapping { eTypeSummaryCapped = true, eTypeSummaryUncapped = false }; - } // namespace lldb #endif // LLDB_lldb_enumerations_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/lldb-forward.h b/contrib/llvm/tools/lldb/include/lldb/lldb-forward.h index e3964268dfda..92aa5bb611c3 100644 --- a/contrib/llvm/tools/lldb/include/lldb/lldb-forward.h +++ b/contrib/llvm/tools/lldb/include/lldb/lldb-forward.h @@ -107,7 +107,6 @@ class File; class FileSpec; class FileSpecList; class Flags; -class GoASTContext; class TypeCategoryImpl; class FormatManager; class FormattersMatchCandidate; @@ -126,13 +125,14 @@ class JITLoaderList; class Language; class LanguageCategory; class LanguageRuntime; -class MemoryRegionInfo; class LineTable; class Listener; class Log; class Mangled; class Materializer; class MemoryHistory; +class MemoryRegionInfo; +class MemoryRegionInfos; class Module; class ModuleList; class ModuleSpec; @@ -184,6 +184,7 @@ class ProcessInstanceInfoMatch; class ProcessLaunchInfo; class Property; struct PropertyDefinition; +class RecognizedStackFrame; class RegisterCheckpoint; class RegisterContext; class RegisterLocation; @@ -191,6 +192,7 @@ class RegisterLocationList; class RegisterValue; class RegularExpression; class REPL; +class RichManglingContext; class Scalar; class ScriptInterpreter; class ScriptInterpreterLocker; @@ -207,6 +209,8 @@ class SourceManagerImpl; class StackFrame; class StackFrameImpl; class StackFrameList; +class StackFrameRecognizer; +class StackFrameRecognizerManager; class StackID; class StopInfo; class Stoppoint; @@ -350,7 +354,6 @@ typedef std::shared_ptr FileSP; typedef std::shared_ptr FunctionSP; typedef std::shared_ptr FunctionCallerSP; typedef std::shared_ptr FuncUnwindersSP; -typedef std::unique_ptr GoASTContextUP; typedef std::shared_ptr InlineFunctionInfoSP; typedef std::shared_ptr InstructionSP; typedef std::shared_ptr @@ -367,7 +370,6 @@ typedef std::shared_ptr LineTableSP; typedef std::shared_ptr ListenerSP; typedef std::weak_ptr ListenerWP; typedef std::shared_ptr MemoryHistorySP; -typedef std::shared_ptr MemoryRegionInfoSP; typedef std::unique_ptr MemoryRegionInfoUP; typedef std::shared_ptr ModuleSP; typedef std::weak_ptr ModuleWP; @@ -413,6 +415,8 @@ typedef std::shared_ptr QueueSP; typedef std::weak_ptr QueueWP; typedef std::shared_ptr QueueItemSP; typedef std::shared_ptr REPLSP; +typedef std::shared_ptr + RecognizedStackFrameSP; typedef std::shared_ptr ScriptSummaryFormatSP; typedef std::shared_ptr ScriptInterpreterSP; @@ -428,6 +432,8 @@ typedef std::shared_ptr StackFrameSP; typedef std::unique_ptr StackFrameUP; typedef std::weak_ptr StackFrameWP; typedef std::shared_ptr StackFrameListSP; +typedef std::shared_ptr + StackFrameRecognizerSP; typedef std::shared_ptr StopInfoSP; typedef std::shared_ptr StoppointLocationSP; typedef std::shared_ptr StreamSP; @@ -492,5 +498,15 @@ typedef std::shared_ptr WatchpointSP; } // namespace lldb +//---------------------------------------------------------------------- +// llvm forward declarations +//---------------------------------------------------------------------- +namespace llvm { + +struct ItaniumPartialDemangler; +class StringRef; + +} // namespace llvm + #endif // #if defined(__cplusplus) #endif // LLDB_lldb_forward_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/lldb-private-forward.h b/contrib/llvm/tools/lldb/include/lldb/lldb-private-forward.h index 65d303281164..975d92d95727 100644 --- a/contrib/llvm/tools/lldb/include/lldb/lldb-private-forward.h +++ b/contrib/llvm/tools/lldb/include/lldb/lldb-private-forward.h @@ -10,26 +10,15 @@ #ifndef LLDB_lldb_private_forward_h_ #define LLDB_lldb_private_forward_h_ -#if defined(__cplusplus) - -#include - namespace lldb_private { // --------------------------------------------------------------- Class // forward decls. // --------------------------------------------------------------- -class NativeBreakpoint; -class NativeBreakpointList; class NativeProcessProtocol; class NativeRegisterContext; class NativeThreadProtocol; class ResumeActionList; class UnixSignals; - -// --------------------------------------------------------------- SP/WP decls. -// --------------------------------------------------------------- -typedef std::shared_ptr NativeBreakpointSP; } -#endif // #if defined(__cplusplus) #endif // #ifndef LLDB_lldb_private_forward_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/lldb-private-interfaces.h b/contrib/llvm/tools/lldb/include/lldb/lldb-private-interfaces.h index 806068ece7b6..76a9fad9f135 100644 --- a/contrib/llvm/tools/lldb/include/lldb/lldb-private-interfaces.h +++ b/contrib/llvm/tools/lldb/include/lldb/lldb-private-interfaces.h @@ -84,10 +84,10 @@ typedef void (*OptionValueChangedCallback)(void *baton, OptionValue *option_value); typedef bool (*ThreadPlanShouldStopHereCallback)( ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, - void *baton); + Status &status, void *baton); typedef lldb::ThreadPlanSP (*ThreadPlanStepFromHereCallback)( ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, - void *baton); + Status &status, void *baton); typedef UnwindAssembly *(*UnwindAssemblyCreateInstance)(const ArchSpec &arch); typedef lldb::MemoryHistorySP (*MemoryHistoryCreateInstance)( const lldb::ProcessSP &process_sp); diff --git a/contrib/llvm/tools/lldb/include/lldb/lldb-private-types.h b/contrib/llvm/tools/lldb/include/lldb/lldb-private-types.h index 7ba7350e868c..e0f0e413cef4 100644 --- a/contrib/llvm/tools/lldb/include/lldb/lldb-private-types.h +++ b/contrib/llvm/tools/lldb/include/lldb/lldb-private-types.h @@ -95,6 +95,8 @@ struct OptionEnumValueElement { const char *usage; }; +using OptionEnumValues = llvm::ArrayRef; + struct OptionValidator { virtual ~OptionValidator() {} virtual bool IsValid(Platform &platform, @@ -112,9 +114,8 @@ struct OptionDefinition { int short_option; // Single character for this option. int option_has_arg; // no_argument, required_argument or optional_argument OptionValidator *validator; // If non-NULL, option is valid iff - // |validator->IsValid()|, otherwise always - // valid. - OptionEnumValueElement *enum_values; // If non-NULL an array of enum values. + // |validator->IsValid()|, otherwise always valid. + OptionEnumValues enum_values; // If not empty, an array of enum values. uint32_t completion_type; // Cookie the option class can use to do define the // argument completion. lldb::CommandArgumentType argument_type; // Type of argument this option takes diff --git a/contrib/llvm/tools/lldb/include/lldb/lldb-types.h b/contrib/llvm/tools/lldb/include/lldb/lldb-types.h index 79f441569304..09dfc5c8a5ed 100644 --- a/contrib/llvm/tools/lldb/include/lldb/lldb-types.h +++ b/contrib/llvm/tools/lldb/include/lldb/lldb-types.h @@ -47,7 +47,8 @@ typedef unsigned int __w64 socket_t; // Host socket type typedef void *thread_arg_t; // Host thread argument type typedef unsigned thread_result_t; // Host thread result type typedef thread_result_t (*thread_func_t)(void *); // Host thread function type -} +typedef void *pipe_t; // Host pipe type is HANDLE +} // namespace lldb #else @@ -65,6 +66,7 @@ typedef int socket_t; // Host socket type typedef void *thread_arg_t; // Host thread argument type typedef void *thread_result_t; // Host thread result type typedef void *(*thread_func_t)(void *); // Host thread function type +typedef int pipe_t; // Host pipe type } // namespace lldb #endif @@ -76,10 +78,11 @@ typedef bool (*CommandOverrideCallbackWithResult)( void *baton, const char **argv, lldb_private::CommandReturnObject &result); typedef bool (*ExpressionCancelCallback)(ExpressionEvaluationPhase phase, void *baton); -} +} // namespace lldb #define LLDB_INVALID_PROCESS ((lldb::process_t)-1) #define LLDB_INVALID_HOST_THREAD ((lldb::thread_t)NULL) +#define LLDB_INVALID_PIPE ((lldb::pipe_t)-1) namespace lldb { typedef uint64_t addr_t; @@ -91,6 +94,6 @@ typedef int32_t break_id_t; typedef int32_t watch_id_t; typedef void *opaque_compiler_type_t; typedef uint64_t queue_id_t; -} +} // namespace lldb #endif // LLDB_lldb_types_h_ diff --git a/contrib/llvm/tools/lldb/include/lldb/module.modulemap b/contrib/llvm/tools/lldb/include/lldb/module.modulemap index cec0428c1840..9c7f3e6f58e5 100644 --- a/contrib/llvm/tools/lldb/include/lldb/module.modulemap +++ b/contrib/llvm/tools/lldb/include/lldb/module.modulemap @@ -38,10 +38,10 @@ module lldb_Host { module PipeBase { header "Host/PipeBase.h" export * } module Pipe { header "Host/Pipe.h" export * } module PosixApi { header "Host/PosixApi.h" export * } - module Predicate { header "Host/Predicate.h" export * } module ProcessLauncher { header "Host/ProcessLauncher.h" export * } module ProcessRunLock { header "Host/ProcessRunLock.h" export * } module PseudoTerminal { header "Host/PseudoTerminal.h" export * } + module SafeMachO { header "Host/SafeMachO.h" export * } module SocketAddress { header "Host/SocketAddress.h" export * } module Socket { header "Host/Socket.h" export * } module StringConvert { header "Host/StringConvert.h" export * } diff --git a/contrib/llvm/tools/lldb/source/API/SBAddress.cpp b/contrib/llvm/tools/lldb/source/API/SBAddress.cpp index d12197e66ddd..09ec6c3f10db 100644 --- a/contrib/llvm/tools/lldb/source/API/SBAddress.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBAddress.cpp @@ -62,7 +62,7 @@ bool lldb::operator==(const SBAddress &lhs, const SBAddress &rhs) { } bool SBAddress::IsValid() const { - return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid(); + return m_opaque_ap != NULL && m_opaque_ap->IsValid(); } void SBAddress::Clear() { m_opaque_ap.reset(new Address()); } @@ -156,7 +156,7 @@ Address *SBAddress::operator->() { return m_opaque_ap.get(); } const Address *SBAddress::operator->() const { return m_opaque_ap.get(); } Address &SBAddress::ref() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new Address()); return *m_opaque_ap; } @@ -198,8 +198,9 @@ SBModule SBAddress::GetModule() { SBSymbolContext SBAddress::GetSymbolContext(uint32_t resolve_scope) { SBSymbolContext sb_sc; + SymbolContextItem scope = static_cast(resolve_scope); if (m_opaque_ap->IsValid()) - m_opaque_ap->CalculateSymbolContext(&sb_sc.ref(), resolve_scope); + m_opaque_ap->CalculateSymbolContext(&sb_sc.ref(), scope); return sb_sc; } diff --git a/contrib/llvm/tools/lldb/source/API/SBAttachInfo.cpp b/contrib/llvm/tools/lldb/source/API/SBAttachInfo.cpp index d6cb212dedf8..a74487a70fe3 100644 --- a/contrib/llvm/tools/lldb/source/API/SBAttachInfo.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBAttachInfo.cpp @@ -26,16 +26,14 @@ SBAttachInfo::SBAttachInfo(lldb::pid_t pid) SBAttachInfo::SBAttachInfo(const char *path, bool wait_for) : m_opaque_sp(new ProcessAttachInfo()) { if (path && path[0]) - m_opaque_sp->GetExecutableFile().SetFile(path, false, - FileSpec::Style::native); + m_opaque_sp->GetExecutableFile().SetFile(path, FileSpec::Style::native); m_opaque_sp->SetWaitForLaunch(wait_for); } SBAttachInfo::SBAttachInfo(const char *path, bool wait_for, bool async) : m_opaque_sp(new ProcessAttachInfo()) { if (path && path[0]) - m_opaque_sp->GetExecutableFile().SetFile(path, false, - FileSpec::Style::native); + m_opaque_sp->GetExecutableFile().SetFile(path, FileSpec::Style::native); m_opaque_sp->SetWaitForLaunch(wait_for); m_opaque_sp->SetAsync(async); } @@ -79,8 +77,7 @@ void SBAttachInfo::SetProcessPluginName(const char *plugin_name) { void SBAttachInfo::SetExecutable(const char *path) { if (path && path[0]) - m_opaque_sp->GetExecutableFile().SetFile(path, false, - FileSpec::Style::native); + m_opaque_sp->GetExecutableFile().SetFile(path, FileSpec::Style::native); else m_opaque_sp->GetExecutableFile().Clear(); } diff --git a/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp b/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp index 6a0ff9536c2c..b6720071e17c 100644 --- a/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBBreakpoint.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/API/SBBreakpoint.h" #include "lldb/API/SBBreakpointLocation.h" #include "lldb/API/SBDebugger.h" @@ -23,6 +19,8 @@ #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Breakpoint/BreakpointResolverScripted.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Address.h" #include "lldb/Core/Debugger.h" @@ -487,6 +485,40 @@ bool SBBreakpoint::GetDescription(SBStream &s, bool include_locations) { return false; } +SBError +SBBreakpoint::AddLocation(SBAddress &address) { + BreakpointSP bkpt_sp = GetSP(); + SBError error; + + if (!address.IsValid()) { + error.SetErrorString("Can't add an invalid address."); + return error; + } + + if (!bkpt_sp) { + error.SetErrorString("No breakpoint to add a location to."); + return error; + } + + if (!llvm::isa(bkpt_sp->GetResolver().get())) { + error.SetErrorString("Only a scripted resolver can add locations."); + return error; + } + + if (bkpt_sp->GetSearchFilter()->AddressPasses(address.ref())) + bkpt_sp->AddLocation(address.ref()); + else + { + StreamString s; + address.get()->Dump(&s, &bkpt_sp->GetTarget(), + Address::DumpStyleModuleWithFileAddress); + error.SetErrorStringWithFormat("Address: %s didn't pass the filter.", + s.GetData()); + } + return error; +} + + void SBBreakpoint ::SetCallback(SBBreakpointHitCallback callback, void *baton) { @@ -656,6 +688,13 @@ SBBreakpoint::GetNumBreakpointLocationsFromEvent(const lldb::SBEvent &event) { return num_locations; } +bool SBBreakpoint::IsHardware() const { + BreakpointSP bkpt_sp = GetSP(); + if (bkpt_sp) + return bkpt_sp->IsHardware(); + return false; +} + BreakpointSP SBBreakpoint::GetSP() const { return m_opaque_wp.lock(); } // This is simple collection of breakpoint id's and their target. diff --git a/contrib/llvm/tools/lldb/source/API/SBBreakpointName.cpp b/contrib/llvm/tools/lldb/source/API/SBBreakpointName.cpp index a6742e3b89ec..47bddd752346 100644 --- a/contrib/llvm/tools/lldb/source/API/SBBreakpointName.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBBreakpointName.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/API/SBBreakpointName.h" #include "lldb/API/SBDebugger.h" #include "lldb/API/SBError.h" @@ -168,11 +164,11 @@ const SBBreakpointName &SBBreakpointName::operator=(const SBBreakpointName &rhs) } bool SBBreakpointName::operator==(const lldb::SBBreakpointName &rhs) { - return *m_impl_up.get() == *rhs.m_impl_up.get(); + return *m_impl_up == *rhs.m_impl_up; } bool SBBreakpointName::operator!=(const lldb::SBBreakpointName &rhs) { - return *m_impl_up.get() != *rhs.m_impl_up.get(); + return *m_impl_up != *rhs.m_impl_up; } bool SBBreakpointName::IsValid() const { diff --git a/contrib/llvm/tools/lldb/source/API/SBBreakpointOptionCommon.cpp b/contrib/llvm/tools/lldb/source/API/SBBreakpointOptionCommon.cpp index 569b860a4235..c0618adb238a 100644 --- a/contrib/llvm/tools/lldb/source/API/SBBreakpointOptionCommon.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBBreakpointOptionCommon.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/API/SBBreakpointName.h" #include "lldb/API/SBBreakpointLocation.h" #include "lldb/API/SBDebugger.h" diff --git a/contrib/llvm/tools/lldb/source/API/SBBroadcaster.cpp b/contrib/llvm/tools/lldb/source/API/SBBroadcaster.cpp index 278576b5ddcd..7868c38a818a 100644 --- a/contrib/llvm/tools/lldb/source/API/SBBroadcaster.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBBroadcaster.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/Broadcaster.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/Log.h" #include "lldb/API/SBBroadcaster.h" diff --git a/contrib/llvm/tools/lldb/source/API/SBCommandInterpreter.cpp b/contrib/llvm/tools/lldb/source/API/SBCommandInterpreter.cpp index cbb514abb6fe..2a06e608c0b9 100644 --- a/contrib/llvm/tools/lldb/source/API/SBCommandInterpreter.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBCommandInterpreter.cpp @@ -7,17 +7,13 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-types.h" -#include "lldb/Core/Listener.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/Listener.h" #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandInterpreter.h" @@ -71,6 +67,14 @@ void SBCommandInterpreterRunOptions::SetEchoCommands(bool echo_commands) { m_opaque_up->SetEchoCommands(echo_commands); } +bool SBCommandInterpreterRunOptions::GetEchoCommentCommands() const { + return m_opaque_up->GetEchoCommentCommands(); +} + +void SBCommandInterpreterRunOptions::SetEchoCommentCommands(bool echo) { + m_opaque_up->SetEchoCommentCommands(echo); +} + bool SBCommandInterpreterRunOptions::GetPrintResults() const { return m_opaque_up->GetPrintResults(); } @@ -94,7 +98,7 @@ SBCommandInterpreterRunOptions::get() const { lldb_private::CommandInterpreterRunOptions & SBCommandInterpreterRunOptions::ref() const { - return *m_opaque_up.get(); + return *m_opaque_up; } class CommandPluginInterfaceImplementation : public CommandObjectParsed { @@ -269,6 +273,16 @@ void SBCommandInterpreter::HandleCommandsFromFile( int SBCommandInterpreter::HandleCompletion( const char *current_line, const char *cursor, const char *last_char, int match_start_point, int max_return_elements, SBStringList &matches) { + SBStringList dummy_descriptions; + return HandleCompletionWithDescriptions( + current_line, cursor, last_char, match_start_point, max_return_elements, + matches, dummy_descriptions); +} + +int SBCommandInterpreter::HandleCompletionWithDescriptions( + const char *current_line, const char *cursor, const char *last_char, + int match_start_point, int max_return_elements, SBStringList &matches, + SBStringList &descriptions) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); int num_completions = 0; @@ -296,13 +310,15 @@ int SBCommandInterpreter::HandleCompletion( match_start_point, max_return_elements); if (IsValid()) { - lldb_private::StringList lldb_matches; + lldb_private::StringList lldb_matches, lldb_descriptions; num_completions = m_opaque_ptr->HandleCompletion( current_line, cursor, last_char, match_start_point, max_return_elements, - lldb_matches); + lldb_matches, lldb_descriptions); - SBStringList temp_list(&lldb_matches); - matches.AppendList(temp_list); + SBStringList temp_matches_list(&lldb_matches); + matches.AppendList(temp_matches_list); + SBStringList temp_descriptions_list(&lldb_descriptions); + descriptions.AppendList(temp_descriptions_list); } if (log) log->Printf( @@ -312,6 +328,17 @@ int SBCommandInterpreter::HandleCompletion( return num_completions; } +int SBCommandInterpreter::HandleCompletionWithDescriptions( + const char *current_line, uint32_t cursor_pos, int match_start_point, + int max_return_elements, SBStringList &matches, + SBStringList &descriptions) { + const char *cursor = current_line + cursor_pos; + const char *last_char = current_line + strlen(current_line); + return HandleCompletionWithDescriptions( + current_line, cursor, last_char, match_start_point, max_return_elements, + matches, descriptions); +} + int SBCommandInterpreter::HandleCompletion(const char *current_line, uint32_t cursor_pos, int match_start_point, diff --git a/contrib/llvm/tools/lldb/source/API/SBCommandReturnObject.cpp b/contrib/llvm/tools/lldb/source/API/SBCommandReturnObject.cpp index 5a8909b98e53..7bc02985a3ec 100644 --- a/contrib/llvm/tools/lldb/source/API/SBCommandReturnObject.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBCommandReturnObject.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/API/SBCommandReturnObject.h" #include "lldb/API/SBError.h" #include "lldb/API/SBStream.h" @@ -52,9 +48,7 @@ operator=(const SBCommandReturnObject &rhs) { return *this; } -bool SBCommandReturnObject::IsValid() const { - return m_opaque_ap.get() != nullptr; -} +bool SBCommandReturnObject::IsValid() const { return m_opaque_ap != nullptr; } const char *SBCommandReturnObject::GetOutput() { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); diff --git a/contrib/llvm/tools/lldb/source/API/SBCompileUnit.cpp b/contrib/llvm/tools/lldb/source/API/SBCompileUnit.cpp index 149d587913e9..4e2fc6af460a 100644 --- a/contrib/llvm/tools/lldb/source/API/SBCompileUnit.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBCompileUnit.cpp @@ -135,17 +135,21 @@ uint32_t SBCompileUnit::GetNumSupportFiles() const { lldb::SBTypeList SBCompileUnit::GetTypes(uint32_t type_mask) { SBTypeList sb_type_list; - if (m_opaque_ptr) { - ModuleSP module_sp(m_opaque_ptr->GetModule()); - if (module_sp) { - SymbolVendor *vendor = module_sp->GetSymbolVendor(); - if (vendor) { - TypeList type_list; - vendor->GetTypes(m_opaque_ptr, type_mask, type_list); - sb_type_list.m_opaque_ap->Append(type_list); - } - } - } + if (!m_opaque_ptr) + return sb_type_list; + + ModuleSP module_sp(m_opaque_ptr->GetModule()); + if (!module_sp) + return sb_type_list; + + SymbolVendor *vendor = module_sp->GetSymbolVendor(); + if (!vendor) + return sb_type_list; + + TypeClass type_class = static_cast(type_mask); + TypeList type_list; + vendor->GetTypes(m_opaque_ptr, type_class, type_list); + sb_type_list.m_opaque_ap->Append(type_list); return sb_type_list; } diff --git a/contrib/llvm/tools/lldb/source/API/SBData.cpp b/contrib/llvm/tools/lldb/source/API/SBData.cpp index a8ba5808d4f6..a30a778a19d2 100644 --- a/contrib/llvm/tools/lldb/source/API/SBData.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBData.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include // PRIu64 +#include #include "lldb/API/SBData.h" #include "lldb/API/SBError.h" diff --git a/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp b/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp index a651141003a4..af343233c90e 100644 --- a/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBDebugger.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "SystemInitializerFull.h" @@ -41,7 +37,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/DataFormatters/DataVisualization.h" @@ -53,6 +48,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/TargetList.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" @@ -90,7 +86,7 @@ static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp, "lldb::PluginInitialize(lldb::SBDebugger)"); } } else { - if (spec.Exists()) + if (FileSystem::Instance().Exists(spec)) error.SetErrorString("this file does not represent a loadable dylib"); else error.SetErrorString("no such file"); @@ -129,13 +125,23 @@ SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) { } void SBDebugger::Initialize() { + SBInitializerOptions options; + SBDebugger::Initialize(options); +} + +lldb::SBError SBDebugger::Initialize(SBInitializerOptions &options) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); if (log) log->Printf("SBDebugger::Initialize ()"); - g_debugger_lifetime->Initialize(llvm::make_unique(), - LoadPlugin); + SBError error; + if (auto e = g_debugger_lifetime->Initialize( + llvm::make_unique(), *options.m_opaque_up, + LoadPlugin)) { + error.SetError(Status(std::move(e))); + } + return error; } void SBDebugger::Terminate() { g_debugger_lifetime->Terminate(); } @@ -558,7 +564,8 @@ lldb::SBTarget SBDebugger::CreateTarget(const char *filename, platform_options.SetPlatformName(platform_name); sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget( - *m_opaque_sp, filename, target_triple, add_dependent_modules, + *m_opaque_sp, filename, target_triple, + add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, &platform_options, target_sp); if (sb_error.Success()) @@ -587,7 +594,8 @@ SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename, if (m_opaque_sp) { const bool add_dependent_modules = true; Status error(m_opaque_sp->GetTargetList().CreateTarget( - *m_opaque_sp, filename, target_triple, add_dependent_modules, nullptr, + *m_opaque_sp, filename, target_triple, + add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, target_sp)); sb_target.SetSP(target_sp); } @@ -613,7 +621,8 @@ SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename, const bool add_dependent_modules = true; error = m_opaque_sp->GetTargetList().CreateTarget( - *m_opaque_sp, filename, arch_cstr, add_dependent_modules, nullptr, + *m_opaque_sp, filename, arch_cstr, + add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, target_sp); if (error.Success()) { @@ -638,7 +647,9 @@ SBTarget SBDebugger::CreateTarget(const char *filename) { Status error; const bool add_dependent_modules = true; error = m_opaque_sp->GetTargetList().CreateTarget( - *m_opaque_sp, filename, "", add_dependent_modules, nullptr, target_sp); + *m_opaque_sp, filename, "", + add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr, + target_sp); if (error.Success()) { m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp.get()); @@ -730,7 +741,7 @@ SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename, m_opaque_sp->GetPlatformList().GetSelectedPlatform().get(), arch_name); TargetSP target_sp( m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture( - FileSpec(filename, false), arch_name ? &arch : nullptr)); + FileSpec(filename), arch_name ? &arch : nullptr)); sb_target.SetSP(target_sp); } return sb_target; @@ -1050,6 +1061,12 @@ void SBDebugger::SetPrompt(const char *prompt) { m_opaque_sp->SetPrompt(llvm::StringRef::withNullAsEmpty(prompt)); } +const char *SBDebugger::GetReproducerPath() const { + return (m_opaque_sp + ? ConstString(m_opaque_sp->GetReproducerPath()).GetCString() + : nullptr); +} + ScriptLanguage SBDebugger::GetScriptLanguage() const { return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone); } diff --git a/contrib/llvm/tools/lldb/source/API/SBDeclaration.cpp b/contrib/llvm/tools/lldb/source/API/SBDeclaration.cpp index d6e61e32582d..90e4db367d2a 100644 --- a/contrib/llvm/tools/lldb/source/API/SBDeclaration.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBDeclaration.cpp @@ -75,7 +75,7 @@ uint32_t SBDeclaration::GetLine() const { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); uint32_t line = 0; - if (m_opaque_ap.get()) + if (m_opaque_ap) line = m_opaque_ap->GetLine(); if (log) @@ -86,7 +86,7 @@ uint32_t SBDeclaration::GetLine() const { } uint32_t SBDeclaration::GetColumn() const { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->GetColumn(); return 0; } @@ -126,7 +126,7 @@ const lldb_private::Declaration *SBDeclaration::operator->() const { } lldb_private::Declaration &SBDeclaration::ref() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new lldb_private::Declaration()); return *m_opaque_ap; } @@ -138,7 +138,7 @@ const lldb_private::Declaration &SBDeclaration::ref() const { bool SBDeclaration::GetDescription(SBStream &description) { Stream &strm = description.ref(); - if (m_opaque_ap.get()) { + if (m_opaque_ap) { char file_path[PATH_MAX * 2]; m_opaque_ap->GetFile().GetPath(file_path, sizeof(file_path)); strm.Printf("%s:%u", file_path, GetLine()); diff --git a/contrib/llvm/tools/lldb/source/API/SBError.cpp b/contrib/llvm/tools/lldb/source/API/SBError.cpp index b2811d0ac381..04433bb1aab0 100644 --- a/contrib/llvm/tools/lldb/source/API/SBError.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBError.cpp @@ -28,7 +28,7 @@ SBError::~SBError() {} const SBError &SBError::operator=(const SBError &rhs) { if (rhs.IsValid()) { - if (m_opaque_ap.get()) + if (m_opaque_ap) *m_opaque_ap = *rhs; else m_opaque_ap.reset(new Status(*rhs)); @@ -39,13 +39,13 @@ const SBError &SBError::operator=(const SBError &rhs) { } const char *SBError::GetCString() const { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->AsCString(); return NULL; } void SBError::Clear() { - if (m_opaque_ap.get()) + if (m_opaque_ap) m_opaque_ap->Clear(); } @@ -53,7 +53,7 @@ bool SBError::Fail() const { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); bool ret_value = false; - if (m_opaque_ap.get()) + if (m_opaque_ap) ret_value = m_opaque_ap->Fail(); if (log) @@ -66,7 +66,7 @@ bool SBError::Fail() const { bool SBError::Success() const { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); bool ret_value = true; - if (m_opaque_ap.get()) + if (m_opaque_ap) ret_value = m_opaque_ap->Success(); if (log) @@ -80,7 +80,7 @@ uint32_t SBError::GetError() const { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); uint32_t err = 0; - if (m_opaque_ap.get()) + if (m_opaque_ap) err = m_opaque_ap->GetError(); if (log) @@ -93,7 +93,7 @@ uint32_t SBError::GetError() const { ErrorType SBError::GetType() const { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); ErrorType err_type = eErrorTypeInvalid; - if (m_opaque_ap.get()) + if (m_opaque_ap) err_type = m_opaque_ap->GetType(); if (log) @@ -137,10 +137,10 @@ int SBError::SetErrorStringWithFormat(const char *format, ...) { return num_chars; } -bool SBError::IsValid() const { return m_opaque_ap.get() != NULL; } +bool SBError::IsValid() const { return m_opaque_ap != NULL; } void SBError::CreateIfNeeded() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new Status()); } @@ -159,7 +159,7 @@ const lldb_private::Status &SBError::operator*() const { } bool SBError::GetDescription(SBStream &description) { - if (m_opaque_ap.get()) { + if (m_opaque_ap) { if (m_opaque_ap->Success()) description.Printf("success"); else { diff --git a/contrib/llvm/tools/lldb/source/API/SBEvent.cpp b/contrib/llvm/tools/lldb/source/API/SBEvent.cpp index 65eb71c09285..0556f50f6544 100644 --- a/contrib/llvm/tools/lldb/source/API/SBEvent.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBEvent.cpp @@ -12,11 +12,11 @@ #include "lldb/API/SBStream.h" #include "lldb/Breakpoint/Breakpoint.h" -#include "lldb/Core/Event.h" #include "lldb/Core/StreamFile.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Target/Process.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/Stream.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/API/SBExpressionOptions.cpp b/contrib/llvm/tools/lldb/source/API/SBExpressionOptions.cpp index e26fa11651e5..76cec876a216 100644 --- a/contrib/llvm/tools/lldb/source/API/SBExpressionOptions.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBExpressionOptions.cpp @@ -159,6 +159,15 @@ void SBExpressionOptions::SetTopLevel(bool b) { : m_opaque_ap->default_execution_policy); } +bool SBExpressionOptions::GetAllowJIT() { + return m_opaque_ap->GetExecutionPolicy() != eExecutionPolicyNever; +} + +void SBExpressionOptions::SetAllowJIT(bool allow) { + m_opaque_ap->SetExecutionPolicy(allow ? m_opaque_ap->default_execution_policy + : eExecutionPolicyNever); +} + EvaluateExpressionOptions *SBExpressionOptions::get() const { return m_opaque_ap.get(); } diff --git a/contrib/llvm/tools/lldb/source/API/SBFileSpec.cpp b/contrib/llvm/tools/lldb/source/API/SBFileSpec.cpp index 011b88225ef9..f136409d0b68 100644 --- a/contrib/llvm/tools/lldb/source/API/SBFileSpec.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBFileSpec.cpp @@ -7,11 +7,12 @@ // //===----------------------------------------------------------------------===// -#include // PRIu64 +#include #include #include "lldb/API/SBFileSpec.h" #include "lldb/API/SBStream.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/PosixApi.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" @@ -31,11 +32,15 @@ SBFileSpec::SBFileSpec(const lldb_private::FileSpec &fspec) : m_opaque_ap(new lldb_private::FileSpec(fspec)) {} // Deprecated!!! -SBFileSpec::SBFileSpec(const char *path) - : m_opaque_ap(new FileSpec(path, true)) {} +SBFileSpec::SBFileSpec(const char *path) : m_opaque_ap(new FileSpec(path)) { + FileSystem::Instance().Resolve(*m_opaque_ap); +} SBFileSpec::SBFileSpec(const char *path, bool resolve) - : m_opaque_ap(new FileSpec(path, resolve)) {} + : m_opaque_ap(new FileSpec(path)) { + if (resolve) + FileSystem::Instance().Resolve(*m_opaque_ap); +} SBFileSpec::~SBFileSpec() {} @@ -50,7 +55,7 @@ bool SBFileSpec::IsValid() const { return m_opaque_ap->operator bool(); } bool SBFileSpec::Exists() const { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - bool result = m_opaque_ap->Exists(); + bool result = FileSystem::Instance().Exists(*m_opaque_ap); if (log) log->Printf("SBFileSpec(%p)::Exists () => %s", @@ -61,13 +66,13 @@ bool SBFileSpec::Exists() const { } bool SBFileSpec::ResolveExecutableLocation() { - return m_opaque_ap->ResolveExecutableLocation(); + return FileSystem::Instance().ResolveExecutableLocation(*m_opaque_ap); } int SBFileSpec::ResolvePath(const char *src_path, char *dst_path, size_t dst_len) { llvm::SmallString<64> result(src_path); - lldb_private::FileSpec::Resolve(result); + FileSystem::Instance().Resolve(result); ::snprintf(dst_path, dst_len, "%s", result.c_str()); return std::min(dst_len - 1, result.size()); } @@ -143,12 +148,10 @@ const lldb_private::FileSpec *SBFileSpec::get() const { } const lldb_private::FileSpec &SBFileSpec::operator*() const { - return *m_opaque_ap.get(); + return *m_opaque_ap; } -const lldb_private::FileSpec &SBFileSpec::ref() const { - return *m_opaque_ap.get(); -} +const lldb_private::FileSpec &SBFileSpec::ref() const { return *m_opaque_ap; } void SBFileSpec::SetFileSpec(const lldb_private::FileSpec &fs) { *m_opaque_ap = fs; diff --git a/contrib/llvm/tools/lldb/source/API/SBFileSpecList.cpp b/contrib/llvm/tools/lldb/source/API/SBFileSpecList.cpp index 67d28dcbe111..439859c3fd85 100644 --- a/contrib/llvm/tools/lldb/source/API/SBFileSpecList.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBFileSpecList.cpp @@ -26,7 +26,7 @@ SBFileSpecList::SBFileSpecList() : m_opaque_ap(new FileSpecList()) {} SBFileSpecList::SBFileSpecList(const SBFileSpecList &rhs) : m_opaque_ap() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - if (rhs.m_opaque_ap.get()) + if (rhs.m_opaque_ap) m_opaque_ap.reset(new FileSpecList(*(rhs.get()))); if (log) { @@ -78,17 +78,17 @@ const lldb_private::FileSpecList *SBFileSpecList::get() const { } const lldb_private::FileSpecList &SBFileSpecList::operator*() const { - return *m_opaque_ap.get(); + return *m_opaque_ap; } const lldb_private::FileSpecList &SBFileSpecList::ref() const { - return *m_opaque_ap.get(); + return *m_opaque_ap; } bool SBFileSpecList::GetDescription(SBStream &description) const { Stream &strm = description.ref(); - if (m_opaque_ap.get()) { + if (m_opaque_ap) { uint32_t num_files = m_opaque_ap->GetSize(); strm.Printf("%d files: ", num_files); for (uint32_t i = 0; i < num_files; i++) { diff --git a/contrib/llvm/tools/lldb/source/API/SBFrame.cpp b/contrib/llvm/tools/lldb/source/API/SBFrame.cpp index 5762a75f33d6..44dcfd806be5 100644 --- a/contrib/llvm/tools/lldb/source/API/SBFrame.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBFrame.cpp @@ -7,14 +7,10 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/API/SBFrame.h" #include "lldb/lldb-types.h" @@ -36,6 +32,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/StackID.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" @@ -112,7 +109,7 @@ SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const { SBSymbolContext sb_sym_ctx; std::unique_lock lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); - + SymbolContextItem scope = static_cast(resolve_scope); StackFrame *frame = nullptr; Target *target = exe_ctx.GetTargetPtr(); Process *process = exe_ctx.GetProcessPtr(); @@ -121,7 +118,7 @@ SBSymbolContext SBFrame::GetSymbolContext(uint32_t resolve_scope) const { if (stop_locker.TryLock(&process->GetRunLock())) { frame = exe_ctx.GetFramePtr(); if (frame) { - sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext(resolve_scope)); + sb_sym_ctx.SetSymbolContext(&frame->GetSymbolContext(scope)); } else { if (log) log->Printf("SBFrame::GetVariables () => error: could not " @@ -666,28 +663,10 @@ SBValue SBFrame::FindVariable(const char *name, if (stop_locker.TryLock(&process->GetRunLock())) { frame = exe_ctx.GetFramePtr(); if (frame) { - VariableList variable_list; - SymbolContext sc(frame->GetSymbolContext(eSymbolContextBlock)); + value_sp = frame->FindVariable(ConstString(name)); - if (sc.block) { - const bool can_create = true; - const bool get_parent_variables = true; - const bool stop_if_block_is_inlined_function = true; - - if (sc.block->AppendVariables( - can_create, get_parent_variables, - stop_if_block_is_inlined_function, - [frame](Variable *v) { return v->IsInScope(frame); }, - &variable_list)) { - var_sp = variable_list.FindVariable(ConstString(name)); - } - } - - if (var_sp) { - value_sp = - frame->GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); + if (value_sp) sb_value.SetSP(value_sp, use_dynamic); - } } else { if (log) log->Printf("SBFrame::FindVariable () => error: could not " @@ -978,6 +957,8 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) { const bool statics = options.GetIncludeStatics(); const bool arguments = options.GetIncludeArguments(); + const bool recognized_arguments = + options.GetIncludeRecognizedArguments(SBTarget(exe_ctx.GetTargetSP())); const bool locals = options.GetIncludeLocals(); const bool in_scope_only = options.GetInScopeOnly(); const bool include_runtime_support_values = @@ -985,10 +966,11 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) { const lldb::DynamicValueType use_dynamic = options.GetUseDynamic(); if (log) - log->Printf("SBFrame::GetVariables (arguments=%i, locals=%i, statics=%i, " - "in_scope_only=%i runtime=%i dynamic=%i)", - arguments, locals, statics, in_scope_only, - include_runtime_support_values, use_dynamic); + log->Printf( + "SBFrame::GetVariables (arguments=%i, recognized_arguments=%i, " + "locals=%i, statics=%i, in_scope_only=%i runtime=%i dynamic=%i)", + arguments, recognized_arguments, locals, statics, in_scope_only, + include_runtime_support_values, use_dynamic); std::set variable_set; Process *process = exe_ctx.GetProcessPtr(); @@ -1050,6 +1032,20 @@ SBValueList SBFrame::GetVariables(const lldb::SBVariablesOptions &options) { } } } + if (recognized_arguments) { + auto recognized_frame = frame->GetRecognizedFrame(); + if (recognized_frame) { + ValueObjectListSP recognized_arg_list = + recognized_frame->GetRecognizedArguments(); + if (recognized_arg_list) { + for (auto &rec_value_sp : recognized_arg_list->GetObjects()) { + SBValue value_sb; + value_sb.SetSP(rec_value_sp, use_dynamic); + value_list.Append(value_sb); + } + } + } + } } else { if (log) log->Printf("SBFrame::GetVariables () => error: could not " @@ -1366,6 +1362,21 @@ bool SBFrame::IsInlined() const { return false; } +bool SBFrame::IsArtificial() { + return static_cast(this)->IsArtificial(); +} + +bool SBFrame::IsArtificial() const { + std::unique_lock lock; + ExecutionContext exe_ctx(m_opaque_sp.get(), lock); + + StackFrame *frame = exe_ctx.GetFramePtr(); + if (frame) + return frame->IsArtificial(); + + return false; +} + const char *SBFrame::GetFunctionName() { return static_cast(this)->GetFunctionName(); } diff --git a/contrib/llvm/tools/lldb/source/API/SBHostOS.cpp b/contrib/llvm/tools/lldb/source/API/SBHostOS.cpp index e56951df43be..ac6ab40bda41 100644 --- a/contrib/llvm/tools/lldb/source/API/SBHostOS.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBHostOS.cpp @@ -11,8 +11,9 @@ #include "Plugins/ScriptInterpreter/Python/lldb-python.h" #endif -#include "lldb/API/SBHostOS.h" #include "lldb/API/SBError.h" +#include "lldb/API/SBHostOS.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostNativeThread.h" @@ -86,7 +87,8 @@ SBFileSpec SBHostOS::GetUserHomeDirectory() { llvm::SmallString<64> home_dir_path; llvm::sys::path::home_directory(home_dir_path); - FileSpec homedir(home_dir_path.c_str(), true); + FileSpec homedir(home_dir_path.c_str()); + FileSystem::Instance().Resolve(homedir); sb_fspec.SetFileSpec(homedir); return sb_fspec; diff --git a/contrib/llvm/tools/lldb/source/API/SBInitializerOptions.cpp b/contrib/llvm/tools/lldb/source/API/SBInitializerOptions.cpp new file mode 100644 index 000000000000..8d8ec28190ec --- /dev/null +++ b/contrib/llvm/tools/lldb/source/API/SBInitializerOptions.cpp @@ -0,0 +1,49 @@ +//===-- SBInitializerOptions.cpp --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/API/SBInitializerOptions.h" +#include "lldb/Initialization/SystemInitializer.h" + +using namespace lldb; +using namespace lldb_private; + +SBInitializerOptions::SBInitializerOptions(const SBInitializerOptions &rhs) { + m_opaque_up.reset(new InitializerOptions()); + *(m_opaque_up.get()) = rhs.ref(); +} + +const SBInitializerOptions &SBInitializerOptions:: +operator=(const SBInitializerOptions &rhs) { + if (this != &rhs) { + this->ref() = rhs.ref(); + } + return *this; +} + +SBInitializerOptions::~SBInitializerOptions() {} + +SBInitializerOptions::SBInitializerOptions() { + m_opaque_up.reset(new InitializerOptions()); +} + +void SBInitializerOptions::SetCaptureReproducer(bool b) { + m_opaque_up->reproducer_capture = b; +} + +void SBInitializerOptions::SetReplayReproducer(bool b) { + m_opaque_up->reproducer_replay = b; +} + +void SBInitializerOptions::SetReproducerPath(const char *path) { + m_opaque_up->reproducer_path = path; +} + +InitializerOptions &SBInitializerOptions::ref() const { + return *(m_opaque_up.get()); +} diff --git a/contrib/llvm/tools/lldb/source/API/SBLaunchInfo.cpp b/contrib/llvm/tools/lldb/source/API/SBLaunchInfo.cpp index aa1759ab3d00..b1bbfa55d5c1 100644 --- a/contrib/llvm/tools/lldb/source/API/SBLaunchInfo.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBLaunchInfo.cpp @@ -128,7 +128,7 @@ const char *SBLaunchInfo::GetWorkingDirectory() const { } void SBLaunchInfo::SetWorkingDirectory(const char *working_dir) { - m_opaque_sp->SetWorkingDirectory(FileSpec{working_dir, false}); + m_opaque_sp->SetWorkingDirectory(FileSpec(working_dir)); } uint32_t SBLaunchInfo::GetLaunchFlags() { @@ -155,7 +155,7 @@ const char *SBLaunchInfo::GetShell() { } void SBLaunchInfo::SetShell(const char *path) { - m_opaque_sp->SetShell(FileSpec(path, false)); + m_opaque_sp->SetShell(FileSpec(path)); } bool SBLaunchInfo::GetShellExpandArguments() { @@ -184,8 +184,7 @@ bool SBLaunchInfo::AddDuplicateFileAction(int fd, int dup_fd) { bool SBLaunchInfo::AddOpenFileAction(int fd, const char *path, bool read, bool write) { - return m_opaque_sp->AppendOpenFileAction(fd, FileSpec{path, false}, read, - write); + return m_opaque_sp->AppendOpenFileAction(fd, FileSpec(path), read, write); } bool SBLaunchInfo::AddSuppressFileAction(int fd, bool read, bool write) { diff --git a/contrib/llvm/tools/lldb/source/API/SBLineEntry.cpp b/contrib/llvm/tools/lldb/source/API/SBLineEntry.cpp index 7341d3603dfe..6f59fe3407e8 100644 --- a/contrib/llvm/tools/lldb/source/API/SBLineEntry.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBLineEntry.cpp @@ -50,7 +50,7 @@ SBLineEntry::~SBLineEntry() {} SBAddress SBLineEntry::GetStartAddress() const { SBAddress sb_address; - if (m_opaque_ap.get()) + if (m_opaque_ap) sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress()); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); @@ -70,7 +70,7 @@ SBAddress SBLineEntry::GetStartAddress() const { SBAddress SBLineEntry::GetEndAddress() const { SBAddress sb_address; - if (m_opaque_ap.get()) { + if (m_opaque_ap) { sb_address.SetAddress(&m_opaque_ap->range.GetBaseAddress()); sb_address.OffsetAddress(m_opaque_ap->range.GetByteSize()); } @@ -114,7 +114,7 @@ uint32_t SBLineEntry::GetLine() const { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); uint32_t line = 0; - if (m_opaque_ap.get()) + if (m_opaque_ap) line = m_opaque_ap->line; if (log) @@ -125,7 +125,7 @@ uint32_t SBLineEntry::GetLine() const { } uint32_t SBLineEntry::GetColumn() const { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->column; return 0; } @@ -165,7 +165,7 @@ const lldb_private::LineEntry *SBLineEntry::operator->() const { } lldb_private::LineEntry &SBLineEntry::ref() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new lldb_private::LineEntry()); return *m_opaque_ap; } @@ -175,7 +175,7 @@ const lldb_private::LineEntry &SBLineEntry::ref() const { return *m_opaque_ap; } bool SBLineEntry::GetDescription(SBStream &description) { Stream &strm = description.ref(); - if (m_opaque_ap.get()) { + if (m_opaque_ap) { char file_path[PATH_MAX * 2]; m_opaque_ap->file.GetPath(file_path, sizeof(file_path)); strm.Printf("%s:%u", file_path, GetLine()); diff --git a/contrib/llvm/tools/lldb/source/API/SBListener.cpp b/contrib/llvm/tools/lldb/source/API/SBListener.cpp index 50fed4e1ee7b..e671d9f2ce8c 100644 --- a/contrib/llvm/tools/lldb/source/API/SBListener.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBListener.cpp @@ -12,9 +12,9 @@ #include "lldb/API/SBDebugger.h" #include "lldb/API/SBEvent.h" #include "lldb/API/SBStream.h" -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Listener.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Listener.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" diff --git a/contrib/llvm/tools/lldb/source/API/SBMemoryRegionInfoList.cpp b/contrib/llvm/tools/lldb/source/API/SBMemoryRegionInfoList.cpp index fff4044f73e0..1cefc9dcc044 100644 --- a/contrib/llvm/tools/lldb/source/API/SBMemoryRegionInfoList.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBMemoryRegionInfoList.cpp @@ -32,31 +32,47 @@ public: return *this; } - uint32_t GetSize() { return m_regions.size(); } + size_t GetSize() const { return m_regions.size(); } - void Append(const lldb::SBMemoryRegionInfo &sb_region) { + void Reserve(size_t capacity) { return m_regions.reserve(capacity); } + + void Append(const MemoryRegionInfo &sb_region) { m_regions.push_back(sb_region); } void Append(const MemoryRegionInfoListImpl &list) { - for (auto val : list.m_regions) + Reserve(GetSize() + list.GetSize()); + + for (const auto &val : list.m_regions) Append(val); } void Clear() { m_regions.clear(); } - bool GetMemoryRegionInfoAtIndex(uint32_t index, - SBMemoryRegionInfo ®ion_info) { + bool GetMemoryRegionInfoAtIndex(size_t index, + MemoryRegionInfo ®ion_info) { if (index >= GetSize()) return false; region_info = m_regions[index]; return true; } + MemoryRegionInfos &Ref() { return m_regions; } + + const MemoryRegionInfos &Ref() const { return m_regions; } + private: - std::vector m_regions; + MemoryRegionInfos m_regions; }; +MemoryRegionInfos &SBMemoryRegionInfoList::ref() { + return m_opaque_ap->Ref(); +} + +const MemoryRegionInfos &SBMemoryRegionInfoList::ref() const { + return m_opaque_ap->Ref(); +} + SBMemoryRegionInfoList::SBMemoryRegionInfoList() : m_opaque_ap(new MemoryRegionInfoListImpl()) {} @@ -82,7 +98,7 @@ bool SBMemoryRegionInfoList::GetMemoryRegionAtIndex( uint32_t idx, SBMemoryRegionInfo ®ion_info) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - bool result = m_opaque_ap->GetMemoryRegionInfoAtIndex(idx, region_info); + bool result = m_opaque_ap->GetMemoryRegionInfoAtIndex(idx, region_info.ref()); if (log) { SBStream sstr; @@ -100,7 +116,7 @@ bool SBMemoryRegionInfoList::GetMemoryRegionAtIndex( void SBMemoryRegionInfoList::Clear() { m_opaque_ap->Clear(); } void SBMemoryRegionInfoList::Append(SBMemoryRegionInfo &sb_region) { - m_opaque_ap->Append(sb_region); + m_opaque_ap->Append(sb_region.ref()); } void SBMemoryRegionInfoList::Append(SBMemoryRegionInfoList &sb_region_list) { @@ -113,5 +129,5 @@ const MemoryRegionInfoListImpl *SBMemoryRegionInfoList::operator->() const { const MemoryRegionInfoListImpl &SBMemoryRegionInfoList::operator*() const { assert(m_opaque_ap.get()); - return *m_opaque_ap.get(); + return *m_opaque_ap; } diff --git a/contrib/llvm/tools/lldb/source/API/SBModule.cpp b/contrib/llvm/tools/lldb/source/API/SBModule.cpp index 3dd99d5321b4..31980793bce0 100644 --- a/contrib/llvm/tools/lldb/source/API/SBModule.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBModule.cpp @@ -217,9 +217,9 @@ SBModule::ResolveSymbolContextForAddress(const SBAddress &addr, uint32_t resolve_scope) { SBSymbolContext sb_sc; ModuleSP module_sp(GetSP()); + SymbolContextItem scope = static_cast(resolve_scope); if (module_sp && addr.IsValid()) - module_sp->ResolveSymbolContextForAddress(addr.ref(), resolve_scope, - *sb_sc); + module_sp->ResolveSymbolContextForAddress(addr.ref(), scope, *sb_sc); return sb_sc; } @@ -365,8 +365,9 @@ lldb::SBSymbolContextList SBModule::FindFunctions(const char *name, const bool append = true; const bool symbols_ok = true; const bool inlines_ok = true; - module_sp->FindFunctions(ConstString(name), NULL, name_type_mask, - symbols_ok, inlines_ok, append, *sb_sc_list); + FunctionNameType type = static_cast(name_type_mask); + module_sp->FindFunctions(ConstString(name), NULL, type, symbols_ok, + inlines_ok, append, *sb_sc_list); } return sb_sc_list; } @@ -439,13 +440,12 @@ lldb::SBTypeList SBModule::FindTypes(const char *type) { ModuleSP module_sp(GetSP()); if (type && module_sp) { - SymbolContext sc; TypeList type_list; const bool exact_match = false; ConstString name(type); llvm::DenseSet searched_symbol_files; const uint32_t num_matches = module_sp->FindTypes( - sc, name, exact_match, UINT32_MAX, searched_symbol_files, type_list); + name, exact_match, UINT32_MAX, searched_symbol_files, type_list); if (num_matches > 0) { for (size_t idx = 0; idx < num_matches; idx++) { @@ -484,14 +484,16 @@ lldb::SBTypeList SBModule::GetTypes(uint32_t type_mask) { SBTypeList sb_type_list; ModuleSP module_sp(GetSP()); - if (module_sp) { - SymbolVendor *vendor = module_sp->GetSymbolVendor(); - if (vendor) { - TypeList type_list; - vendor->GetTypes(NULL, type_mask, type_list); - sb_type_list.m_opaque_ap->Append(type_list); - } - } + if (!module_sp) + return sb_type_list; + SymbolVendor *vendor = module_sp->GetSymbolVendor(); + if (!vendor) + return sb_type_list; + + TypeClass type_class = static_cast(type_mask); + TypeList type_list; + vendor->GetTypes(NULL, type_class, type_list); + sb_type_list.m_opaque_ap->Append(type_list); return sb_type_list; } @@ -584,7 +586,18 @@ lldb::SBAddress SBModule::GetObjectFileHeaderAddress() const { if (module_sp) { ObjectFile *objfile_ptr = module_sp->GetObjectFile(); if (objfile_ptr) - sb_addr.ref() = objfile_ptr->GetHeaderAddress(); + sb_addr.ref() = objfile_ptr->GetBaseAddress(); + } + return sb_addr; +} + +lldb::SBAddress SBModule::GetObjectFileEntryPointAddress() const { + lldb::SBAddress sb_addr; + ModuleSP module_sp(GetSP()); + if (module_sp) { + ObjectFile *objfile_ptr = module_sp->GetObjectFile(); + if (objfile_ptr) + sb_addr.ref() = objfile_ptr->GetEntryPointAddress(); } return sb_addr; } diff --git a/contrib/llvm/tools/lldb/source/API/SBModuleSpec.cpp b/contrib/llvm/tools/lldb/source/API/SBModuleSpec.cpp index afabd9ace2b9..65492f58b015 100644 --- a/contrib/llvm/tools/lldb/source/API/SBModuleSpec.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBModuleSpec.cpp @@ -114,7 +114,8 @@ SBModuleSpecList::~SBModuleSpecList() {} SBModuleSpecList SBModuleSpecList::GetModuleSpecifications(const char *path) { SBModuleSpecList specs; - FileSpec file_spec(path, true); + FileSpec file_spec(path); + FileSystem::Instance().Resolve(file_spec); Host::ResolveExecutableInBundle(file_spec); ObjectFile::GetModuleSpecifications(file_spec, 0, 0, *specs.m_opaque_ap); return specs; diff --git a/contrib/llvm/tools/lldb/source/API/SBPlatform.cpp b/contrib/llvm/tools/lldb/source/API/SBPlatform.cpp index 5f29f0033988..aedad871cd20 100644 --- a/contrib/llvm/tools/lldb/source/API/SBPlatform.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBPlatform.cpp @@ -244,9 +244,9 @@ bool SBPlatform::SetWorkingDirectory(const char *path) { PlatformSP platform_sp(GetSP()); if (platform_sp) { if (path) - platform_sp->SetWorkingDirectory(FileSpec{path, false}); + platform_sp->SetWorkingDirectory(FileSpec(path)); else - platform_sp->SetWorkingDirectory(FileSpec{}); + platform_sp->SetWorkingDirectory(FileSpec()); return true; } return false; @@ -364,9 +364,9 @@ SBError SBPlatform::Get(SBFileSpec &src, SBFileSpec &dst) { SBError SBPlatform::Put(SBFileSpec &src, SBFileSpec &dst) { return ExecuteConnected([&](const lldb::PlatformSP &platform_sp) { if (src.Exists()) { - uint32_t permissions = src.ref().GetPermissions(); + uint32_t permissions = FileSystem::Instance().GetPermissions(src.ref()); if (permissions == 0) { - if (llvm::sys::fs::is_directory(src.ref().GetPath())) + if (FileSystem::Instance().IsDirectory(src.ref())) permissions = eFilePermissionsDirectoryDefault; else permissions = eFilePermissionsFileDefault; @@ -406,7 +406,7 @@ SBError SBPlatform::Run(SBPlatformShellCommand &shell_command) { if (working_dir) shell_command.SetWorkingDirectory(working_dir); } - return platform_sp->RunShellCommand(command, FileSpec{working_dir, false}, + return platform_sp->RunShellCommand(command, FileSpec(working_dir), &shell_command.m_opaque_ptr->m_status, &shell_command.m_opaque_ptr->m_signo, &shell_command.m_opaque_ptr->m_output, @@ -449,7 +449,7 @@ SBError SBPlatform::MakeDirectory(const char *path, uint32_t file_permissions) { PlatformSP platform_sp(GetSP()); if (platform_sp) { sb_error.ref() = - platform_sp->MakeDirectory(FileSpec{path, false}, file_permissions); + platform_sp->MakeDirectory(FileSpec(path), file_permissions); } else { sb_error.SetErrorString("invalid platform"); } @@ -460,7 +460,7 @@ uint32_t SBPlatform::GetFilePermissions(const char *path) { PlatformSP platform_sp(GetSP()); if (platform_sp) { uint32_t file_permissions = 0; - platform_sp->GetFilePermissions(FileSpec{path, false}, file_permissions); + platform_sp->GetFilePermissions(FileSpec(path), file_permissions); return file_permissions; } return 0; @@ -471,8 +471,8 @@ SBError SBPlatform::SetFilePermissions(const char *path, SBError sb_error; PlatformSP platform_sp(GetSP()); if (platform_sp) { - sb_error.ref() = platform_sp->SetFilePermissions(FileSpec{path, false}, - file_permissions); + sb_error.ref() = + platform_sp->SetFilePermissions(FileSpec(path), file_permissions); } else { sb_error.SetErrorString("invalid platform"); } diff --git a/contrib/llvm/tools/lldb/source/API/SBProcess.cpp b/contrib/llvm/tools/lldb/source/API/SBProcess.cpp index 4d5ddc86ccf9..cb1124607ec0 100644 --- a/contrib/llvm/tools/lldb/source/API/SBProcess.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBProcess.cpp @@ -9,7 +9,6 @@ #include "lldb/API/SBProcess.h" -// C Includes #include #include "lldb/lldb-defines.h" @@ -18,7 +17,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Process.h" @@ -28,9 +26,9 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" -// Project includes #include "lldb/API/SBBroadcaster.h" #include "lldb/API/SBCommandReturnObject.h" @@ -130,10 +128,9 @@ bool SBProcess::RemoteLaunch(char const **argv, char const **envp, if (process_sp->GetState() == eStateConnected) { if (stop_at_entry) launch_flags |= eLaunchFlagStopAtEntry; - ProcessLaunchInfo launch_info( - FileSpec{stdin_path, false}, FileSpec{stdout_path, false}, - FileSpec{stderr_path, false}, FileSpec{working_directory, false}, - launch_flags); + ProcessLaunchInfo launch_info(FileSpec(stdin_path), FileSpec(stdout_path), + FileSpec(stderr_path), + FileSpec(working_directory), launch_flags); Module *exe_module = process_sp->GetTarget().GetExecutableModulePointer(); if (exe_module) launch_info.SetExecutableFile(exe_module->GetPlatformFileSpec(), true); @@ -1351,7 +1348,7 @@ lldb::SBError SBProcess::SaveCore(const char *file_name) { return error; } - FileSpec core_file(file_name, false); + FileSpec core_file(file_name); error.ref() = PluginManager::SaveCore(process_sp, core_file); return error; } @@ -1361,18 +1358,14 @@ SBProcess::GetMemoryRegionInfo(lldb::addr_t load_addr, SBMemoryRegionInfo &sb_region_info) { lldb::SBError sb_error; ProcessSP process_sp(GetSP()); - MemoryRegionInfoSP region_info_sp = - std::make_shared(); if (process_sp) { Process::StopLocker stop_locker; if (stop_locker.TryLock(&process_sp->GetRunLock())) { std::lock_guard guard( process_sp->GetTarget().GetAPIMutex()); + sb_error.ref() = - process_sp->GetMemoryRegionInfo(load_addr, *region_info_sp); - if (sb_error.Success()) { - sb_region_info.ref() = *region_info_sp; - } + process_sp->GetMemoryRegionInfo(load_addr, sb_region_info.ref()); } else { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); if (log) @@ -1388,35 +1381,23 @@ SBProcess::GetMemoryRegionInfo(lldb::addr_t load_addr, } lldb::SBMemoryRegionInfoList SBProcess::GetMemoryRegions() { - lldb::SBError sb_error; lldb::SBMemoryRegionInfoList sb_region_list; + ProcessSP process_sp(GetSP()); - if (process_sp) { - Process::StopLocker stop_locker; - if (stop_locker.TryLock(&process_sp->GetRunLock())) { - std::lock_guard guard( - process_sp->GetTarget().GetAPIMutex()); - std::vector region_list; - sb_error.ref() = process_sp->GetMemoryRegions(region_list); - if (sb_error.Success()) { - std::vector::iterator end = region_list.end(); - for (std::vector::iterator it = region_list.begin(); - it != end; it++) { - SBMemoryRegionInfo sb_region_info(it->get()); - sb_region_list.Append(sb_region_info); - } - } - } else { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - if (log) - log->Printf( - "SBProcess(%p)::GetMemoryRegionInfo() => error: process is running", - static_cast(process_sp.get())); - sb_error.SetErrorString("process is running"); - } + Process::StopLocker stop_locker; + if (process_sp && stop_locker.TryLock(&process_sp->GetRunLock())) { + std::lock_guard guard( + process_sp->GetTarget().GetAPIMutex()); + + process_sp->GetMemoryRegions(sb_region_list.ref()); } else { - sb_error.SetErrorString("SBProcess is invalid"); + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf( + "SBProcess(%p)::GetMemoryRegionInfo() => error: process is running", + static_cast(process_sp.get())); } + return sb_region_list; } diff --git a/contrib/llvm/tools/lldb/source/API/SBProcessInfo.cpp b/contrib/llvm/tools/lldb/source/API/SBProcessInfo.cpp index 38f6c1d1e699..2b3ebfb2465f 100644 --- a/contrib/llvm/tools/lldb/source/API/SBProcessInfo.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBProcessInfo.cpp @@ -36,7 +36,7 @@ SBProcessInfo &SBProcessInfo::operator=(const SBProcessInfo &rhs) { } ProcessInstanceInfo &SBProcessInfo::ref() { - if (m_opaque_ap.get() == nullptr) { + if (m_opaque_ap == nullptr) { m_opaque_ap.reset(new ProcessInstanceInfo()); } return *m_opaque_ap; @@ -46,7 +46,7 @@ void SBProcessInfo::SetProcessInfo(const ProcessInstanceInfo &proc_info_ref) { ref() = proc_info_ref; } -bool SBProcessInfo::IsValid() const { return m_opaque_ap.get() != nullptr; } +bool SBProcessInfo::IsValid() const { return m_opaque_ap != nullptr; } const char *SBProcessInfo::GetName() { const char *name = nullptr; diff --git a/contrib/llvm/tools/lldb/source/API/SBQueue.cpp b/contrib/llvm/tools/lldb/source/API/SBQueue.cpp index 5f852111e077..b4a3cd0c52fb 100644 --- a/contrib/llvm/tools/lldb/source/API/SBQueue.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBQueue.cpp @@ -107,7 +107,7 @@ public: } void FetchThreads() { - if (m_thread_list_fetched == false) { + if (!m_thread_list_fetched) { lldb::QueueSP queue_sp = m_queue_wp.lock(); if (queue_sp) { Process::StopLocker stop_locker; @@ -127,7 +127,7 @@ public: } void FetchItems() { - if (m_pending_items_fetched == false) { + if (!m_pending_items_fetched) { QueueSP queue_sp = m_queue_wp.lock(); if (queue_sp) { Process::StopLocker stop_locker; @@ -178,7 +178,7 @@ public: uint32_t result = 0; QueueSP queue_sp = m_queue_wp.lock(); - if (m_pending_items_fetched == false && queue_sp) { + if (!m_pending_items_fetched && queue_sp) { result = queue_sp->GetNumPendingWorkItems(); } else { result = m_pending_items.size(); diff --git a/contrib/llvm/tools/lldb/source/API/SBSection.cpp b/contrib/llvm/tools/lldb/source/API/SBSection.cpp index 9da5d170da9e..7193857d1281 100644 --- a/contrib/llvm/tools/lldb/source/API/SBSection.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBSection.cpp @@ -14,7 +14,6 @@ #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/DataBuffer.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -166,7 +165,7 @@ SBData SBSection::GetSectionData(uint64_t offset, uint64_t size) { else file_size = 0; } - auto data_buffer_sp = DataBufferLLVM::CreateSliceFromPath( + auto data_buffer_sp = FileSystem::Instance().CreateDataBuffer( objfile->GetFileSpec().GetPath(), file_size, file_offset); if (data_buffer_sp && data_buffer_sp->GetByteSize() > 0) { DataExtractorSP data_extractor_sp( diff --git a/contrib/llvm/tools/lldb/source/API/SBSourceManager.cpp b/contrib/llvm/tools/lldb/source/API/SBSourceManager.cpp index 5804c22bacb8..1d47cc034e35 100644 --- a/contrib/llvm/tools/lldb/source/API/SBSourceManager.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBSourceManager.cpp @@ -107,7 +107,7 @@ size_t SBSourceManager::DisplaySourceLinesWithLineNumbersAndColumn( const SBFileSpec &file, uint32_t line, uint32_t column, uint32_t context_before, uint32_t context_after, const char *current_line_cstr, SBStream &s) { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) return 0; return m_opaque_ap->DisplaySourceLinesWithLineNumbers( diff --git a/contrib/llvm/tools/lldb/source/API/SBStream.cpp b/contrib/llvm/tools/lldb/source/API/SBStream.cpp index d1af77a40fa3..876ef02170d2 100644 --- a/contrib/llvm/tools/lldb/source/API/SBStream.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBStream.cpp @@ -10,6 +10,7 @@ #include "lldb/API/SBStream.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -24,12 +25,12 @@ SBStream::SBStream(SBStream &&rhs) SBStream::~SBStream() {} -bool SBStream::IsValid() const { return (m_opaque_ap.get() != NULL); } +bool SBStream::IsValid() const { return (m_opaque_ap != NULL); } // If this stream is not redirected to a file, it will maintain a local cache // for the stream data which can be accessed using this accessor. const char *SBStream::GetData() { - if (m_is_file || m_opaque_ap.get() == NULL) + if (m_is_file || m_opaque_ap == NULL) return NULL; return static_cast(m_opaque_ap.get())->GetData(); @@ -38,7 +39,7 @@ const char *SBStream::GetData() { // If this stream is not redirected to a file, it will maintain a local cache // for the stream output whose length can be accessed using this accessor. size_t SBStream::GetSize() { - if (m_is_file || m_opaque_ap.get() == NULL) + if (m_is_file || m_opaque_ap == NULL) return 0; return static_cast(m_opaque_ap.get())->GetSize(); @@ -58,7 +59,7 @@ void SBStream::RedirectToFile(const char *path, bool append) { return; std::string local_data; - if (m_opaque_ap.get()) { + if (m_opaque_ap) { // See if we have any locally backed data. If so, copy it so we can then // redirect it to the file so we don't lose the data if (!m_is_file) @@ -70,12 +71,12 @@ void SBStream::RedirectToFile(const char *path, bool append) { open_options |= File::eOpenOptionAppend; else open_options |= File::eOpenOptionTruncate; - stream_file->GetFile().Open(path, open_options, - lldb::eFilePermissionsFileDefault); + FileSystem::Instance().Open(stream_file->GetFile(), FileSpec(path), + open_options); m_opaque_ap.reset(stream_file); - if (m_opaque_ap.get()) { + if (m_opaque_ap) { m_is_file = true; // If we had any data locally in our StreamString, then pass that along to @@ -91,7 +92,7 @@ void SBStream::RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership) { return; std::string local_data; - if (m_opaque_ap.get()) { + if (m_opaque_ap) { // See if we have any locally backed data. If so, copy it so we can then // redirect it to the file so we don't lose the data if (!m_is_file) @@ -99,7 +100,7 @@ void SBStream::RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership) { } m_opaque_ap.reset(new StreamFile(fh, transfer_fh_ownership)); - if (m_opaque_ap.get()) { + if (m_opaque_ap) { m_is_file = true; // If we had any data locally in our StreamString, then pass that along to @@ -112,7 +113,7 @@ void SBStream::RedirectToFileHandle(FILE *fh, bool transfer_fh_ownership) { void SBStream::RedirectToFileDescriptor(int fd, bool transfer_fh_ownership) { std::string local_data; - if (m_opaque_ap.get()) { + if (m_opaque_ap) { // See if we have any locally backed data. If so, copy it so we can then // redirect it to the file so we don't lose the data if (!m_is_file) @@ -120,7 +121,7 @@ void SBStream::RedirectToFileDescriptor(int fd, bool transfer_fh_ownership) { } m_opaque_ap.reset(new StreamFile(::fdopen(fd, "w"), transfer_fh_ownership)); - if (m_opaque_ap.get()) { + if (m_opaque_ap) { m_is_file = true; // If we had any data locally in our StreamString, then pass that along to @@ -136,13 +137,13 @@ lldb_private::Stream *SBStream::operator->() { return m_opaque_ap.get(); } lldb_private::Stream *SBStream::get() { return m_opaque_ap.get(); } lldb_private::Stream &SBStream::ref() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new StreamString()); - return *m_opaque_ap.get(); + return *m_opaque_ap; } void SBStream::Clear() { - if (m_opaque_ap.get()) { + if (m_opaque_ap) { // See if we have any locally backed data. If so, copy it so we can then // redirect it to the file so we don't lose the data if (m_is_file) diff --git a/contrib/llvm/tools/lldb/source/API/SBStringList.cpp b/contrib/llvm/tools/lldb/source/API/SBStringList.cpp index 9ac69b15ebb7..6ed4d4b7fb82 100644 --- a/contrib/llvm/tools/lldb/source/API/SBStringList.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBStringList.cpp @@ -47,7 +47,7 @@ const lldb_private::StringList &SBStringList::operator*() const { return *m_opaque_ap; } -bool SBStringList::IsValid() const { return (m_opaque_ap.get() != NULL); } +bool SBStringList::IsValid() const { return (m_opaque_ap != NULL); } void SBStringList::AppendString(const char *str) { if (str != NULL) { diff --git a/contrib/llvm/tools/lldb/source/API/SBStructuredData.cpp b/contrib/llvm/tools/lldb/source/API/SBStructuredData.cpp index d506410f6d80..277193424e99 100644 --- a/contrib/llvm/tools/lldb/source/API/SBStructuredData.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBStructuredData.cpp @@ -10,9 +10,10 @@ #include "lldb/API/SBStructuredData.h" #include "lldb/API/SBStream.h" -#include "lldb/Core/Event.h" +#include "lldb/API/SBStringList.h" #include "lldb/Core/StructuredDataImpl.h" #include "lldb/Target/StructuredDataPlugin.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StructuredData.h" @@ -31,6 +32,9 @@ SBStructuredData::SBStructuredData(const lldb::SBStructuredData &rhs) SBStructuredData::SBStructuredData(const lldb::EventSP &event_sp) : m_impl_up(new StructuredDataImpl(event_sp)) {} +SBStructuredData::SBStructuredData(lldb_private::StructuredDataImpl *impl) + : m_impl_up(impl) {} + SBStructuredData::~SBStructuredData() {} SBStructuredData &SBStructuredData:: @@ -76,6 +80,33 @@ size_t SBStructuredData::GetSize() const { return (m_impl_up ? m_impl_up->GetSize() : 0); } +bool SBStructuredData::GetKeys(lldb::SBStringList &keys) const { + if (!m_impl_up) + return false; + + if (GetType() != eStructuredDataTypeDictionary) + return false; + + StructuredData::ObjectSP obj_sp = m_impl_up->GetObjectSP(); + if (!obj_sp) + return false; + + StructuredData::Dictionary *dict = obj_sp->GetAsDictionary(); + // We claimed we were a dictionary, so this can't be null. + assert(dict); + // The return kind of GetKeys is an Array: + StructuredData::ObjectSP array_sp = dict->GetKeys(); + StructuredData::Array *key_arr = array_sp->GetAsArray(); + assert(key_arr); + + key_arr->ForEach([&keys] (StructuredData::Object *object) -> bool { + llvm::StringRef key = object->GetStringValue(""); + keys.AppendString(key.str().c_str()); + return true; + }); + return true; +} + lldb::SBStructuredData SBStructuredData::GetValueForKey(const char *key) const { if (!m_impl_up) return SBStructuredData(); diff --git a/contrib/llvm/tools/lldb/source/API/SBSymbolContext.cpp b/contrib/llvm/tools/lldb/source/API/SBSymbolContext.cpp index 45dfffd916e7..ab70c6f6ca68 100644 --- a/contrib/llvm/tools/lldb/source/API/SBSymbolContext.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBSymbolContext.cpp @@ -27,7 +27,7 @@ SBSymbolContext::SBSymbolContext(const SymbolContext *sc_ptr) : m_opaque_ap() { SBSymbolContext::SBSymbolContext(const SBSymbolContext &rhs) : m_opaque_ap() { if (rhs.IsValid()) { - if (m_opaque_ap.get()) + if (m_opaque_ap) *m_opaque_ap = *rhs.m_opaque_ap; else ref() = *rhs.m_opaque_ap; @@ -39,32 +39,31 @@ SBSymbolContext::~SBSymbolContext() {} const SBSymbolContext &SBSymbolContext::operator=(const SBSymbolContext &rhs) { if (this != &rhs) { if (rhs.IsValid()) - m_opaque_ap.reset( - new lldb_private::SymbolContext(*rhs.m_opaque_ap.get())); + m_opaque_ap.reset(new lldb_private::SymbolContext(*rhs.m_opaque_ap)); } return *this; } void SBSymbolContext::SetSymbolContext(const SymbolContext *sc_ptr) { if (sc_ptr) { - if (m_opaque_ap.get()) + if (m_opaque_ap) *m_opaque_ap = *sc_ptr; else m_opaque_ap.reset(new SymbolContext(*sc_ptr)); } else { - if (m_opaque_ap.get()) + if (m_opaque_ap) m_opaque_ap->Clear(true); } } -bool SBSymbolContext::IsValid() const { return m_opaque_ap.get() != NULL; } +bool SBSymbolContext::IsValid() const { return m_opaque_ap != NULL; } SBModule SBSymbolContext::GetModule() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); SBModule sb_module; ModuleSP module_sp; - if (m_opaque_ap.get()) { + if (m_opaque_ap) { module_sp = m_opaque_ap->module_sp; sb_module.SetSP(module_sp); } @@ -81,7 +80,7 @@ SBModule SBSymbolContext::GetModule() { } SBCompileUnit SBSymbolContext::GetCompileUnit() { - return SBCompileUnit(m_opaque_ap.get() ? m_opaque_ap->comp_unit : NULL); + return SBCompileUnit(m_opaque_ap ? m_opaque_ap->comp_unit : NULL); } SBFunction SBSymbolContext::GetFunction() { @@ -89,7 +88,7 @@ SBFunction SBSymbolContext::GetFunction() { Function *function = NULL; - if (m_opaque_ap.get()) + if (m_opaque_ap) function = m_opaque_ap->function; SBFunction sb_function(function); @@ -103,14 +102,14 @@ SBFunction SBSymbolContext::GetFunction() { } SBBlock SBSymbolContext::GetBlock() { - return SBBlock(m_opaque_ap.get() ? m_opaque_ap->block : NULL); + return SBBlock(m_opaque_ap ? m_opaque_ap->block : NULL); } SBLineEntry SBSymbolContext::GetLineEntry() { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); SBLineEntry sb_line_entry; - if (m_opaque_ap.get()) + if (m_opaque_ap) sb_line_entry.SetLineEntry(m_opaque_ap->line_entry); if (log) { @@ -127,7 +126,7 @@ SBSymbol SBSymbolContext::GetSymbol() { Symbol *symbol = NULL; - if (m_opaque_ap.get()) + if (m_opaque_ap) symbol = m_opaque_ap->symbol; SBSymbol sb_symbol(symbol); @@ -173,19 +172,19 @@ lldb_private::SymbolContext *SBSymbolContext::operator->() const { const lldb_private::SymbolContext &SBSymbolContext::operator*() const { assert(m_opaque_ap.get()); - return *m_opaque_ap.get(); + return *m_opaque_ap; } lldb_private::SymbolContext &SBSymbolContext::operator*() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new SymbolContext); - return *m_opaque_ap.get(); + return *m_opaque_ap; } lldb_private::SymbolContext &SBSymbolContext::ref() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new SymbolContext); - return *m_opaque_ap.get(); + return *m_opaque_ap; } lldb_private::SymbolContext *SBSymbolContext::get() const { @@ -195,7 +194,7 @@ lldb_private::SymbolContext *SBSymbolContext::get() const { bool SBSymbolContext::GetDescription(SBStream &description) { Stream &strm = description.ref(); - if (m_opaque_ap.get()) { + if (m_opaque_ap) { m_opaque_ap->GetDescription(&strm, lldb::eDescriptionLevelFull, NULL); } else strm.PutCString("No value"); diff --git a/contrib/llvm/tools/lldb/source/API/SBSymbolContextList.cpp b/contrib/llvm/tools/lldb/source/API/SBSymbolContextList.cpp index 8cc29c3422d0..b07ab2afd554 100644 --- a/contrib/llvm/tools/lldb/source/API/SBSymbolContextList.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBSymbolContextList.cpp @@ -31,14 +31,14 @@ operator=(const SBSymbolContextList &rhs) { } uint32_t SBSymbolContextList::GetSize() const { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->GetSize(); return 0; } SBSymbolContext SBSymbolContextList::GetContextAtIndex(uint32_t idx) { SBSymbolContext sb_sc; - if (m_opaque_ap.get()) { + if (m_opaque_ap) { SymbolContext sc; if (m_opaque_ap->GetContextAtIndex(idx, sc)) { sb_sc.SetSymbolContext(&sc); @@ -48,7 +48,7 @@ SBSymbolContext SBSymbolContextList::GetContextAtIndex(uint32_t idx) { } void SBSymbolContextList::Clear() { - if (m_opaque_ap.get()) + if (m_opaque_ap) m_opaque_ap->Clear(); } @@ -62,7 +62,7 @@ void SBSymbolContextList::Append(SBSymbolContextList &sc_list) { m_opaque_ap->Append(*sc_list); } -bool SBSymbolContextList::IsValid() const { return m_opaque_ap.get() != NULL; } +bool SBSymbolContextList::IsValid() const { return m_opaque_ap != NULL; } lldb_private::SymbolContextList *SBSymbolContextList::operator->() const { return m_opaque_ap.get(); @@ -70,12 +70,12 @@ lldb_private::SymbolContextList *SBSymbolContextList::operator->() const { lldb_private::SymbolContextList &SBSymbolContextList::operator*() const { assert(m_opaque_ap.get()); - return *m_opaque_ap.get(); + return *m_opaque_ap; } bool SBSymbolContextList::GetDescription(lldb::SBStream &description) { Stream &strm = description.ref(); - if (m_opaque_ap.get()) + if (m_opaque_ap) m_opaque_ap->GetDescription(&strm, lldb::eDescriptionLevelFull, NULL); return true; } diff --git a/contrib/llvm/tools/lldb/source/API/SBTarget.cpp b/contrib/llvm/tools/lldb/source/API/SBTarget.cpp index 550d336906d3..98587e7d7677 100644 --- a/contrib/llvm/tools/lldb/source/API/SBTarget.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBTarget.cpp @@ -202,6 +202,21 @@ SBStructuredData SBTarget::GetStatistics() { return data; } +void SBTarget::SetCollectingStats(bool v) { + TargetSP target_sp(GetSP()); + if (!target_sp) + return; + return target_sp->SetCollectingStats(v); +} + +bool SBTarget::GetCollectingStats() { + TargetSP target_sp(GetSP()); + if (!target_sp) + return false; + return target_sp->GetCollectingStats(); +} + + SBProcess SBTarget::LoadCore(const char *core_file) { lldb::SBError error; // Ignored return LoadCore(core_file, error); @@ -211,7 +226,8 @@ SBProcess SBTarget::LoadCore(const char *core_file, lldb::SBError &error) { SBProcess sb_process; TargetSP target_sp(GetSP()); if (target_sp) { - FileSpec filespec(core_file, true); + FileSpec filespec(core_file); + FileSystem::Instance().Resolve(filespec); ProcessSP process_sp(target_sp->CreateProcess( target_sp->GetDebugger().GetListener(), "", &filespec)); if (process_sp) { @@ -310,10 +326,9 @@ SBProcess SBTarget::Launch(SBListener &listener, char const **argv, if (getenv("LLDB_LAUNCH_FLAG_DISABLE_STDIO")) launch_flags |= eLaunchFlagDisableSTDIO; - ProcessLaunchInfo launch_info( - FileSpec{stdin_path, false}, FileSpec{stdout_path, false}, - FileSpec{stderr_path, false}, FileSpec{working_directory, false}, - launch_flags); + ProcessLaunchInfo launch_info(FileSpec(stdin_path), FileSpec(stdout_path), + FileSpec(stderr_path), + FileSpec(working_directory), launch_flags); Module *exe_module = target_sp->GetExecutableModulePointer(); if (exe_module) @@ -501,8 +516,7 @@ lldb::SBProcess SBTarget::AttachToProcessWithName( if (name && target_sp) { ProcessAttachInfo attach_info; - attach_info.GetExecutableFile().SetFile(name, false, - FileSpec::Style::native); + attach_info.GetExecutableFile().SetFile(name, FileSpec::Style::native); attach_info.SetWaitForLaunch(wait_for); if (listener.IsValid()) attach_info.SetListener(listener.GetSP()); @@ -645,11 +659,12 @@ SBSymbolContext SBTarget::ResolveSymbolContextForAddress(const SBAddress &addr, uint32_t resolve_scope) { SBSymbolContext sc; + SymbolContextItem scope = static_cast(resolve_scope); if (addr.IsValid()) { TargetSP target_sp(GetSP()); if (target_sp) - target_sp->GetImages().ResolveSymbolContextForAddress( - addr.ref(), resolve_scope, sc.ref()); + target_sp->GetImages().ResolveSymbolContextForAddress(addr.ref(), scope, + sc.ref()); } return sc; } @@ -693,6 +708,13 @@ SBBreakpoint SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec, uint32_t line, lldb::addr_t offset, SBFileSpecList &sb_module_list) { + return BreakpointCreateByLocation(sb_file_spec, line, 0, offset, + sb_module_list); +} + +SBBreakpoint SBTarget::BreakpointCreateByLocation( + const SBFileSpec &sb_file_spec, uint32_t line, uint32_t column, + lldb::addr_t offset, SBFileSpecList &sb_module_list) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); SBBreakpoint sb_bp; @@ -710,8 +732,8 @@ SBTarget::BreakpointCreateByLocation(const SBFileSpec &sb_file_spec, module_list = sb_module_list.get(); } sb_bp = target_sp->CreateBreakpoint( - module_list, *sb_file_spec, line, offset, check_inlines, skip_prologue, - internal, hardware, move_to_nearest_code); + module_list, *sb_file_spec, line, column, offset, check_inlines, + skip_prologue, internal, hardware, move_to_nearest_code); } if (log) { @@ -743,7 +765,7 @@ SBBreakpoint SBTarget::BreakpointCreateByName(const char *symbol_name, const lldb::addr_t offset = 0; if (module_name && module_name[0]) { FileSpecList module_spec_list; - module_spec_list.Append(FileSpec(module_name, false)); + module_spec_list.Append(FileSpec(module_name)); sb_bp = target_sp->CreateBreakpoint( &module_spec_list, NULL, symbol_name, eFunctionNameTypeAuto, eLanguageTypeUnknown, offset, skip_prologue, internal, hardware); @@ -767,7 +789,7 @@ lldb::SBBreakpoint SBTarget::BreakpointCreateByName(const char *symbol_name, const SBFileSpecList &module_list, const SBFileSpecList &comp_unit_list) { - uint32_t name_type_mask = eFunctionNameTypeAuto; + lldb::FunctionNameType name_type_mask = eFunctionNameTypeAuto; return BreakpointCreateByName(symbol_name, name_type_mask, eLanguageTypeUnknown, module_list, comp_unit_list); @@ -794,9 +816,10 @@ lldb::SBBreakpoint SBTarget::BreakpointCreateByName( const bool hardware = false; const LazyBool skip_prologue = eLazyBoolCalculate; std::lock_guard guard(target_sp->GetAPIMutex()); - sb_bp = target_sp->CreateBreakpoint( - module_list.get(), comp_unit_list.get(), symbol_name, name_type_mask, - symbol_language, 0, skip_prologue, internal, hardware); + FunctionNameType mask = static_cast(name_type_mask); + sb_bp = target_sp->CreateBreakpoint(module_list.get(), comp_unit_list.get(), + symbol_name, mask, symbol_language, 0, + skip_prologue, internal, hardware); } if (log) @@ -837,11 +860,11 @@ lldb::SBBreakpoint SBTarget::BreakpointCreateByNames( std::lock_guard guard(target_sp->GetAPIMutex()); const bool internal = false; const bool hardware = false; + FunctionNameType mask = static_cast(name_type_mask); const LazyBool skip_prologue = eLazyBoolCalculate; sb_bp = target_sp->CreateBreakpoint( - module_list.get(), comp_unit_list.get(), symbol_names, num_names, - name_type_mask, symbol_language, offset, skip_prologue, internal, - hardware); + module_list.get(), comp_unit_list.get(), symbol_names, num_names, mask, + symbol_language, offset, skip_prologue, internal, hardware); } if (log) { @@ -870,7 +893,7 @@ SBBreakpoint SBTarget::BreakpointCreateByRegex(const char *symbol_name_regex, SBFileSpecList module_spec_list; SBFileSpecList comp_unit_list; if (module_name && module_name[0]) { - module_spec_list.Append(FileSpec(module_name, false)); + module_spec_list.Append(FileSpec(module_name)); } return BreakpointCreateByRegex(symbol_name_regex, eLanguageTypeUnknown, module_spec_list, comp_unit_list); @@ -971,7 +994,7 @@ SBTarget::BreakpointCreateBySourceRegex(const char *source_regex, SBFileSpecList module_spec_list; if (module_name && module_name[0]) { - module_spec_list.Append(FileSpec(module_name, false)); + module_spec_list.Append(FileSpec(module_name)); } SBFileSpecList source_file_list; @@ -1037,7 +1060,7 @@ SBTarget::BreakpointCreateForException(lldb::LanguageType language, } if (log) - log->Printf("SBTarget(%p)::BreakpointCreateByRegex (Language: %s, catch: " + log->Printf("SBTarget(%p)::BreakpointCreateForException (Language: %s, catch: " "%s throw: %s) => SBBreakpoint(%p)", static_cast(target_sp.get()), Language::GetNameForLanguageType(language), @@ -1047,6 +1070,42 @@ SBTarget::BreakpointCreateForException(lldb::LanguageType language, return sb_bp; } +lldb::SBBreakpoint +SBTarget::BreakpointCreateFromScript(const char *class_name, + SBStructuredData &extra_args, + const SBFileSpecList &module_list, + const SBFileSpecList &file_list, + bool request_hardware) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + + SBBreakpoint sb_bp; + TargetSP target_sp(GetSP()); + if (target_sp) { + std::lock_guard guard(target_sp->GetAPIMutex()); + Status error; + + StructuredData::ObjectSP obj_sp = extra_args.m_impl_up->GetObjectSP(); + sb_bp = + target_sp->CreateScriptedBreakpoint(class_name, + module_list.get(), + file_list.get(), + false, /* internal */ + request_hardware, + obj_sp, + &error); + } + if (log) + log->Printf("SBTarget(%p)::BreakpointCreateFromScript (class name: %s) " + " => SBBreakpoint(%p)", + static_cast(target_sp.get()), + class_name, + static_cast(sb_bp.GetSP().get())); + + return sb_bp; +} + + uint32_t SBTarget::GetNumBreakpoints() const { TargetSP target_sp(GetSP()); if (target_sp) { @@ -1457,6 +1516,26 @@ bool SBTarget::DeleteAllWatchpoints() { return false; } +void SBTarget::AppendImageSearchPath(const char *from, const char *to, + lldb::SBError &error) { + TargetSP target_sp(GetSP()); + if (!target_sp) + return error.SetErrorString("invalid target"); + + const ConstString csFrom(from), csTo(to); + if (!csFrom) + return error.SetErrorString(" path can't be empty"); + if (!csTo) + return error.SetErrorString(" path can't be empty"); + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); + if (log) + log->Printf("SBTarget(%p)::%s: '%s' -> '%s'", + static_cast(target_sp.get()), __FUNCTION__, + from, to); + target_sp->GetImageSearchPathList().Append(csFrom, csTo, true); +} + lldb::SBModule SBTarget::AddModule(const char *path, const char *triple, const char *uuid_cstr) { return AddModule(path, triple, uuid_cstr, NULL); @@ -1469,7 +1548,7 @@ lldb::SBModule SBTarget::AddModule(const char *path, const char *triple, if (target_sp) { ModuleSpec module_spec; if (path) - module_spec.GetFileSpec().SetFile(path, false, FileSpec::Style::native); + module_spec.GetFileSpec().SetFile(path, FileSpec::Style::native); if (uuid_cstr) module_spec.GetUUID().SetFromStringRef(uuid_cstr); @@ -1481,8 +1560,7 @@ lldb::SBModule SBTarget::AddModule(const char *path, const char *triple, module_spec.GetArchitecture() = target_sp->GetArchitecture(); if (symfile) - module_spec.GetSymbolFileSpec().SetFile(symfile, false, - FileSpec::Style::native); + module_spec.GetSymbolFileSpec().SetFile(symfile, FileSpec::Style::native); sb_module.SetSP(target_sp->GetSharedModule(module_spec)); } @@ -1656,17 +1734,19 @@ bool SBTarget::GetDescription(SBStream &description, lldb::SBSymbolContextList SBTarget::FindFunctions(const char *name, uint32_t name_type_mask) { lldb::SBSymbolContextList sb_sc_list; - if (name && name[0]) { - TargetSP target_sp(GetSP()); - if (target_sp) { - const bool symbols_ok = true; - const bool inlines_ok = true; - const bool append = true; - target_sp->GetImages().FindFunctions(ConstString(name), name_type_mask, - symbols_ok, inlines_ok, append, - *sb_sc_list); - } - } + if (!name | !name[0]) + return sb_sc_list; + + TargetSP target_sp(GetSP()); + if (!target_sp) + return sb_sc_list; + + const bool symbols_ok = true; + const bool inlines_ok = true; + const bool append = true; + FunctionNameType mask = static_cast(name_type_mask); + target_sp->GetImages().FindFunctions(ConstString(name), mask, symbols_ok, + inlines_ok, append, *sb_sc_list); return sb_sc_list; } @@ -1770,11 +1850,10 @@ lldb::SBTypeList SBTarget::FindTypes(const char *typename_cstr) { ModuleList &images = target_sp->GetImages(); ConstString const_typename(typename_cstr); bool exact_match = false; - SymbolContext sc; TypeList type_list; llvm::DenseSet searched_symbol_files; uint32_t num_matches = - images.FindTypes(sc, const_typename, exact_match, UINT32_MAX, + images.FindTypes(nullptr, const_typename, exact_match, UINT32_MAX, searched_symbol_files, type_list); if (num_matches > 0) { diff --git a/contrib/llvm/tools/lldb/source/API/SBThread.cpp b/contrib/llvm/tools/lldb/source/API/SBThread.cpp index 0d25b85f57d2..2c859d5222d6 100644 --- a/contrib/llvm/tools/lldb/source/API/SBThread.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBThread.cpp @@ -14,7 +14,6 @@ #include "lldb/API/SBSymbolContext.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ValueObject.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -32,6 +31,7 @@ #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepRange.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StructuredData.h" @@ -571,7 +571,7 @@ bool SBThread::GetInfoItemByPathAsString(const char *path, SBStream &strm) { success = true; } if (node->GetType() == eStructuredDataTypeBoolean) { - if (node->GetAsBoolean()->GetValue() == true) + if (node->GetAsBoolean()->GetValue()) strm.Printf("true"); else strm.Printf("false"); @@ -657,6 +657,7 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { bool abort_other_plans = false; StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); + Status new_plan_status; ThreadPlanSP new_plan_sp; if (frame_sp) { if (frame_sp->HasDebugInformation()) { @@ -664,10 +665,10 @@ void SBThread::StepOver(lldb::RunMode stop_other_threads, SBError &error) { SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); new_plan_sp = thread->QueueThreadPlanForStepOverRange( abort_other_plans, sc.line_entry, sc, stop_other_threads, - avoid_no_debug); + new_plan_status, avoid_no_debug); } else { new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( - true, abort_other_plans, stop_other_threads); + true, abort_other_plans, stop_other_threads, new_plan_status); } } error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); @@ -707,6 +708,7 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line, Thread *thread = exe_ctx.GetThreadPtr(); StackFrameSP frame_sp(thread->GetStackFrameAtIndex(0)); ThreadPlanSP new_plan_sp; + Status new_plan_status; if (frame_sp && frame_sp->HasDebugInformation()) { SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); @@ -724,13 +726,17 @@ void SBThread::StepInto(const char *target_name, uint32_t end_line, eLazyBoolCalculate; new_plan_sp = thread->QueueThreadPlanForStepInRange( abort_other_plans, range, sc, target_name, stop_other_threads, - step_in_avoids_code_without_debug_info, + new_plan_status, step_in_avoids_code_without_debug_info, step_out_avoids_code_without_debug_info); } else { new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( - false, abort_other_plans, stop_other_threads); + false, abort_other_plans, stop_other_threads, new_plan_status); } - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } void SBThread::StepOut() { @@ -759,11 +765,15 @@ void SBThread::StepOut(SBError &error) { Thread *thread = exe_ctx.GetThreadPtr(); const LazyBool avoid_no_debug = eLazyBoolCalculate; + Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( abort_other_plans, NULL, false, stop_other_threads, eVoteYes, - eVoteNoOpinion, 0, avoid_no_debug)); + eVoteNoOpinion, 0, new_plan_status, avoid_no_debug)); - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } void SBThread::StepOutOfFrame(SBFrame &sb_frame) { @@ -812,11 +822,15 @@ void SBThread::StepOutOfFrame(SBFrame &sb_frame, SBError &error) { return; } + Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepOut( abort_other_plans, NULL, false, stop_other_threads, eVoteYes, - eVoteNoOpinion, frame_sp->GetFrameIndex())); + eVoteNoOpinion, frame_sp->GetFrameIndex(), new_plan_status)); - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } void SBThread::StepInstruction(bool step_over) { @@ -840,10 +854,14 @@ void SBThread::StepInstruction(bool step_over, SBError &error) { } Thread *thread = exe_ctx.GetThreadPtr(); - ThreadPlanSP new_plan_sp( - thread->QueueThreadPlanForStepSingleInstruction(step_over, true, true)); + Status new_plan_status; + ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepSingleInstruction( + step_over, true, true, new_plan_status)); - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } void SBThread::RunToAddress(lldb::addr_t addr) { @@ -873,10 +891,14 @@ void SBThread::RunToAddress(lldb::addr_t addr, SBError &error) { Thread *thread = exe_ctx.GetThreadPtr(); + Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForRunToAddress( - abort_other_plans, target_addr, stop_other_threads)); + abort_other_plans, target_addr, stop_other_threads, new_plan_status)); - error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); } SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, @@ -988,12 +1010,16 @@ SBError SBThread::StepOverUntil(lldb::SBFrame &sb_frame, } else sb_error.SetErrorString("step until target not in current function"); } else { + Status new_plan_status; ThreadPlanSP new_plan_sp(thread->QueueThreadPlanForStepUntil( abort_other_plans, &step_over_until_addrs[0], step_over_until_addrs.size(), stop_other_threads, - frame_sp->GetFrameIndex())); + frame_sp->GetFrameIndex(), new_plan_status)); - sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + if (new_plan_status.Success()) + sb_error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + sb_error.SetErrorString(new_plan_status.AsCString()); } } else { sb_error.SetErrorString("this SBThread object is invalid"); @@ -1008,7 +1034,7 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name) { SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, bool resume_immediately) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); - SBError sb_error; + SBError error; std::unique_lock lock; ExecutionContext exe_ctx(m_opaque_sp.get(), lock); @@ -1019,37 +1045,29 @@ SBError SBThread::StepUsingScriptedThreadPlan(const char *script_class_name, } if (!exe_ctx.HasThreadScope()) { - sb_error.SetErrorString("this SBThread object is invalid"); - return sb_error; + error.SetErrorString("this SBThread object is invalid"); + return error; } Thread *thread = exe_ctx.GetThreadPtr(); - ThreadPlanSP thread_plan_sp = - thread->QueueThreadPlanForStepScripted(false, script_class_name, false); + Status new_plan_status; + ThreadPlanSP new_plan_sp = thread->QueueThreadPlanForStepScripted( + false, script_class_name, false, new_plan_status); - if (!thread_plan_sp) { - sb_error.SetErrorStringWithFormat( - "Error queueing thread plan for class: %s", script_class_name); - return sb_error; + if (new_plan_status.Fail()) { + error.SetErrorString(new_plan_status.AsCString()); + return error; } - if (!resume_immediately) { - return sb_error; - } + if (!resume_immediately) + return error; - if (thread_plan_sp) - sb_error = ResumeNewPlan(exe_ctx, thread_plan_sp.get()); - else { - sb_error.SetErrorStringWithFormat( - "Error resuming thread plan for class: %s.", script_class_name); - if (log) - log->Printf("SBThread(%p)::StepUsingScriptedThreadPlan: Error queuing " - "thread plan for class: %s", - static_cast(exe_ctx.GetThreadPtr()), - script_class_name); - } + if (new_plan_status.Success()) + error = ResumeNewPlan(exe_ctx, new_plan_sp.get()); + else + error.SetErrorString(new_plan_status.AsCString()); - return sb_error; + return error; } SBError SBThread::JumpToLine(lldb::SBFileSpec &file_spec, uint32_t line) { @@ -1452,7 +1470,7 @@ SBThread SBThread::GetExtendedBacktraceThread(const char *type) { } } - if (log && sb_origin_thread.IsValid() == false) + if (log && !sb_origin_thread.IsValid()) log->Printf("SBThread(%p)::GetExtendedBacktraceThread() is not returning a " "Valid thread", static_cast(exe_ctx.GetThreadPtr())); @@ -1466,6 +1484,20 @@ uint32_t SBThread::GetExtendedBacktraceOriginatingIndexID() { return LLDB_INVALID_INDEX32; } +SBValue SBThread::GetCurrentException() { + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (!thread_sp) return SBValue(); + + return SBValue(thread_sp->GetCurrentException()); +} + +SBThread SBThread::GetCurrentExceptionBacktrace() { + ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); + if (!thread_sp) return SBThread(); + + return SBThread(thread_sp->GetCurrentExceptionBacktrace()); +} + bool SBThread::SafeToCallFunctions() { ThreadSP thread_sp(m_opaque_sp->GetThreadSP()); if (thread_sp) diff --git a/contrib/llvm/tools/lldb/source/API/SBThreadPlan.cpp b/contrib/llvm/tools/lldb/source/API/SBThreadPlan.cpp index 131f84195908..fc54f5b5f87e 100644 --- a/contrib/llvm/tools/lldb/source/API/SBThreadPlan.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBThreadPlan.cpp @@ -14,7 +14,6 @@ #include "lldb/API/SBSymbolContext.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/CompileUnit.h" @@ -31,6 +30,7 @@ #include "lldb/Target/ThreadPlanStepInstruction.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepRange.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StructuredData.h" @@ -143,6 +143,12 @@ bool SBThreadPlan::IsValid() { SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address, lldb::addr_t size) { + SBError error; + return QueueThreadPlanForStepOverRange(sb_start_address, size, error); +} + +SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOverRange( + SBAddress &sb_start_address, lldb::addr_t size, SBError &error) { if (m_opaque_sp) { Address *start_address = sb_start_address.get(); if (!start_address) { @@ -152,9 +158,16 @@ SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address, AddressRange range(*start_address, size); SymbolContext sc; start_address->CalculateSymbolContext(&sc); - return SBThreadPlan( - m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange( - false, range, sc, eAllThreads)); + Status plan_status; + + SBThreadPlan plan = + SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOverRange( + false, range, sc, eAllThreads, plan_status)); + + if (plan_status.Fail()) + error.SetErrorString(plan_status.AsCString()); + + return plan; } else { return SBThreadPlan(); } @@ -163,6 +176,13 @@ SBThreadPlan::QueueThreadPlanForStepOverRange(SBAddress &sb_start_address, SBThreadPlan SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address, lldb::addr_t size) { + SBError error; + return QueueThreadPlanForStepInRange(sb_start_address, size, error); +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address, + lldb::addr_t size, SBError &error) { if (m_opaque_sp) { Address *start_address = sb_start_address.get(); if (!start_address) { @@ -172,8 +192,16 @@ SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address, AddressRange range(*start_address, size); SymbolContext sc; start_address->CalculateSymbolContext(&sc); - return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange( - false, range, sc, NULL, eAllThreads)); + + Status plan_status; + SBThreadPlan plan = + SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepInRange( + false, range, sc, NULL, eAllThreads, plan_status)); + + if (plan_status.Fail()) + error.SetErrorString(plan_status.AsCString()); + + return plan; } else { return SBThreadPlan(); } @@ -182,13 +210,28 @@ SBThreadPlan::QueueThreadPlanForStepInRange(SBAddress &sb_start_address, SBThreadPlan SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, bool first_insn) { + SBError error; + return QueueThreadPlanForStepOut(frame_idx_to_step_to, first_insn, error); +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, + bool first_insn, SBError &error) { if (m_opaque_sp) { SymbolContext sc; sc = m_opaque_sp->GetThread().GetStackFrameAtIndex(0)->GetSymbolContext( lldb::eSymbolContextEverything); - return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOut( - false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion, - frame_idx_to_step_to)); + + Status plan_status; + SBThreadPlan plan = + SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepOut( + false, &sc, first_insn, false, eVoteYes, eVoteNoOpinion, + frame_idx_to_step_to, plan_status)); + + if (plan_status.Fail()) + error.SetErrorString(plan_status.AsCString()); + + return plan; } else { return SBThreadPlan(); } @@ -196,13 +239,50 @@ SBThreadPlan::QueueThreadPlanForStepOut(uint32_t frame_idx_to_step_to, SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address) { + SBError error; + return QueueThreadPlanForRunToAddress(sb_address, error); +} + +SBThreadPlan SBThreadPlan::QueueThreadPlanForRunToAddress(SBAddress sb_address, + SBError &error) { if (m_opaque_sp) { Address *address = sb_address.get(); if (!address) return SBThreadPlan(); - return SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress( - false, *address, false)); + Status plan_status; + SBThreadPlan plan = + SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForRunToAddress( + false, *address, false, plan_status)); + + if (plan_status.Fail()) + error.SetErrorString(plan_status.AsCString()); + + return plan; + } else { + return SBThreadPlan(); + } +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name) { + SBError error; + return QueueThreadPlanForStepScripted(script_class_name, error); +} + +SBThreadPlan +SBThreadPlan::QueueThreadPlanForStepScripted(const char *script_class_name, + SBError &error) { + if (m_opaque_sp) { + Status plan_status; + SBThreadPlan plan = + SBThreadPlan(m_opaque_sp->GetThread().QueueThreadPlanForStepScripted( + false, script_class_name, false, plan_status)); + + if (plan_status.Fail()) + error.SetErrorString(plan_status.AsCString()); + + return plan; } else { return SBThreadPlan(); } diff --git a/contrib/llvm/tools/lldb/source/API/SBType.cpp b/contrib/llvm/tools/lldb/source/API/SBType.cpp index e199b7a33e48..77d7dc654100 100644 --- a/contrib/llvm/tools/lldb/source/API/SBType.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBType.cpp @@ -47,20 +47,20 @@ SBType::SBType(const SBType &rhs) : m_opaque_sp() { //{} // bool SBType::operator==(SBType &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); - if (rhs.IsValid() == false) + if (!rhs.IsValid()) return false; return *m_opaque_sp.get() == *rhs.m_opaque_sp.get(); } bool SBType::operator!=(SBType &rhs) { - if (IsValid() == false) + if (!IsValid()) return rhs.IsValid(); - if (rhs.IsValid() == false) + if (!rhs.IsValid()) return true; return *m_opaque_sp.get() != *rhs.m_opaque_sp.get(); @@ -103,10 +103,11 @@ bool SBType::IsValid() const { } uint64_t SBType::GetByteSize() { - if (!IsValid()) - return 0; - - return m_opaque_sp->GetCompilerType(false).GetByteSize(nullptr); + if (IsValid()) + if (llvm::Optional size = + m_opaque_sp->GetCompilerType(false).GetByteSize(nullptr)) + return *size; + return 0; } bool SBType::IsPointerType() { @@ -451,7 +452,7 @@ SBTypeList::SBTypeList(const SBTypeList &rhs) Append(const_cast(rhs).GetTypeAtIndex(i)); } -bool SBTypeList::IsValid() { return (m_opaque_ap.get() != NULL); } +bool SBTypeList::IsValid() { return (m_opaque_ap != NULL); } SBTypeList &SBTypeList::operator=(const SBTypeList &rhs) { if (this != &rhs) { @@ -469,7 +470,7 @@ void SBTypeList::Append(SBType type) { } SBType SBTypeList::GetTypeAtIndex(uint32_t index) { - if (m_opaque_ap.get()) + if (m_opaque_ap) return SBType(m_opaque_ap->GetTypeAtIndex(index)); return SBType(); } @@ -500,39 +501,39 @@ lldb::SBTypeMember &SBTypeMember::operator=(const lldb::SBTypeMember &rhs) { bool SBTypeMember::IsValid() const { return m_opaque_ap.get(); } const char *SBTypeMember::GetName() { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->GetName().GetCString(); return NULL; } SBType SBTypeMember::GetType() { SBType sb_type; - if (m_opaque_ap.get()) { + if (m_opaque_ap) { sb_type.SetSP(m_opaque_ap->GetTypeImpl()); } return sb_type; } uint64_t SBTypeMember::GetOffsetInBytes() { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->GetBitOffset() / 8u; return 0; } uint64_t SBTypeMember::GetOffsetInBits() { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->GetBitOffset(); return 0; } bool SBTypeMember::IsBitfield() { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->GetIsBitfield(); return false; } uint32_t SBTypeMember::GetBitfieldSizeInBits() { - if (m_opaque_ap.get()) + if (m_opaque_ap) return m_opaque_ap->GetBitfieldBitSize(); return 0; } @@ -541,7 +542,7 @@ bool SBTypeMember::GetDescription(lldb::SBStream &description, lldb::DescriptionLevel description_level) { Stream &strm = description.ref(); - if (m_opaque_ap.get()) { + if (m_opaque_ap) { const uint32_t bit_offset = m_opaque_ap->GetBitOffset(); const uint32_t byte_offset = bit_offset / 8u; const uint32_t byte_bit_offset = bit_offset % 8u; @@ -571,12 +572,12 @@ void SBTypeMember::reset(TypeMemberImpl *type_member_impl) { } TypeMemberImpl &SBTypeMember::ref() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new TypeMemberImpl()); - return *m_opaque_ap.get(); + return *m_opaque_ap; } -const TypeMemberImpl &SBTypeMember::ref() const { return *m_opaque_ap.get(); } +const TypeMemberImpl &SBTypeMember::ref() const { return *m_opaque_ap; } SBTypeMemberFunction::SBTypeMemberFunction() : m_opaque_sp() {} diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeCategory.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeCategory.cpp index 30414bd728cb..7c2a37e7cf21 100644 --- a/contrib/llvm/tools/lldb/source/API/SBTypeCategory.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBTypeCategory.cpp @@ -529,14 +529,14 @@ operator=(const lldb::SBTypeCategory &rhs) { } bool SBTypeCategory::operator==(lldb::SBTypeCategory &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp.get() == rhs.m_opaque_sp.get(); } bool SBTypeCategory::operator!=(lldb::SBTypeCategory &rhs) { - if (IsValid() == false) + if (!IsValid()) return rhs.IsValid(); return m_opaque_sp.get() != rhs.m_opaque_sp.get(); diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeEnumMember.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeEnumMember.cpp index 5ca9db7ce242..87be40e8b141 100644 --- a/contrib/llvm/tools/lldb/source/API/SBTypeEnumMember.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBTypeEnumMember.cpp @@ -94,7 +94,7 @@ SBTypeEnumMemberList::SBTypeEnumMemberList(const SBTypeEnumMemberList &rhs) Append(const_cast(rhs).GetTypeEnumMemberAtIndex(i)); } -bool SBTypeEnumMemberList::IsValid() { return (m_opaque_ap.get() != NULL); } +bool SBTypeEnumMemberList::IsValid() { return (m_opaque_ap != NULL); } SBTypeEnumMemberList &SBTypeEnumMemberList:: operator=(const SBTypeEnumMemberList &rhs) { @@ -116,7 +116,7 @@ void SBTypeEnumMemberList::Append(SBTypeEnumMember enum_member) { SBTypeEnumMember SBTypeEnumMemberList::GetTypeEnumMemberAtIndex(uint32_t index) { - if (m_opaque_ap.get()) + if (m_opaque_ap) return SBTypeEnumMember(m_opaque_ap->GetTypeEnumMemberAtIndex(index)); return SBTypeEnumMember(); } diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeFilter.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeFilter.cpp index 8fa322211384..9709d2e5da10 100644 --- a/contrib/llvm/tools/lldb/source/API/SBTypeFilter.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBTypeFilter.cpp @@ -91,14 +91,14 @@ lldb::SBTypeFilter &SBTypeFilter::operator=(const lldb::SBTypeFilter &rhs) { } bool SBTypeFilter::operator==(lldb::SBTypeFilter &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp == rhs.m_opaque_sp; } bool SBTypeFilter::IsEqualTo(lldb::SBTypeFilter &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); if (GetNumberOfExpressionPaths() != rhs.GetNumberOfExpressionPaths()) @@ -113,7 +113,7 @@ bool SBTypeFilter::IsEqualTo(lldb::SBTypeFilter &rhs) { } bool SBTypeFilter::operator!=(lldb::SBTypeFilter &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp != rhs.m_opaque_sp; diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeFormat.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeFormat.cpp index 6fe7625831d2..66bfd3671736 100644 --- a/contrib/llvm/tools/lldb/source/API/SBTypeFormat.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBTypeFormat.cpp @@ -88,13 +88,13 @@ lldb::SBTypeFormat &SBTypeFormat::operator=(const lldb::SBTypeFormat &rhs) { } bool SBTypeFormat::operator==(lldb::SBTypeFormat &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp == rhs.m_opaque_sp; } bool SBTypeFormat::IsEqualTo(lldb::SBTypeFormat &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); if (GetFormat() == rhs.GetFormat()) @@ -104,7 +104,7 @@ bool SBTypeFormat::IsEqualTo(lldb::SBTypeFormat &rhs) { } bool SBTypeFormat::operator!=(lldb::SBTypeFormat &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp != rhs.m_opaque_sp; } diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeNameSpecifier.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeNameSpecifier.cpp index 2f9deafb68c8..5ffb3d98a0f2 100644 --- a/contrib/llvm/tools/lldb/source/API/SBTypeNameSpecifier.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBTypeNameSpecifier.cpp @@ -80,13 +80,13 @@ operator=(const lldb::SBTypeNameSpecifier &rhs) { } bool SBTypeNameSpecifier::operator==(lldb::SBTypeNameSpecifier &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp == rhs.m_opaque_sp; } bool SBTypeNameSpecifier::IsEqualTo(lldb::SBTypeNameSpecifier &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); if (IsRegex() != rhs.IsRegex()) @@ -98,7 +98,7 @@ bool SBTypeNameSpecifier::IsEqualTo(lldb::SBTypeNameSpecifier &rhs) { } bool SBTypeNameSpecifier::operator!=(lldb::SBTypeNameSpecifier &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp != rhs.m_opaque_sp; } diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp index cd4edd17f672..76c94ae83444 100644 --- a/contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBTypeSummary.cpp @@ -25,7 +25,7 @@ SBTypeSummaryOptions::SBTypeSummaryOptions() { SBTypeSummaryOptions::SBTypeSummaryOptions( const lldb::SBTypeSummaryOptions &rhs) { if (rhs.m_opaque_ap) - m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap.get())); + m_opaque_ap.reset(new TypeSummaryOptions(*rhs.m_opaque_ap)); else m_opaque_ap.reset(new TypeSummaryOptions()); } @@ -70,11 +70,11 @@ lldb_private::TypeSummaryOptions *SBTypeSummaryOptions::get() { } lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() { - return *m_opaque_ap.get(); + return *m_opaque_ap; } const lldb_private::TypeSummaryOptions &SBTypeSummaryOptions::ref() const { - return *m_opaque_ap.get(); + return *m_opaque_ap; } SBTypeSummaryOptions::SBTypeSummaryOptions( @@ -261,7 +261,7 @@ lldb::SBTypeSummary &SBTypeSummary::operator=(const lldb::SBTypeSummary &rhs) { } bool SBTypeSummary::operator==(lldb::SBTypeSummary &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp == rhs.m_opaque_sp; } @@ -305,7 +305,7 @@ bool SBTypeSummary::IsEqualTo(lldb::SBTypeSummary &rhs) { } bool SBTypeSummary::operator!=(lldb::SBTypeSummary &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp != rhs.m_opaque_sp; } diff --git a/contrib/llvm/tools/lldb/source/API/SBTypeSynthetic.cpp b/contrib/llvm/tools/lldb/source/API/SBTypeSynthetic.cpp index 37b6086f855a..750d917e67f1 100644 --- a/contrib/llvm/tools/lldb/source/API/SBTypeSynthetic.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBTypeSynthetic.cpp @@ -106,13 +106,13 @@ operator=(const lldb::SBTypeSynthetic &rhs) { } bool SBTypeSynthetic::operator==(lldb::SBTypeSynthetic &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp == rhs.m_opaque_sp; } bool SBTypeSynthetic::IsEqualTo(lldb::SBTypeSynthetic &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); if (m_opaque_sp->IsScripted() != rhs.m_opaque_sp->IsScripted()) @@ -128,7 +128,7 @@ bool SBTypeSynthetic::IsEqualTo(lldb::SBTypeSynthetic &rhs) { } bool SBTypeSynthetic::operator!=(lldb::SBTypeSynthetic &rhs) { - if (IsValid() == false) + if (!IsValid()) return !rhs.IsValid(); return m_opaque_sp != rhs.m_opaque_sp; } diff --git a/contrib/llvm/tools/lldb/source/API/SBValue.cpp b/contrib/llvm/tools/lldb/source/API/SBValue.cpp index a270c0471e9f..a61a2a19a621 100644 --- a/contrib/llvm/tools/lldb/source/API/SBValue.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBValue.cpp @@ -18,7 +18,6 @@ #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Module.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" @@ -38,6 +37,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Stream.h" #include "lldb/API/SBDebugger.h" @@ -98,10 +98,7 @@ public: // they depend on. So I have no good way to make that check without // tracking that in all the ValueObject subclasses. TargetSP target_sp = m_valobj_sp->GetTargetSP(); - if (target_sp && target_sp->IsValid()) - return true; - else - return false; + return target_sp && target_sp->IsValid(); } } diff --git a/contrib/llvm/tools/lldb/source/API/SBValueList.cpp b/contrib/llvm/tools/lldb/source/API/SBValueList.cpp index 0adf3bb914aa..82b464bab9b9 100644 --- a/contrib/llvm/tools/lldb/source/API/SBValueList.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBValueList.cpp @@ -99,7 +99,7 @@ SBValueList::SBValueList(const ValueListImpl *lldb_object_ptr) : m_opaque_ap() { SBValueList::~SBValueList() {} -bool SBValueList::IsValid() const { return (m_opaque_ap.get() != NULL); } +bool SBValueList::IsValid() const { return (m_opaque_ap != NULL); } void SBValueList::Clear() { m_opaque_ap.reset(); } @@ -150,7 +150,7 @@ SBValue SBValueList::GetValueAtIndex(uint32_t idx) const { // idx); SBValue sb_value; - if (m_opaque_ap.get()) + if (m_opaque_ap) sb_value = m_opaque_ap->GetValueAtIndex(idx); if (log) { @@ -172,7 +172,7 @@ uint32_t SBValueList::GetSize() const { // log->Printf ("SBValueList::GetSize ()"); uint32_t size = 0; - if (m_opaque_ap.get()) + if (m_opaque_ap) size = m_opaque_ap->GetSize(); if (log) @@ -183,20 +183,20 @@ uint32_t SBValueList::GetSize() const { } void SBValueList::CreateIfNeeded() { - if (m_opaque_ap.get() == NULL) + if (m_opaque_ap == NULL) m_opaque_ap.reset(new ValueListImpl()); } SBValue SBValueList::FindValueObjectByUID(lldb::user_id_t uid) { SBValue sb_value; - if (m_opaque_ap.get()) + if (m_opaque_ap) sb_value = m_opaque_ap->FindValueByUID(uid); return sb_value; } SBValue SBValueList::GetFirstValueByName(const char *name) const { SBValue sb_value; - if (m_opaque_ap.get()) + if (m_opaque_ap) sb_value = m_opaque_ap->GetFirstValueByName(name); return sb_value; } @@ -205,5 +205,5 @@ void *SBValueList::opaque_ptr() { return m_opaque_ap.get(); } ValueListImpl &SBValueList::ref() { CreateIfNeeded(); - return *m_opaque_ap.get(); + return *m_opaque_ap; } diff --git a/contrib/llvm/tools/lldb/source/API/SBVariablesOptions.cpp b/contrib/llvm/tools/lldb/source/API/SBVariablesOptions.cpp index e12b9696521c..2651ce11d02a 100644 --- a/contrib/llvm/tools/lldb/source/API/SBVariablesOptions.cpp +++ b/contrib/llvm/tools/lldb/source/API/SBVariablesOptions.cpp @@ -9,6 +9,10 @@ //===----------------------------------------------------------------------===// #include "lldb/API/SBVariablesOptions.h" +#include "lldb/API/SBTarget.h" +#include "lldb/Target/Target.h" + +#include "lldb/lldb-private.h" using namespace lldb; using namespace lldb_private; @@ -19,6 +23,7 @@ public: : m_include_arguments(false), m_include_locals(false), m_include_statics(false), m_in_scope_only(false), m_include_runtime_support_values(false), + m_include_recognized_arguments(eLazyBoolCalculate), m_use_dynamic(lldb::eNoDynamicValues) {} VariablesOptionsImpl(const VariablesOptionsImpl &) = default; @@ -31,6 +36,16 @@ public: void SetIncludeArguments(bool b) { m_include_arguments = b; } + bool GetIncludeRecognizedArguments(const lldb::TargetSP &target_sp) const { + if (m_include_recognized_arguments != eLazyBoolCalculate) + return m_include_recognized_arguments; + return target_sp ? target_sp->GetDisplayRecognizedArguments() : false; + } + + void SetIncludeRecognizedArguments(bool b) { + m_include_recognized_arguments = b ? eLazyBoolYes : eLazyBoolNo; + } + bool GetIncludeLocals() const { return m_include_locals; } void SetIncludeLocals(bool b) { m_include_locals = b; } @@ -61,6 +76,7 @@ private: bool m_include_statics : 1; bool m_in_scope_only : 1; bool m_include_runtime_support_values : 1; + LazyBool m_include_recognized_arguments; // can be overridden with a setting lldb::DynamicValueType m_use_dynamic; }; @@ -78,9 +94,7 @@ operator=(const SBVariablesOptions &options) { SBVariablesOptions::~SBVariablesOptions() = default; -bool SBVariablesOptions::IsValid() const { - return m_opaque_ap.get() != nullptr; -} +bool SBVariablesOptions::IsValid() const { return m_opaque_ap != nullptr; } bool SBVariablesOptions::GetIncludeArguments() const { return m_opaque_ap->GetIncludeArguments(); @@ -90,6 +104,15 @@ void SBVariablesOptions::SetIncludeArguments(bool arguments) { m_opaque_ap->SetIncludeArguments(arguments); } +bool SBVariablesOptions::GetIncludeRecognizedArguments( + const lldb::SBTarget &target) const { + return m_opaque_ap->GetIncludeRecognizedArguments(target.GetSP()); +} + +void SBVariablesOptions::SetIncludeRecognizedArguments(bool arguments) { + m_opaque_ap->SetIncludeRecognizedArguments(arguments); +} + bool SBVariablesOptions::GetIncludeLocals() const { return m_opaque_ap->GetIncludeLocals(); } diff --git a/contrib/llvm/tools/lldb/source/API/SystemInitializerFull.cpp b/contrib/llvm/tools/lldb/source/API/SystemInitializerFull.cpp index 8c4e12ded996..60fb0979ef8a 100644 --- a/contrib/llvm/tools/lldb/source/API/SystemInitializerFull.cpp +++ b/contrib/llvm/tools/lldb/source/API/SystemInitializerFull.cpp @@ -24,11 +24,6 @@ #include "lldb/Initialization/SystemInitializerCommon.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/ClangASTContext.h" -#include "lldb/Symbol/GoASTContext.h" -#ifdef LLDB_ENABLE_ALL -#include "lldb/Symbol/JavaASTContext.h" -#endif // LLDB_ENABLE_ALL -#include "lldb/Symbol/OCamlASTContext.h" #include "lldb/Utility/Timer.h" #ifdef LLDB_ENABLE_ALL @@ -51,6 +46,7 @@ #endif // LLDB_ENABLE_ALL #include "Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h" #include "Plugins/Architecture/Arm/ArchitectureArm.h" +#include "Plugins/Architecture/Mips/ArchitectureMips.h" #include "Plugins/Architecture/PPC64/ArchitecturePPC64.h" #include "Plugins/Disassembler/llvm/DisassemblerLLVMC.h" #ifdef LLDB_ENABLE_ALL @@ -73,26 +69,21 @@ #include "Plugins/JITLoader/GDB/JITLoaderGDB.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #ifdef LLDB_ENABLE_ALL -#include "Plugins/Language/Go/GoLanguage.h" -#include "Plugins/Language/Java/JavaLanguage.h" -#include "Plugins/Language/OCaml/OCamlLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h" #endif // LLDB_ENABLE_ALL #include "Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h" #ifdef LLDB_ENABLE_ALL -#include "Plugins/LanguageRuntime/Go/GoLanguageRuntime.h" -#include "Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h" #include "Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h" #endif // LLDB_ENABLE_ALL #include "Plugins/MemoryHistory/asan/MemoryHistoryASan.h" +#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h" #include "Plugins/ObjectFile/ELF/ObjectFileELF.h" #ifdef LLDB_ENABLE_ALL #include "Plugins/ObjectFile/Mach-O/ObjectFileMachO.h" #include "Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h" -#include "Plugins/OperatingSystem/Go/OperatingSystemGo.h" #include "Plugins/OperatingSystem/Python/OperatingSystemPython.h" #include "Plugins/Platform/Android/PlatformAndroid.h" #endif // LLDB_ENABLE_ALL @@ -114,6 +105,7 @@ #include "Plugins/Process/minidump/ProcessMinidump.h" #endif // LLDB_ENABLE_ALL #include "Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h" +#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h" #ifdef LLDB_ENABLE_ALL @@ -134,6 +126,7 @@ #include "Plugins/Platform/MacOSX/PlatformDarwinKernel.h" #include "Plugins/Platform/MacOSX/PlatformRemoteAppleTV.h" #include "Plugins/Platform/MacOSX/PlatformRemoteAppleWatch.h" +#include "Plugins/Platform/MacOSX/PlatformRemoteAppleBridge.h" #include "Plugins/Platform/MacOSX/PlatformiOSSimulator.h" #include "Plugins/Process/MacOSX-Kernel/ProcessKDP.h" #include "Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.h" @@ -207,6 +200,18 @@ extern "C" bool LLDBSWIGPythonCallThreadPlan(void *implementor, const char *method_name, Event *event_sp, bool &got_error); +extern "C" void *LLDBSwigPythonCreateScriptedBreakpointResolver( + const char *python_class_name, + const char *session_dictionary_name, + lldb_private::StructuredDataImpl *args, + lldb::BreakpointSP &bkpt_sp); + +extern "C" unsigned int LLDBSwigPythonCallBreakpointResolver( + void *implementor, + const char *method_name, + lldb_private::SymbolContext *sym_ctx +); + extern "C" size_t LLDBSwigPython_CalculateNumChildren(void *implementor, uint32_t max); @@ -252,6 +257,13 @@ LLDBSWIGPythonCreateOSPlugin(const char *python_class_name, const char *session_dictionary_name, const lldb::ProcessSP &process_sp); +extern "C" void *LLDBSWIGPython_CreateFrameRecognizer( + const char *python_class_name, + const char *session_dictionary_name); + +extern "C" void *LLDBSwigPython_GetRecognizedArguments(void *implementor, + const lldb::StackFrameSP& frame_sp); + extern "C" bool LLDBSWIGPythonRunScriptKeywordProcess( const char *python_function_name, const char *session_dictionary_name, lldb::ProcessSP &process, std::string &output); @@ -282,9 +294,12 @@ SystemInitializerFull::SystemInitializerFull() {} SystemInitializerFull::~SystemInitializerFull() {} -void SystemInitializerFull::Initialize() { - SystemInitializerCommon::Initialize(); +llvm::Error +SystemInitializerFull::Initialize(const InitializerOptions &options) { + if (auto e = SystemInitializerCommon::Initialize(options)) + return e; + breakpad::ObjectFileBreakpad::Initialize(); ObjectFileELF::Initialize(); #ifdef LLDB_ENABLE_ALL ObjectFileMachO::Initialize(); @@ -296,9 +311,6 @@ void SystemInitializerFull::Initialize() { #ifndef LLDB_DISABLE_PYTHON OperatingSystemPython::Initialize(); #endif -#ifdef LLDB_ENABLE_ALL - OperatingSystemGo::Initialize(); -#endif // LLDB_ENABLE_ALL #if !defined(LLDB_DISABLE_PYTHON) InitializeSWIG(); @@ -332,11 +344,8 @@ void SystemInitializerFull::Initialize() { llvm::InitializeAllDisassemblers(); ClangASTContext::Initialize(); -#ifdef LLDB_ENABLE_ALL - GoASTContext::Initialize(); - JavaASTContext::Initialize(); - OCamlASTContext::Initialize(); +#ifdef LLDB_ENABLE_ALL ABIMacOSX_i386::Initialize(); ABIMacOSX_arm::Initialize(); ABIMacOSX_arm64::Initialize(); @@ -357,6 +366,7 @@ void SystemInitializerFull::Initialize() { #endif // LLDB_ENABLE_ALL ArchitectureArm::Initialize(); + ArchitectureMips::Initialize(); ArchitecturePPC64::Initialize(); DisassemblerLLVMC::Initialize(); @@ -376,6 +386,7 @@ void SystemInitializerFull::Initialize() { MainThreadCheckerRuntime::Initialize(); SymbolVendorELF::Initialize(); + breakpad::SymbolFileBreakpad::Initialize(); SymbolFileDWARF::Initialize(); #ifdef LLDB_ENABLE_ALL SymbolFilePDB::Initialize(); @@ -392,17 +403,12 @@ void SystemInitializerFull::Initialize() { AppleObjCRuntimeV1::Initialize(); SystemRuntimeMacOSX::Initialize(); RenderScriptRuntime::Initialize(); - GoLanguageRuntime::Initialize(); - JavaLanguageRuntime::Initialize(); #endif // LLDB_ENABLE_ALL CPlusPlusLanguage::Initialize(); #ifdef LLDB_ENABLE_ALL - GoLanguage::Initialize(); - JavaLanguage::Initialize(); ObjCLanguage::Initialize(); ObjCPlusPlusLanguage::Initialize(); - OCamlLanguage::Initialize(); #endif // LLDB_ENABLE_ALL #if defined(_WIN32) @@ -418,6 +424,7 @@ void SystemInitializerFull::Initialize() { PlatformAppleWatchSimulator::Initialize(); PlatformRemoteAppleTV::Initialize(); PlatformRemoteAppleWatch::Initialize(); + PlatformRemoteAppleBridge::Initialize(); DynamicLoaderDarwinKernel::Initialize(); #endif @@ -451,6 +458,8 @@ void SystemInitializerFull::Initialize() { // AFTER PluginManager::Initialize is called. Debugger::SettingsInitialize(); + + return llvm::Error::success(); } void SystemInitializerFull::InitializeSWIG() { @@ -467,11 +476,14 @@ void SystemInitializerFull::InitializeSWIG() { LLDBSwigPython_MightHaveChildrenSynthProviderInstance, LLDBSwigPython_GetValueSynthProviderInstance, LLDBSwigPythonCallCommand, LLDBSwigPythonCallCommandObject, LLDBSwigPythonCallModuleInit, - LLDBSWIGPythonCreateOSPlugin, LLDBSWIGPythonRunScriptKeywordProcess, + LLDBSWIGPythonCreateOSPlugin, LLDBSWIGPython_CreateFrameRecognizer, + LLDBSwigPython_GetRecognizedArguments, + LLDBSWIGPythonRunScriptKeywordProcess, LLDBSWIGPythonRunScriptKeywordThread, LLDBSWIGPythonRunScriptKeywordTarget, LLDBSWIGPythonRunScriptKeywordFrame, LLDBSWIGPythonRunScriptKeywordValue, LLDBSWIGPython_GetDynamicSetting, - LLDBSwigPythonCreateScriptedThreadPlan, LLDBSWIGPythonCallThreadPlan); + LLDBSwigPythonCreateScriptedThreadPlan, LLDBSWIGPythonCallThreadPlan, + LLDBSwigPythonCreateScriptedBreakpointResolver, LLDBSwigPythonCallBreakpointResolver); #endif } @@ -485,10 +497,11 @@ void SystemInitializerFull::Terminate() { PluginManager::Terminate(); ClangASTContext::Terminate(); - GoASTContext::Terminate(); + #ifdef LLDB_ENABLE_ALL - JavaASTContext::Terminate(); - OCamlASTContext::Terminate(); + ArchitectureArm::Terminate(); + ArchitectureMips::Terminate(); + ArchitecturePPC64::Terminate(); ABIMacOSX_i386::Terminate(); ABIMacOSX_arm::Terminate(); @@ -524,6 +537,7 @@ void SystemInitializerFull::Terminate() { UndefinedBehaviorSanitizerRuntime::Terminate(); MainThreadCheckerRuntime::Terminate(); SymbolVendorELF::Terminate(); + breakpad::SymbolFileBreakpad::Terminate(); SymbolFileDWARF::Terminate(); #ifdef LLDB_ENABLE_ALL SymbolFilePDB::Terminate(); @@ -540,16 +554,12 @@ void SystemInitializerFull::Terminate() { AppleObjCRuntimeV1::Terminate(); SystemRuntimeMacOSX::Terminate(); RenderScriptRuntime::Terminate(); - JavaLanguageRuntime::Terminate(); #endif // LLDB_ENABLE_ALL CPlusPlusLanguage::Terminate(); #ifdef LLDB_ENABLE_ALL - GoLanguage::Terminate(); - JavaLanguage::Terminate(); ObjCLanguage::Terminate(); ObjCPlusPlusLanguage::Terminate(); - OCamlLanguage::Terminate(); #endif // LLDB_ENABLE_ALL #if defined(__APPLE__) @@ -560,6 +570,7 @@ void SystemInitializerFull::Terminate() { PlatformAppleWatchSimulator::Terminate(); PlatformRemoteAppleTV::Terminate(); PlatformRemoteAppleWatch::Terminate(); + PlatformRemoteAppleBridge::Terminate(); #endif #if defined(__FreeBSD__) @@ -584,9 +595,6 @@ void SystemInitializerFull::Terminate() { #ifndef LLDB_DISABLE_PYTHON OperatingSystemPython::Terminate(); #endif -#ifdef LLDB_ENABLE_ALL - OperatingSystemGo::Terminate(); -#endif // LLDB_ENABLE_ALL platform_freebsd::PlatformFreeBSD::Terminate(); #ifdef LLDB_ENABLE_ALL @@ -604,6 +612,7 @@ void SystemInitializerFull::Terminate() { PlatformDarwinKernel::Terminate(); #endif + breakpad::ObjectFileBreakpad::Terminate(); ObjectFileELF::Terminate(); #ifdef LLDB_ENABLE_ALL ObjectFileMachO::Terminate(); diff --git a/contrib/llvm/tools/lldb/source/API/SystemInitializerFull.h b/contrib/llvm/tools/lldb/source/API/SystemInitializerFull.h index 9cfc6896da61..b0cf476e9193 100644 --- a/contrib/llvm/tools/lldb/source/API/SystemInitializerFull.h +++ b/contrib/llvm/tools/lldb/source/API/SystemInitializerFull.h @@ -26,7 +26,7 @@ public: SystemInitializerFull(); ~SystemInitializerFull() override; - void Initialize() override; + llvm::Error Initialize(const InitializerOptions &options) override; void Terminate() override; private: diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/Breakpoint.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/Breakpoint.cpp index 1dc029654bfc..131d2a707d44 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/Breakpoint.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/Breakpoint.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/Support/Casting.h" -// Project includes #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" @@ -785,8 +781,8 @@ void Breakpoint::ModuleReplaced(ModuleSP old_module_sp, // we go. if (old_id_vec.size() == new_id_vec.size()) { - llvm::sort(old_id_vec.begin(), old_id_vec.end()); - llvm::sort(new_id_vec.begin(), new_id_vec.end()); + llvm::sort(old_id_vec); + llvm::sort(new_id_vec); size_t num_elements = old_id_vec.size(); for (size_t idx = 0; idx < num_elements; idx++) { BreakpointLocationSP old_loc_sp = @@ -857,6 +853,10 @@ size_t Breakpoint::GetNumResolvedLocations() const { return m_locations.GetNumResolvedLocations(); } +bool Breakpoint::HasResolvedLocations() const { + return GetNumResolvedLocations() > 0; +} + size_t Breakpoint::GetNumLocations() const { return m_locations.GetSize(); } bool Breakpoint::AddName(llvm::StringRef new_name) { diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointID.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointID.cpp index 3f72f2052b52..eb12e09abcf1 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointID.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointID.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Utility/Status.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointIDList.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointIDList.cpp index bc4c2a111fd4..b86f276a5c47 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointIDList.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointIDList.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/Breakpoint/BreakpointIDList.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointList.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointList.cpp index 4a49b1e105ab..370da10d82b4 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointList.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointList.cpp @@ -9,15 +9,18 @@ #include "lldb/Breakpoint/BreakpointList.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Target.h" using namespace lldb; using namespace lldb_private; +static void NotifyChange(const BreakpointSP &bp, BreakpointEventType event) { + Target &target = bp->GetTarget(); + if (target.EventTypeHasListeners(Target::eBroadcastBitBreakpointChanged)) + target.BroadcastEvent(Target::eBroadcastBitBreakpointChanged, + new Breakpoint::BreakpointEventData(event, bp)); +} + BreakpointList::BreakpointList(bool is_internal) : m_mutex(), m_breakpoints(), m_next_break_id(0), m_is_internal(is_internal) {} @@ -26,37 +29,34 @@ BreakpointList::~BreakpointList() {} break_id_t BreakpointList::Add(BreakpointSP &bp_sp, bool notify) { std::lock_guard guard(m_mutex); + // Internal breakpoint IDs are negative, normal ones are positive bp_sp->SetID(m_is_internal ? --m_next_break_id : ++m_next_break_id); m_breakpoints.push_back(bp_sp); - if (notify) { - if (bp_sp->GetTarget().EventTypeHasListeners( - Target::eBroadcastBitBreakpointChanged)) - bp_sp->GetTarget().BroadcastEvent(Target::eBroadcastBitBreakpointChanged, - new Breakpoint::BreakpointEventData( - eBreakpointEventTypeAdded, bp_sp)); - } + + if (notify) + NotifyChange(bp_sp, eBreakpointEventTypeAdded); + return bp_sp->GetID(); } bool BreakpointList::Remove(break_id_t break_id, bool notify) { std::lock_guard guard(m_mutex); - bp_collection::iterator pos = GetBreakpointIDIterator(break_id); // Predicate - if (pos != m_breakpoints.end()) { - BreakpointSP bp_sp(*pos); - m_breakpoints.erase(pos); - if (notify) { - if (bp_sp->GetTarget().EventTypeHasListeners( - Target::eBroadcastBitBreakpointChanged)) - bp_sp->GetTarget().BroadcastEvent( - Target::eBroadcastBitBreakpointChanged, - new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved, - bp_sp)); - } - return true; - } - return false; + + auto it = std::find_if( + m_breakpoints.begin(), m_breakpoints.end(), + [&](const BreakpointSP &bp) { return bp->GetID() == break_id; }); + + if (it == m_breakpoints.end()) + return false; + + if (notify) + NotifyChange(*it, eBreakpointEventTypeRemoved); + + m_breakpoints.erase(it); + + return true; } void BreakpointList::RemoveInvalidLocations(const ArchSpec &arch) { @@ -83,93 +83,50 @@ void BreakpointList::RemoveAll(bool notify) { ClearAllBreakpointSites(); if (notify) { - bp_collection::iterator pos, end = m_breakpoints.end(); - for (pos = m_breakpoints.begin(); pos != end; ++pos) { - if ((*pos)->GetTarget().EventTypeHasListeners( - Target::eBroadcastBitBreakpointChanged)) { - (*pos)->GetTarget().BroadcastEvent( - Target::eBroadcastBitBreakpointChanged, - new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved, - *pos)); - } - } + for (const auto &bp_sp : m_breakpoints) + NotifyChange(bp_sp, eBreakpointEventTypeRemoved); } - m_breakpoints.erase(m_breakpoints.begin(), m_breakpoints.end()); + + m_breakpoints.clear(); } void BreakpointList::RemoveAllowed(bool notify) { std::lock_guard guard(m_mutex); - bp_collection::iterator pos, end = m_breakpoints.end(); - if (notify) { - for (pos = m_breakpoints.begin(); pos != end; ++pos) { - if(!(*pos)->AllowDelete()) - continue; - if ((*pos)->GetTarget().EventTypeHasListeners( - Target::eBroadcastBitBreakpointChanged)) { - (*pos)->GetTarget().BroadcastEvent( - Target::eBroadcastBitBreakpointChanged, - new Breakpoint::BreakpointEventData(eBreakpointEventTypeRemoved, - *pos)); - } - } - } - pos = m_breakpoints.begin(); - while ( pos != end) { - auto bp = *pos; - if (bp->AllowDelete()) { - bp->ClearAllBreakpointSites(); - pos = m_breakpoints.erase(pos); - } else - pos++; + for (const auto &bp_sp : m_breakpoints) { + if (bp_sp->AllowDelete()) + bp_sp->ClearAllBreakpointSites(); + if (notify) + NotifyChange(bp_sp, eBreakpointEventTypeRemoved); } + + m_breakpoints.erase( + std::remove_if(m_breakpoints.begin(), m_breakpoints.end(), + [&](const BreakpointSP &bp) { return bp->AllowDelete(); }), + m_breakpoints.end()); } -class BreakpointIDMatches { -public: - BreakpointIDMatches(break_id_t break_id) : m_break_id(break_id) {} - - bool operator()(const BreakpointSP &bp) const { - return m_break_id == bp->GetID(); - } - -private: - const break_id_t m_break_id; -}; - BreakpointList::bp_collection::iterator BreakpointList::GetBreakpointIDIterator(break_id_t break_id) { - return std::find_if(m_breakpoints.begin(), - m_breakpoints.end(), // Search full range - BreakpointIDMatches(break_id)); // Predicate + return std::find_if( + m_breakpoints.begin(), m_breakpoints.end(), + [&](const BreakpointSP &bp) { return bp->GetID() == break_id; }); } BreakpointList::bp_collection::const_iterator BreakpointList::GetBreakpointIDConstIterator(break_id_t break_id) const { - return std::find_if(m_breakpoints.begin(), - m_breakpoints.end(), // Search full range - BreakpointIDMatches(break_id)); // Predicate + return std::find_if( + m_breakpoints.begin(), m_breakpoints.end(), + [&](const BreakpointSP &bp) { return bp->GetID() == break_id; }); } -BreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) { +BreakpointSP BreakpointList::FindBreakpointByID(break_id_t break_id) const { std::lock_guard guard(m_mutex); - BreakpointSP stop_sp; - bp_collection::iterator pos = GetBreakpointIDIterator(break_id); - if (pos != m_breakpoints.end()) - stop_sp = *pos; - return stop_sp; -} - -const BreakpointSP -BreakpointList::FindBreakpointByID(break_id_t break_id) const { - std::lock_guard guard(m_mutex); - BreakpointSP stop_sp; - bp_collection::const_iterator pos = GetBreakpointIDConstIterator(break_id); - if (pos != m_breakpoints.end()) - stop_sp = *pos; - - return stop_sp; + auto it = GetBreakpointIDConstIterator(break_id); + if (it != m_breakpoints.end()) + return *it; + return {}; } bool BreakpointList::FindBreakpointsByName(const char *name, @@ -186,6 +143,7 @@ bool BreakpointList::FindBreakpointsByName(const char *name, matching_bps.Add(bkpt_sp, false); } } + return true; } @@ -201,30 +159,11 @@ void BreakpointList::Dump(Stream *s) const { s->IndentLess(); } -BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) { +BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const { std::lock_guard guard(m_mutex); - BreakpointSP stop_sp; - bp_collection::iterator end = m_breakpoints.end(); - bp_collection::iterator pos; - size_t curr_i = 0; - for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) { - if (curr_i == i) - stop_sp = *pos; - } - return stop_sp; -} - -const BreakpointSP BreakpointList::GetBreakpointAtIndex(size_t i) const { - std::lock_guard guard(m_mutex); - BreakpointSP stop_sp; - bp_collection::const_iterator end = m_breakpoints.end(); - bp_collection::const_iterator pos; - size_t curr_i = 0; - for (pos = m_breakpoints.begin(), curr_i = 0; pos != end; ++pos, ++curr_i) { - if (curr_i == i) - stop_sp = *pos; - } - return stop_sp; + if (i < m_breakpoints.size()) + return m_breakpoints[i]; + return {}; } void BreakpointList::UpdateBreakpoints(ModuleList &module_list, bool added, diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocation.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocation.cpp index 932147703304..5d3763a367c3 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocation.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocation.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/BreakpointID.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocationCollection.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocationCollection.cpp index 6536002bda67..27957a50d2b0 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocationCollection.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocationCollection.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocationCollection.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocationList.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocationList.cpp index 23ca89da6ce1..6a3280e961cc 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocationList.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointLocationList.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocationList.h" #include "lldb/Breakpoint/Breakpoint.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointName.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointName.cpp index be4710d7849c..baf871ebbae1 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointName.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointName.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/Support/Casting.h" -// Project includes #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointOptions.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointOptions.cpp index b5869fc34dfc..ff497c5633b0 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointOptions.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointOptions.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolver.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolver.cpp index 6ab578dd8576..0a1eeed28954 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolver.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolver.cpp @@ -9,10 +9,6 @@ #include "lldb/Breakpoint/BreakpointResolver.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" // Have to include the other breakpoint resolver types here so the static @@ -21,6 +17,7 @@ #include "lldb/Breakpoint/BreakpointResolverFileLine.h" #include "lldb/Breakpoint/BreakpointResolverFileRegex.h" #include "lldb/Breakpoint/BreakpointResolverName.h" +#include "lldb/Breakpoint/BreakpointResolverScripted.h" #include "lldb/Core/Address.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/SearchFilter.h" @@ -44,9 +41,10 @@ const char *BreakpointResolver::g_ty_to_name[] = {"FileAndLine", "Address", const char *BreakpointResolver::g_option_names[static_cast( BreakpointResolver::OptionNames::LastOptionName)] = { - "AddressOffset", "Exact", "FileName", "Inlines", "Language", - "LineNumber", "ModuleName", "NameMask", "Offset", "Regex", - "SectionName", "SkipPrologue", "SymbolNames"}; + "AddressOffset", "Exact", "FileName", "Inlines", "Language", + "LineNumber", "Column", "ModuleName", "NameMask", "Offset", + "PythonClass", "Regex", "ScriptArgs", "SectionName", "SearchDepth", + "SkipPrologue", "SymbolNames"}; const char *BreakpointResolver::ResolverTyToName(enum ResolverTy type) { if (type > LastKnownResolverType) @@ -132,6 +130,10 @@ BreakpointResolverSP BreakpointResolver::CreateFromStructuredData( resolver = BreakpointResolverFileRegex::CreateFromStructuredData( nullptr, *subclass_options, error); break; + case PythonResolver: + resolver = BreakpointResolverScripted::CreateFromStructuredData( + nullptr, *subclass_options, error); + break; case ExceptionResolver: error.SetErrorString("Exception resolvers are hard."); break; @@ -165,6 +167,7 @@ StructuredData::DictionarySP BreakpointResolver::WrapOptionsDict( void BreakpointResolver::SetBreakpoint(Breakpoint *bkpt) { m_breakpoint = bkpt; + NotifyBreakpointSet(); } void BreakpointResolver::ResolveBreakpointInModules(SearchFilter &filter, @@ -176,133 +179,162 @@ void BreakpointResolver::ResolveBreakpoint(SearchFilter &filter) { filter.Search(*this); } +namespace { +struct SourceLoc { + uint32_t line = UINT32_MAX; + uint32_t column; + SourceLoc(uint32_t l, uint32_t c) : line(l), column(c ? c : UINT32_MAX) {} + SourceLoc(const SymbolContext &sc) + : line(sc.line_entry.line), + column(sc.line_entry.column ? sc.line_entry.column : UINT32_MAX) {} +}; + +bool operator<(const SourceLoc a, const SourceLoc b) { + if (a.line < b.line) + return true; + if (a.line > b.line) + return false; + uint32_t a_col = a.column ? a.column : UINT32_MAX; + uint32_t b_col = b.column ? b.column : UINT32_MAX; + return a_col < b_col; +} +} // namespace + void BreakpointResolver::SetSCMatchesByLine(SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, - llvm::StringRef log_ident) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + llvm::StringRef log_ident, + uint32_t line, uint32_t column) { + llvm::SmallVector all_scs; + for (uint32_t i = 0; i < sc_list.GetSize(); ++i) + all_scs.push_back(sc_list[i]); - while (sc_list.GetSize() > 0) { - SymbolContextList tmp_sc_list; - unsigned current_idx = 0; - SymbolContext sc; - bool first_entry = true; + while (all_scs.size()) { + uint32_t closest_line = UINT32_MAX; - FileSpec match_file_spec; - FileSpec match_original_file_spec; - uint32_t closest_line_number = UINT32_MAX; - - // Pull out the first entry, and all the others that match its file spec, - // and stuff them in the tmp list. - while (current_idx < sc_list.GetSize()) { - bool matches; - - sc_list.GetContextAtIndex(current_idx, sc); - if (first_entry) { - match_file_spec = sc.line_entry.file; - match_original_file_spec = sc.line_entry.original_file; - matches = true; - first_entry = false; - } else - matches = ((sc.line_entry.file == match_file_spec) || - (sc.line_entry.original_file == match_original_file_spec)); - - if (matches) { - tmp_sc_list.Append(sc); - sc_list.RemoveContextAtIndex(current_idx); - - // ResolveSymbolContext will always return a number that is >= the line - // number you pass in. So the smaller line number is always better. - if (sc.line_entry.line < closest_line_number) - closest_line_number = sc.line_entry.line; - } else - current_idx++; - } - - // Okay, we've found the closest line number match, now throw away all the - // others: - - current_idx = 0; - while (current_idx < tmp_sc_list.GetSize()) { - if (tmp_sc_list.GetContextAtIndex(current_idx, sc)) { - if (sc.line_entry.line != closest_line_number) - tmp_sc_list.RemoveContextAtIndex(current_idx); - else - current_idx++; - } - } - - // Next go through and see if there are line table entries that are - // contiguous, and if so keep only the first of the contiguous range: - - current_idx = 0; - std::map blocks_with_breakpoints; - - while (current_idx < tmp_sc_list.GetSize()) { - if (tmp_sc_list.GetContextAtIndex(current_idx, sc)) { - if (blocks_with_breakpoints.find(sc.block) != - blocks_with_breakpoints.end()) - tmp_sc_list.RemoveContextAtIndex(current_idx); - else { - blocks_with_breakpoints.insert(std::pair( - sc.block, sc.line_entry.range.GetBaseAddress().GetFileAddress())); - current_idx++; - } - } - } - - // and make breakpoints out of the closest line number match. - - uint32_t tmp_sc_list_size = tmp_sc_list.GetSize(); - - for (uint32_t i = 0; i < tmp_sc_list_size; i++) { - if (tmp_sc_list.GetContextAtIndex(i, sc)) { - Address line_start = sc.line_entry.range.GetBaseAddress(); - if (line_start.IsValid()) { - if (filter.AddressPasses(line_start)) { - // If the line number is before the prologue end, move it there... - bool skipped_prologue = false; - if (skip_prologue) { - if (sc.function) { - Address prologue_addr( - sc.function->GetAddressRange().GetBaseAddress()); - if (prologue_addr.IsValid() && (line_start == prologue_addr)) { - const uint32_t prologue_byte_size = - sc.function->GetPrologueByteSize(); - if (prologue_byte_size) { - prologue_addr.Slide(prologue_byte_size); - - if (filter.AddressPasses(prologue_addr)) { - skipped_prologue = true; - line_start = prologue_addr; - } - } - } - } - } - - BreakpointLocationSP bp_loc_sp(AddLocation(line_start)); - if (log && bp_loc_sp && !m_breakpoint->IsInternal()) { - StreamString s; - bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); - log->Printf("Added location (skipped prologue: %s): %s \n", - skipped_prologue ? "yes" : "no", s.GetData()); - } - } else if (log) { - log->Printf("Breakpoint %s at file address 0x%" PRIx64 - " didn't pass the filter.\n", - log_ident.str().c_str(), line_start.GetFileAddress()); + // Move all the elements with a matching file spec to the end. + auto &match = all_scs[0]; + auto worklist_begin = std::partition( + all_scs.begin(), all_scs.end(), [&](const SymbolContext &sc) { + if (sc.line_entry.file == match.line_entry.file || + sc.line_entry.original_file == match.line_entry.original_file) { + // When a match is found, keep track of the smallest line number. + closest_line = std::min(closest_line, sc.line_entry.line); + return false; } - } else { - if (log) - log->Printf( - "error: Unable to set breakpoint %s at file address 0x%" PRIx64 - "\n", - log_ident.str().c_str(), line_start.GetFileAddress()); + return true; + }); + + // (worklist_begin, worklist_end) now contains all entries for one filespec. + auto worklist_end = all_scs.end(); + + if (column) { + // If a column was requested, do a more precise match and only + // return the first location that comes after or at the + // requested location. + SourceLoc requested(line, column); + // First, filter out all entries left of the requested column. + worklist_end = std::remove_if( + worklist_begin, worklist_end, + [&](const SymbolContext &sc) { return SourceLoc(sc) < requested; }); + // Sort the remaining entries by (line, column). + llvm::sort(worklist_begin, worklist_end, + [](const SymbolContext &a, const SymbolContext &b) { + return SourceLoc(a) < SourceLoc(b); + }); + + // Filter out all locations with a source location after the closest match. + if (worklist_begin != worklist_end) + worklist_end = std::remove_if( + worklist_begin, worklist_end, [&](const SymbolContext &sc) { + return SourceLoc(*worklist_begin) < SourceLoc(sc); + }); + } else { + // Remove all entries with a larger line number. + // ResolveSymbolContext will always return a number that is >= + // the line number you pass in. So the smaller line number is + // always better. + worklist_end = std::remove_if(worklist_begin, worklist_end, + [&](const SymbolContext &sc) { + return closest_line != sc.line_entry.line; + }); + } + + // Sort by file address. + llvm::sort(worklist_begin, worklist_end, + [](const SymbolContext &a, const SymbolContext &b) { + return a.line_entry.range.GetBaseAddress().GetFileAddress() < + b.line_entry.range.GetBaseAddress().GetFileAddress(); + }); + + // Go through and see if there are line table entries that are + // contiguous, and if so keep only the first of the contiguous range. + // We do this by picking the first location in each lexical block. + llvm::SmallDenseSet blocks_with_breakpoints; + for (auto first = worklist_begin; first != worklist_end; ++first) { + assert(!blocks_with_breakpoints.count(first->block)); + blocks_with_breakpoints.insert(first->block); + worklist_end = + std::remove_if(std::next(first), worklist_end, + [&](const SymbolContext &sc) { + return blocks_with_breakpoints.count(sc.block); + }); + } + + // Make breakpoints out of the closest line number match. + for (auto &sc : llvm::make_range(worklist_begin, worklist_end)) + AddLocation(filter, sc, skip_prologue, log_ident); + + // Remove all contexts processed by this iteration. + all_scs.erase(worklist_begin, all_scs.end()); + } +} + +void BreakpointResolver::AddLocation(SearchFilter &filter, + const SymbolContext &sc, + bool skip_prologue, + llvm::StringRef log_ident) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + Address line_start = sc.line_entry.range.GetBaseAddress(); + if (!line_start.IsValid()) { + if (log) + log->Printf("error: Unable to set breakpoint %s at file address " + "0x%" PRIx64 "\n", + log_ident.str().c_str(), line_start.GetFileAddress()); + return; + } + + if (!filter.AddressPasses(line_start)) { + if (log) + log->Printf("Breakpoint %s at file address 0x%" PRIx64 + " didn't pass the filter.\n", + log_ident.str().c_str(), line_start.GetFileAddress()); + } + + // If the line number is before the prologue end, move it there... + bool skipped_prologue = false; + if (skip_prologue && sc.function) { + Address prologue_addr(sc.function->GetAddressRange().GetBaseAddress()); + if (prologue_addr.IsValid() && (line_start == prologue_addr)) { + const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize(); + if (prologue_byte_size) { + prologue_addr.Slide(prologue_byte_size); + + if (filter.AddressPasses(prologue_addr)) { + skipped_prologue = true; + line_start = prologue_addr; } } } } + + BreakpointLocationSP bp_loc_sp(AddLocation(line_start)); + if (log && bp_loc_sp && !m_breakpoint->IsInternal()) { + StreamString s; + bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose); + log->Printf("Added location (skipped prologue: %s): %s \n", + skipped_prologue ? "yes" : "no", s.GetData()); + } } BreakpointLocationSP BreakpointResolver::AddLocation(Address loc_addr, @@ -315,7 +347,8 @@ void BreakpointResolver::SetOffset(lldb::addr_t offset) { // There may already be an offset, so we are actually adjusting location // addresses by the difference. // lldb::addr_t slide = offset - m_offset; - // FIXME: We should go fix up all the already set locations for the new slide. + // FIXME: We should go fix up all the already set locations for the new + // slide. m_offset = offset; } diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverAddress.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverAddress.cpp index d4647e2c589d..3084ce41e8e3 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverAddress.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverAddress.cpp @@ -9,10 +9,6 @@ #include "lldb/Breakpoint/BreakpointResolverAddress.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" @@ -66,7 +62,7 @@ BreakpointResolver *BreakpointResolverAddress::CreateFromStructuredData( error.SetErrorString("BRA::CFSD: Couldn't read module name entry."); return nullptr; } - module_filespec.SetFile(module_name, false, FileSpec::Style::native); + module_filespec.SetFile(module_name, FileSpec::Style::native); } return new BreakpointResolverAddress(bkpt, address, module_filespec); } @@ -173,8 +169,8 @@ BreakpointResolverAddress::SearchCallback(SearchFilter &filter, return Searcher::eCallbackReturnStop; } -Searcher::Depth BreakpointResolverAddress::GetDepth() { - return Searcher::eDepthTarget; +lldb::SearchDepth BreakpointResolverAddress::GetDepth() { + return lldb::eSearchDepthTarget; } void BreakpointResolverAddress::GetDescription(Stream *s) { diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp index ecef88eb9989..438f430bd2a5 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverFileLine.cpp @@ -9,10 +9,6 @@ #include "lldb/Breakpoint/BreakpointResolverFileLine.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/CompileUnit.h" @@ -28,11 +24,12 @@ using namespace lldb_private; //---------------------------------------------------------------------- BreakpointResolverFileLine::BreakpointResolverFileLine( Breakpoint *bkpt, const FileSpec &file_spec, uint32_t line_no, - lldb::addr_t offset, bool check_inlines, bool skip_prologue, - bool exact_match) + uint32_t column, lldb::addr_t offset, bool check_inlines, + bool skip_prologue, bool exact_match) : BreakpointResolver(bkpt, BreakpointResolver::FileLineResolver, offset), - m_file_spec(file_spec), m_line_number(line_no), m_inlines(check_inlines), - m_skip_prologue(skip_prologue), m_exact_match(exact_match) {} + m_file_spec(file_spec), m_line_number(line_no), m_column(column), + m_inlines(check_inlines), m_skip_prologue(skip_prologue), + m_exact_match(exact_match) {} BreakpointResolverFileLine::~BreakpointResolverFileLine() {} @@ -41,6 +38,7 @@ BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( Status &error) { llvm::StringRef filename; uint32_t line_no; + uint32_t column; bool check_inlines; bool skip_prologue; bool exact_match; @@ -62,6 +60,13 @@ BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( return nullptr; } + success = + options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Column), column); + if (!success) { + // Backwards compatibility. + column = 0; + } + success = options_dict.GetValueForKeyAsBoolean(GetKey(OptionNames::Inlines), check_inlines); if (!success) { @@ -83,10 +88,10 @@ BreakpointResolver *BreakpointResolverFileLine::CreateFromStructuredData( return nullptr; } - FileSpec file_spec(filename, false); + FileSpec file_spec(filename); - return new BreakpointResolverFileLine(bkpt, file_spec, line_no, offset, - check_inlines, skip_prologue, + return new BreakpointResolverFileLine(bkpt, file_spec, line_no, column, + offset, check_inlines, skip_prologue, exact_match); } @@ -99,6 +104,8 @@ BreakpointResolverFileLine::SerializeToStructuredData() { m_file_spec.GetPath()); options_dict_sp->AddIntegerItem(GetKey(OptionNames::LineNumber), m_line_number); + options_dict_sp->AddIntegerItem(GetKey(OptionNames::Column), + m_column); options_dict_sp->AddBooleanItem(GetKey(OptionNames::Inlines), m_inlines); options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue), m_skip_prologue); @@ -181,8 +188,12 @@ void BreakpointResolverFileLine::FilterContexts(SymbolContextList &sc_list, // inline int foo2() { ... } // // but that's the best we can do for now. + // One complication, if the line number returned from GetStartLineSourceInfo + // is 0, then we can't do this calculation. That can happen if + // GetStartLineSourceInfo gets an error, or if the first line number in + // the function really is 0 - which happens for some languages. const int decl_line_is_too_late_fudge = 1; - if (m_line_number < line - decl_line_is_too_late_fudge) { + if (line && m_line_number < line - decl_line_is_too_late_fudge) { LLDB_LOG(log, "removing symbol context at {0}:{1}", file, line); sc_list.RemoveContextAtIndex(i); --i; @@ -236,18 +247,22 @@ BreakpointResolverFileLine::SearchCallback(SearchFilter &filter, s.Printf("for %s:%d ", m_file_spec.GetFilename().AsCString(""), m_line_number); - SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString()); + SetSCMatchesByLine(filter, sc_list, m_skip_prologue, s.GetString(), + m_line_number, m_column); return Searcher::eCallbackReturnContinue; } -Searcher::Depth BreakpointResolverFileLine::GetDepth() { - return Searcher::eDepthModule; +lldb::SearchDepth BreakpointResolverFileLine::GetDepth() { + return lldb::eSearchDepthModule; } void BreakpointResolverFileLine::GetDescription(Stream *s) { - s->Printf("file = '%s', line = %u, exact_match = %d", - m_file_spec.GetPath().c_str(), m_line_number, m_exact_match); + s->Printf("file = '%s', line = %u, ", m_file_spec.GetPath().c_str(), + m_line_number); + if (m_column) + s->Printf("column = %u, ", m_column); + s->Printf("exact_match = %d", m_exact_match); } void BreakpointResolverFileLine::Dump(Stream *s) const {} @@ -255,7 +270,7 @@ void BreakpointResolverFileLine::Dump(Stream *s) const {} lldb::BreakpointResolverSP BreakpointResolverFileLine::CopyForBreakpoint(Breakpoint &breakpoint) { lldb::BreakpointResolverSP ret_sp(new BreakpointResolverFileLine( - &breakpoint, m_file_spec, m_line_number, m_offset, m_inlines, + &breakpoint, m_file_spec, m_line_number, m_column, m_offset, m_inlines, m_skip_prologue, m_exact_match)); return ret_sp; diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp index 54c05a042468..62cf9553c82c 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverFileRegex.cpp @@ -9,10 +9,6 @@ #include "lldb/Breakpoint/BreakpointResolverFileRegex.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/SourceManager.h" #include "lldb/Symbol/CompileUnit.h" @@ -157,8 +153,8 @@ BreakpointResolverFileRegex::SearchCallback(SearchFilter &filter, return Searcher::eCallbackReturnContinue; } -Searcher::Depth BreakpointResolverFileRegex::GetDepth() { - return Searcher::eDepthCompUnit; +lldb::SearchDepth BreakpointResolverFileRegex::GetDepth() { + return lldb::eSearchDepthCompUnit; } void BreakpointResolverFileRegex::GetDescription(Stream *s) { diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverName.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverName.cpp index ba277ae2655e..43f7cb85a574 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverName.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverName.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointResolverName.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" @@ -30,7 +26,7 @@ using namespace lldb; using namespace lldb_private; BreakpointResolverName::BreakpointResolverName( - Breakpoint *bkpt, const char *name_cstr, uint32_t name_type_mask, + Breakpoint *bkpt, const char *name_cstr, FunctionNameType name_type_mask, LanguageType language, Breakpoint::MatchType type, lldb::addr_t offset, bool skip_prologue) : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset), @@ -51,7 +47,7 @@ BreakpointResolverName::BreakpointResolverName( BreakpointResolverName::BreakpointResolverName( Breakpoint *bkpt, const char *names[], size_t num_names, - uint32_t name_type_mask, LanguageType language, lldb::addr_t offset, + FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset, bool skip_prologue) : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset), m_match_type(Breakpoint::Exact), m_language(language), @@ -61,9 +57,12 @@ BreakpointResolverName::BreakpointResolverName( } } -BreakpointResolverName::BreakpointResolverName( - Breakpoint *bkpt, std::vector names, uint32_t name_type_mask, - LanguageType language, lldb::addr_t offset, bool skip_prologue) +BreakpointResolverName::BreakpointResolverName(Breakpoint *bkpt, + std::vector names, + FunctionNameType name_type_mask, + LanguageType language, + lldb::addr_t offset, + bool skip_prologue) : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset), m_match_type(Breakpoint::Exact), m_language(language), m_skip_prologue(skip_prologue) { @@ -161,9 +160,8 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData( return nullptr; } std::vector names; - std::vector name_masks; + std::vector name_masks; for (size_t i = 0; i < num_elem; i++) { - uint32_t name_mask; llvm::StringRef name; success = names_array->GetItemAtIndexAsString(i, name); @@ -171,13 +169,14 @@ BreakpointResolver *BreakpointResolverName::CreateFromStructuredData( error.SetErrorString("BRN::CFSD: name entry is not a string."); return nullptr; } - success = names_mask_array->GetItemAtIndexAsInteger(i, name_mask); + std::underlying_type::type fnt; + success = names_mask_array->GetItemAtIndexAsInteger(i, fnt); if (!success) { error.SetErrorString("BRN::CFSD: name mask entry is not an integer."); return nullptr; } names.push_back(name); - name_masks.push_back(name_mask); + name_masks.push_back(static_cast(fnt)); } BreakpointResolverName *resolver = new BreakpointResolverName( @@ -220,7 +219,7 @@ StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() { } void BreakpointResolverName::AddNameLookup(const ConstString &name, - uint32_t name_type_mask) { + FunctionNameType name_type_mask) { ObjCLanguage::MethodName objc_method(name.GetCString(), false); if (objc_method.IsValid(false)) { std::vector objc_names; @@ -396,8 +395,8 @@ BreakpointResolverName::SearchCallback(SearchFilter &filter, return Searcher::eCallbackReturnContinue; } -Searcher::Depth BreakpointResolverName::GetDepth() { - return Searcher::eDepthModule; +lldb::SearchDepth BreakpointResolverName::GetDepth() { + return lldb::eSearchDepthModule; } void BreakpointResolverName::GetDescription(Stream *s) { diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverScripted.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverScripted.cpp new file mode 100644 index 000000000000..47940ef60703 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointResolverScripted.cpp @@ -0,0 +1,189 @@ +//===-- BreakpointResolverScripted.cpp ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Breakpoint/BreakpointResolverScripted.h" + + +#include "lldb/Breakpoint/BreakpointLocation.h" +#include "lldb/Core/Debugger.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/StructuredDataImpl.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/StreamString.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// BreakpointResolverScripted: +//---------------------------------------------------------------------- +BreakpointResolverScripted::BreakpointResolverScripted( + Breakpoint *bkpt, + const llvm::StringRef class_name, + lldb::SearchDepth depth, + StructuredDataImpl *args_data, + ScriptInterpreter &script_interp) + : BreakpointResolver(bkpt, BreakpointResolver::PythonResolver), + m_class_name(class_name), m_depth(depth), m_args_ptr(args_data) { + CreateImplementationIfNeeded(); +} + +void BreakpointResolverScripted::CreateImplementationIfNeeded() { + if (m_implementation_sp) + return; + + if (m_class_name.empty()) + return; + + if (m_breakpoint) { + TargetSP target_sp = m_breakpoint->GetTargetSP(); + ScriptInterpreter *script_interp = target_sp->GetDebugger() + .GetCommandInterpreter() + .GetScriptInterpreter(); + if (!script_interp) + return; + lldb::BreakpointSP bkpt_sp(m_breakpoint->shared_from_this()); + m_implementation_sp = script_interp->CreateScriptedBreakpointResolver( + m_class_name.c_str(), m_args_ptr, bkpt_sp); + } +} + +void BreakpointResolverScripted::NotifyBreakpointSet() { + CreateImplementationIfNeeded(); +} + +BreakpointResolverScripted::~BreakpointResolverScripted() {} + +BreakpointResolver * +BreakpointResolverScripted::CreateFromStructuredData( + Breakpoint *bkpt, const StructuredData::Dictionary &options_dict, + Status &error) { + llvm::StringRef class_name; + bool success; + + if (!bkpt) + return nullptr; + + success = options_dict.GetValueForKeyAsString( + GetKey(OptionNames::PythonClassName), class_name); + if (!success) { + error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); + return nullptr; + } + lldb::SearchDepth depth; + int depth_as_int; + success = options_dict.GetValueForKeyAsInteger( + GetKey(OptionNames::SearchDepth), depth_as_int); + if (!success) { + error.SetErrorString("BRFL::CFSD: Couldn't find class name entry."); + return nullptr; + } + if (depth_as_int >= (int) OptionNames::LastOptionName) { + error.SetErrorString("BRFL::CFSD: Invalid value for search depth."); + return nullptr; + } + depth = (lldb::SearchDepth) depth_as_int; + + StructuredDataImpl *args_data_impl = new StructuredDataImpl(); + StructuredData::Dictionary *args_dict = new StructuredData::Dictionary(); + success = options_dict.GetValueForKeyAsDictionary( + GetKey(OptionNames::ScriptArgs), args_dict); + if (success) { + // FIXME: The resolver needs a copy of the ARGS dict that it can own, + // so I need to make a copy constructor for the Dictionary so I can pass + // that to it here. For now the args are empty. + //StructuredData::Dictionary *dict_copy = new StructuredData::Dictionary(args_dict); + + } + ScriptInterpreter *script_interp = bkpt->GetTarget() + .GetDebugger() + .GetCommandInterpreter() + .GetScriptInterpreter(); + return new BreakpointResolverScripted(bkpt, class_name, depth, args_data_impl, + *script_interp); +} + +StructuredData::ObjectSP +BreakpointResolverScripted::SerializeToStructuredData() { + StructuredData::DictionarySP options_dict_sp( + new StructuredData::Dictionary()); + + options_dict_sp->AddStringItem(GetKey(OptionNames::PythonClassName), + m_class_name); + return WrapOptionsDict(options_dict_sp); +} + +ScriptInterpreter *BreakpointResolverScripted::GetScriptInterpreter() { + return m_breakpoint->GetTarget().GetDebugger().GetCommandInterpreter() + .GetScriptInterpreter(); +} + +Searcher::CallbackReturn +BreakpointResolverScripted::SearchCallback(SearchFilter &filter, + SymbolContext &context, Address *addr, + bool containing) { + assert(m_breakpoint != NULL); + bool should_continue = true; + if (!m_implementation_sp) + return Searcher::eCallbackReturnStop; + + ScriptInterpreter *interp = GetScriptInterpreter(); + should_continue = interp->ScriptedBreakpointResolverSearchCallback( + m_implementation_sp, + &context); + if (should_continue) + return Searcher::eCallbackReturnContinue; + else + return Searcher::eCallbackReturnStop; +} + +lldb::SearchDepth +BreakpointResolverScripted::GetDepth() { + assert(m_breakpoint != NULL); + lldb::SearchDepth depth = lldb::eSearchDepthModule; + if (m_implementation_sp) { + ScriptInterpreter *interp = GetScriptInterpreter(); + depth = interp->ScriptedBreakpointResolverSearchDepth( + m_implementation_sp); + } + return depth; +} + +void BreakpointResolverScripted::GetDescription(Stream *s) { + StructuredData::GenericSP generic_sp; + std::string short_help; + + if (m_implementation_sp) { + ScriptInterpreter *interp = GetScriptInterpreter(); + interp->GetShortHelpForCommandObject(m_implementation_sp, + short_help); + } + if (!short_help.empty()) + s->PutCString(short_help.c_str()); + else + s->Printf("python class = %s", m_class_name.c_str()); +} + +void BreakpointResolverScripted::Dump(Stream *s) const {} + +lldb::BreakpointResolverSP +BreakpointResolverScripted::CopyForBreakpoint(Breakpoint &breakpoint) { + ScriptInterpreter *script_interp = GetScriptInterpreter(); + // FIXME: Have to make a copy of the arguments from the m_args_ptr and then + // pass that to the new resolver. + lldb::BreakpointResolverSP ret_sp( + new BreakpointResolverScripted(&breakpoint, m_class_name, + m_depth, nullptr, *script_interp)); + return ret_sp; +} diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSite.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSite.cpp index a5c5136eb7a6..73c1357ce963 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSite.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSite.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Breakpoint/Breakpoint.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSiteList.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSiteList.cpp index 9bb9aa366106..2fe107ee3e30 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSiteList.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/BreakpointSiteList.cpp @@ -9,10 +9,6 @@ #include "lldb/Breakpoint/BreakpointSiteList.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Stream.h" #include diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/Stoppoint.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/Stoppoint.cpp index dbc832b4307a..13a8b837469f 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/Stoppoint.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/Stoppoint.cpp @@ -10,10 +10,6 @@ #include "lldb/Breakpoint/Stoppoint.h" #include "lldb/lldb-private.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/StoppointCallbackContext.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/StoppointCallbackContext.cpp index 3d24eb78c455..828ff18c433f 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/StoppointCallbackContext.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/StoppointCallbackContext.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/StoppointCallbackContext.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/StoppointLocation.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/StoppointLocation.cpp index d624ddbfa519..73394668508b 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/StoppointLocation.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/StoppointLocation.cpp @@ -9,10 +9,6 @@ #include "lldb/Breakpoint/StoppointLocation.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/Watchpoint.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/Watchpoint.cpp index 7a936d1fb130..34daaee64ccd 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/Watchpoint.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/Watchpoint.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" @@ -135,10 +131,7 @@ void Watchpoint::IncrementFalseAlarmsAndReviseHitCount() { bool Watchpoint::ShouldStop(StoppointCallbackContext *context) { IncrementHitCount(); - if (!IsEnabled()) - return false; - - return true; + return IsEnabled(); } void Watchpoint::GetDescription(Stream *s, lldb::DescriptionLevel level) { diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/WatchpointList.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/WatchpointList.cpp index 6497780084d9..e1e2864ba0eb 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/WatchpointList.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/WatchpointList.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/WatchpointList.h" #include "lldb/Breakpoint/Watchpoint.h" diff --git a/contrib/llvm/tools/lldb/source/Breakpoint/WatchpointOptions.cpp b/contrib/llvm/tools/lldb/source/Breakpoint/WatchpointOptions.cpp index 402fee943a02..033eb66014b9 100644 --- a/contrib/llvm/tools/lldb/source/Breakpoint/WatchpointOptions.cpp +++ b/contrib/llvm/tools/lldb/source/Breakpoint/WatchpointOptions.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/WatchpointOptions.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandCompletions.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandCompletions.cpp index 7b351c50dc69..705e87651a8c 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandCompletions.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandCompletions.cpp @@ -7,18 +7,14 @@ // //===----------------------------------------------------------------------===// -// C Includes #include #if defined(__APPLE__) || defined(__linux__) #include #endif -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSet.h" -// Project includes #include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" @@ -105,7 +101,6 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, if (CompletionBuffer.size() >= PATH_MAX) return matches.GetSize(); - namespace fs = llvm::sys::fs; namespace path = llvm::sys::path; llvm::StringRef SearchDir; @@ -121,7 +116,7 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, if (FirstSep != llvm::StringRef::npos) Remainder = Buffer.drop_front(FirstSep + 1); - llvm::SmallString Resolved; + llvm::SmallString<256> Resolved; if (!Resolver.ResolveExact(Username, Resolved)) { // We couldn't resolve it as a full username. If there were no slashes // then this might be a partial username. We try to resolve it as such @@ -166,7 +161,11 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, size_t FullPrefixLen = CompletionBuffer.size(); PartialItem = path::filename(CompletionBuffer); - if (PartialItem == ".") + + // path::filename() will return "." when the passed path ends with a + // directory separator. We have to filter those out, but only when the + // "." doesn't come from the completion request itself. + if (PartialItem == "." && path::is_separator(CompletionBuffer.back())) PartialItem = llvm::StringRef(); if (SearchDir.empty()) { @@ -178,11 +177,16 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, // SearchDir now contains the directory to search in, and Prefix contains the // text we want to match against items in that directory. + FileSystem &fs = FileSystem::Instance(); std::error_code EC; - fs::directory_iterator Iter(SearchDir, EC, false); - fs::directory_iterator End; + llvm::vfs::directory_iterator Iter = fs.DirBegin(SearchDir, EC); + llvm::vfs::directory_iterator End; for (; Iter != End && !EC; Iter.increment(EC)) { auto &Entry = *Iter; + llvm::ErrorOr Status = fs.GetStatus(Entry.path()); + + if (!Status) + continue; auto Name = path::filename(Entry.path()); @@ -190,20 +194,18 @@ static int DiskFilesOrDirectories(const llvm::Twine &partial_name, if (Name == "." || Name == ".." || !Name.startswith(PartialItem)) continue; - // We have a match. - - llvm::ErrorOr st = Entry.status(); - if (!st) - continue; + bool is_dir = Status->isDirectory(); // If it's a symlink, then we treat it as a directory as long as the target // is a directory. - bool is_dir = fs::is_directory(*st); - if (fs::is_symlink_file(*st)) { - fs::file_status target_st; - if (!fs::status(Entry.path(), target_st)) - is_dir = fs::is_directory(target_st); + if (Status->isSymlink()) { + FileSpec symlink_filespec(Entry.path()); + FileSpec resolved_filespec; + auto error = fs.ResolveSymbolicLink(symlink_filespec, resolved_filespec); + if (error.Success()) + is_dir = fs.IsDirectory(symlink_filespec); } + if (only_directories && !is_dir) continue; @@ -357,13 +359,13 @@ CommandCompletions::SourceFileCompleter::SourceFileCompleter( CompletionRequest &request) : CommandCompletions::Completer(interpreter, request), m_include_support_files(include_support_files), m_matching_files() { - FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false); + FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); m_file_name = partial_spec.GetFilename().GetCString(); m_dir_name = partial_spec.GetDirectory().GetCString(); } -Searcher::Depth CommandCompletions::SourceFileCompleter::GetDepth() { - return eDepthCompUnit; +lldb::SearchDepth CommandCompletions::SourceFileCompleter::GetDepth() { + return lldb::eSearchDepthCompUnit; } Searcher::CallbackReturn @@ -454,8 +456,8 @@ CommandCompletions::SymbolCompleter::SymbolCompleter( m_regex.Compile(regex_str); } -Searcher::Depth CommandCompletions::SymbolCompleter::GetDepth() { - return eDepthModule; +lldb::SearchDepth CommandCompletions::SymbolCompleter::GetDepth() { + return lldb::eSearchDepthModule; } Searcher::CallbackReturn CommandCompletions::SymbolCompleter::SearchCallback( @@ -497,13 +499,13 @@ size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) { CommandCompletions::ModuleCompleter::ModuleCompleter( CommandInterpreter &interpreter, CompletionRequest &request) : CommandCompletions::Completer(interpreter, request) { - FileSpec partial_spec(m_request.GetCursorArgumentPrefix(), false); + FileSpec partial_spec(m_request.GetCursorArgumentPrefix()); m_file_name = partial_spec.GetFilename().GetCString(); m_dir_name = partial_spec.GetDirectory().GetCString(); } -Searcher::Depth CommandCompletions::ModuleCompleter::GetDepth() { - return eDepthModule; +lldb::SearchDepth CommandCompletions::ModuleCompleter::GetDepth() { + return lldb::eSearchDepthModule; } Searcher::CallbackReturn CommandCompletions::ModuleCompleter::SearchCallback( diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectApropos.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectApropos.cpp index 047575278faa..69c2760ded4e 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectApropos.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectApropos.cpp @@ -8,10 +8,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "CommandObjectApropos.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectApropos.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectApropos.h index 5cad40d5c62d..acd4cedfe9fd 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectApropos.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectApropos.h @@ -11,10 +11,6 @@ #ifndef liblldb_CommandObjectApropos_h_ #define liblldb_CommandObjectApropos_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp index fb0553e482db..8eb6a5fa5a02 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "CommandObjectBreakpoint.h" #include "CommandObjectBreakpointCommand.h" #include "lldb/Breakpoint/Breakpoint.h" @@ -50,19 +46,19 @@ static void AddBreakpointDescription(Stream *s, Breakpoint *bp, // Modifiable Breakpoint Options //------------------------------------------------------------------------- #pragma mark Modify::CommandOptions -static OptionDefinition g_breakpoint_modify_options[] = { +static constexpr OptionDefinition g_breakpoint_modify_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, - { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, - { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." }, - { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." }, - { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." }, - { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." }, - { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." }, - { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." }, - { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable the breakpoint." }, - { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disable the breakpoint." }, - { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." }, + { LLDB_OPT_SET_1, false, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Set the number of times this breakpoint is skipped before stopping." }, + { LLDB_OPT_SET_1, false, "one-shot", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint is deleted the first time it stop causes a stop." }, + { LLDB_OPT_SET_1, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The breakpoint stops only for the thread whose index matches this argument." }, + { LLDB_OPT_SET_1, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The breakpoint stops only for the thread whose TID matches this argument." }, + { LLDB_OPT_SET_1, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The breakpoint stops only for the thread whose thread name matches this argument." }, + { LLDB_OPT_SET_1, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The breakpoint stops only for threads in the queue whose name is given by this argument." }, + { LLDB_OPT_SET_1, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "The breakpoint stops only if this condition expression evaluates to true." }, + { LLDB_OPT_SET_1, false, "auto-continue",'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "The breakpoint will auto-continue after running its commands." }, + { LLDB_OPT_SET_2, false, "enable", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable the breakpoint." }, + { LLDB_OPT_SET_3, false, "disable", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disable the breakpoint." }, + { LLDB_OPT_SET_4, false, "command", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommand, "A command to run when the breakpoint is hit, can be provided more than once, the commands will get run in order left to right." }, // clang-format on }; class lldb_private::BreakpointOptionGroup : public OptionGroup @@ -198,9 +194,9 @@ public: BreakpointOptions m_bp_opts; }; -static OptionDefinition g_breakpoint_dummy_options[] = { +static constexpr OptionDefinition g_breakpoint_dummy_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, " + { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Act on Dummy breakpoints - i.e. breakpoints set before a file is provided, " "which prime new targets." }, // clang-format on }; @@ -245,23 +241,23 @@ public: // If an additional option set beyond LLDB_OPTION_SET_10 is added, make sure to // update the numbers passed to LLDB_OPT_SET_FROM_TO(...) appropriately. -#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 9) & ~LLDB_OPT_SET_2) -#define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 10) & ~LLDB_OPT_SET_10) +#define LLDB_OPT_NOT_10 (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_10) #define LLDB_OPT_SKIP_PROLOGUE (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8)) -#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_1 | LLDB_OPT_SET_FROM_TO(3, 8)) +#define LLDB_OPT_FILE (LLDB_OPT_SET_FROM_TO(1, 11) & ~LLDB_OPT_SET_2 & ~LLDB_OPT_SET_10) +#define LLDB_OPT_OFFSET_APPLIES (LLDB_OPT_SET_FROM_TO(1, 8) & ~LLDB_OPT_SET_2) #define LLDB_OPT_MOVE_TO_NEAREST_CODE (LLDB_OPT_SET_1 | LLDB_OPT_SET_9) #define LLDB_OPT_EXPR_LANGUAGE (LLDB_OPT_SET_FROM_TO(3, 8)) -static OptionDefinition g_breakpoint_set_options[] = { +static constexpr OptionDefinition g_breakpoint_set_options[] = { // clang-format off - { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option " + { LLDB_OPT_NOT_10, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the breakpoint only in this shared library. Can repeat this option " "multiple times to specify multiple shared libraries." }, - { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." }, - { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default " + { LLDB_OPT_SET_ALL, false, "hardware", 'H', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Require the breakpoint to use hardware breakpoints." }, + { LLDB_OPT_FILE, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file in which to set this breakpoint. Note, by default " "lldb only looks for files that are #included if they use the standard include " "file extensions. To set breakpoints on .c/.cpp/.m/.mm files that are " "#included, set target.inline-breakpoint-strategy to \"always\"." }, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." }, + { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specifies the line number on which to set this breakpoint." }, // Comment out this option for the moment, as we don't actually use it, but // will in the future. This way users won't see it, but the infrastructure is @@ -269,7 +265,7 @@ static OptionDefinition g_breakpoint_set_options[] = { // { 0, false, "column", 'C', OptionParser::eRequiredArgument, nullptr, "", // "Set the breakpoint by source location at this particular column."}, - { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to " + { LLDB_OPT_SET_2, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Set the breakpoint at the specified address. If the address maps uniquely to " "a particular binary, then the address will be converted to a \"file\" " "address, so that the breakpoint will track that binary+offset no matter where " "the binary eventually loads. Alternately, if you also specify the module - " @@ -278,47 +274,50 @@ static OptionDefinition g_breakpoint_set_options[] = { "that offset on subsequent reloads. The module need not have been loaded at " "the time you specify this breakpoint, and will get resolved when the module " "is loaded." }, - { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make " + { LLDB_OPT_SET_3, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function name. Can be repeated multiple times to make " "one breakpoint for multiple names" }, - { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named " + { LLDB_OPT_SET_9, false, "source-regexp-function", 'X', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "When used with '-p' limits the source regex to source contained in the named " "functions. Can be repeated multiple times." }, - { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means " + { LLDB_OPT_SET_4, true, "fullname", 'F', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFullName, "Set the breakpoint by fully qualified function names. For C++ this means " "namespaces and all arguments, and for Objective-C this means a full function " "prototype with class and selector. Can be repeated multiple times to make " "one breakpoint for multiple names." }, - { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to " + { LLDB_OPT_SET_5, true, "selector", 'S', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSelector, "Set the breakpoint by ObjC selector name. Can be repeated multiple times to " "make one breakpoint for multiple Selectors." }, - { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to " + { LLDB_OPT_SET_6, true, "method", 'M', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeMethod, "Set the breakpoint by C++ method names. Can be repeated multiple times to " "make one breakpoint for multiple methods." }, - { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find " + { LLDB_OPT_SET_7, true, "func-regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by function name, evaluating a regular-expression to find " "the function name(s)." }, - { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be " + { LLDB_OPT_SET_8, true, "basename", 'b', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the breakpoint by function basename (C++ namespaces and arguments will be " "ignored). Can be repeated multiple times to make one breakpoint for multiple " "symbols." }, - { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched " + { LLDB_OPT_SET_9, true, "source-pattern-regexp", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Set the breakpoint by specifying a regular expression which is matched " "against the source text in a source file or files specified with the -f " "option. The -f option can be specified more than once. If no source files " "are specified, uses the current \"default source file\". If you want to " "match against all source files, pass the \"--all-files\" option." }, - { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "All files are searched for source pattern matches." }, - { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without " + { LLDB_OPT_SET_9, false, "all-files", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "All files are searched for source pattern matches." }, + { LLDB_OPT_SET_11, true, "python-class", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "The name of the class that implement a scripted breakpoint." }, + { LLDB_OPT_SET_11, false, "python-class-key", 'k', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The key for a key/value pair passed to the class that implements a scripted breakpoint. Can be specified more than once." }, + { LLDB_OPT_SET_11, false, "python-class-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The value for the previous key in the pair passed to the class that implements a scripted breakpoint. Can be specified more than once." }, + { LLDB_OPT_SET_10, true, "language-exception", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Set the breakpoint on exceptions thrown by the specified language (without " "options, on throw but not catch.)" }, - { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." }, - { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." }, + { LLDB_OPT_SET_10, false, "on-throw", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception throW." }, + { LLDB_OPT_SET_10, false, "on-catch", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set the breakpoint on exception catcH." }, // Don't add this option till it actually does something useful... // { LLDB_OPT_SET_10, false, "exception-typename", 'O', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeTypeName, // "The breakpoint will only stop if an exception Object of this type is thrown. Can be repeated multiple times to stop for multiple object types" }, - { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression " + { LLDB_OPT_EXPR_LANGUAGE, false, "language", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when interpreting the breakpoint's expression " "(note: currently only implemented for setting breakpoints on identifiers). " "If not set the target.language setting is used." }, - { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. " + { LLDB_OPT_SKIP_PROLOGUE, false, "skip-prologue", 'K', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "sKip the prologue if the breakpoint is at the beginning of a function. " "If not set the target.skip-prologue setting is used." }, - { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." }, - { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. " + { LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Adds this to the list of names for this breakpoint." }, + { LLDB_OPT_OFFSET_APPLIES, false, "address-slide", 'R', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "Add the specified offset to whatever address(es) the breakpoint resolves to. " "At present this applies the offset directly as given, and doesn't try to align it to instruction boundaries." }, - { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code " + { LLDB_OPT_MOVE_TO_NEAREST_CODE, false, "move-to-nearest-code", 'm', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Move breakpoints to nearest code. If not set the target.move-to-nearest-code " "setting is used." }, // clang-format on }; @@ -336,7 +335,8 @@ public: eSetTypeFunctionName, eSetTypeFunctionRegexp, eSetTypeSourceRegexp, - eSetTypeException + eSetTypeException, + eSetTypeScripted, } BreakpointSetType; CommandObjectBreakpointSet(CommandInterpreter &interpreter) @@ -434,7 +434,7 @@ public: } break; case 'f': - m_filenames.AppendIfUnique(FileSpec(option_arg, false)); + m_filenames.AppendIfUnique(FileSpec(option_arg)); break; case 'F': @@ -454,7 +454,15 @@ public: case 'H': m_hardware = true; break; - + + case 'k': { + if (m_current_key.empty()) + m_current_key.assign(option_arg); + else + error.SetErrorStringWithFormat("Key: %s missing value.", + m_current_key.c_str()); + + } break; case 'K': { bool success; bool value; @@ -535,13 +543,17 @@ public: case 'p': m_source_text_regexp.assign(option_arg); break; + + case 'P': + m_python_class.assign(option_arg); + break; case 'r': m_func_regexp.assign(option_arg); break; case 's': - m_modules.AppendIfUnique(FileSpec(option_arg, false)); + m_modules.AppendIfUnique(FileSpec(option_arg)); break; case 'S': @@ -549,6 +561,16 @@ public: m_func_name_type_mask |= eFunctionNameTypeSelector; break; + case 'v': { + if (!m_current_key.empty()) { + m_extra_args_sp->AddStringItem(m_current_key, option_arg); + m_current_key.clear(); + } + else + error.SetErrorStringWithFormat("Value \"%s\" missing matching key.", + option_arg.str().c_str()); + } break; + case 'w': { bool success; m_throw_bp = OptionArgParser::ToBoolean(option_arg, true, &success); @@ -593,6 +615,9 @@ public: m_exception_extra_args.Clear(); m_move_to_nearest_code = eLazyBoolCalculate; m_source_regex_func_names.clear(); + m_python_class.clear(); + m_extra_args_sp.reset(new StructuredData::Dictionary()); + m_current_key.clear(); } llvm::ArrayRef GetDefinitions() override { @@ -607,7 +632,7 @@ public: uint32_t m_column; std::vector m_func_names; std::vector m_breakpoint_names; - uint32_t m_func_name_type_mask; + lldb::FunctionNameType m_func_name_type_mask; std::string m_func_regexp; std::string m_source_text_regexp; FileSpecList m_modules; @@ -623,6 +648,9 @@ public: Args m_exception_extra_args; LazyBool m_move_to_nearest_code; std::unordered_set m_source_regex_func_names; + std::string m_python_class; + StructuredData::DictionarySP m_extra_args_sp; + std::string m_current_key; }; protected: @@ -649,7 +677,9 @@ protected: BreakpointSetType break_type = eSetTypeInvalid; - if (m_options.m_line_num != 0) + if (!m_options.m_python_class.empty()) + break_type = eSetTypeScripted; + else if (m_options.m_line_num != 0) break_type = eSetTypeFileAndLine; else if (m_options.m_load_addr != LLDB_INVALID_ADDRESS) break_type = eSetTypeAddress; @@ -696,7 +726,8 @@ protected: bp_sp = target->CreateBreakpoint(&(m_options.m_modules), file, - m_options.m_line_num, + m_options.m_line_num, + m_options.m_column, m_options.m_offset_addr, check_inlines, m_options.m_skip_prologue, @@ -730,7 +761,7 @@ protected: } case eSetTypeFunctionName: // Breakpoint by function name { - uint32_t name_type_mask = m_options.m_func_name_type_mask; + FunctionNameType name_type_mask = m_options.m_func_name_type_mask; if (name_type_mask == 0) name_type_mask = eFunctionNameTypeAuto; @@ -823,6 +854,25 @@ protected: return false; } } break; + case eSetTypeScripted: { + + Status error; + bp_sp = target->CreateScriptedBreakpoint(m_options.m_python_class, + &(m_options.m_modules), + &(m_options.m_filenames), + false, + m_options.m_hardware, + m_options.m_extra_args_sp, + &error); + if (error.Fail()) { + result.AppendErrorWithFormat( + "Error setting extra exception arguments: %s", + error.AsCString()); + target->RemoveBreakpointByID(bp_sp->GetID()); + result.SetStatus(eReturnStatusFailed); + return false; + } + } break; default: break; } @@ -1207,15 +1257,15 @@ protected: //------------------------------------------------------------------------- #pragma mark List::CommandOptions -static OptionDefinition g_breakpoint_list_options[] = { +static constexpr OptionDefinition g_breakpoint_list_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show debugger internal breakpoints" }, - { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)." }, + { LLDB_OPT_SET_ALL, false, "internal", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show debugger internal breakpoints" }, + { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a brief description of the breakpoint (no location info)." }, // FIXME: We need to add an "internal" command, and then add this sort of thing to it. // But I need to see it for now, and don't want to wait. - { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." }, - { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, - { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, + { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a full description of the breakpoint and its locations." }, + { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Explain everything we know about the breakpoint (for debugging debugger bugs)." }, + { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "List Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, // clang-format on }; @@ -1373,10 +1423,10 @@ private: //------------------------------------------------------------------------- #pragma mark Clear::CommandOptions -static OptionDefinition g_breakpoint_clear_options[] = { +static constexpr OptionDefinition g_breakpoint_clear_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." }, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." } + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the breakpoint by source location in this particular file." }, + { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specify the breakpoint by source location at this particular line." } // clang-format on }; @@ -1531,10 +1581,10 @@ private: //------------------------------------------------------------------------- // CommandObjectBreakpointDelete //------------------------------------------------------------------------- -static OptionDefinition g_breakpoint_delete_options[] = { +static constexpr OptionDefinition g_breakpoint_delete_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." }, - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, + { LLDB_OPT_SET_1, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete all breakpoints without querying for confirmation." }, + { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, // clang-format on }; @@ -1688,12 +1738,12 @@ private: // CommandObjectBreakpointName //------------------------------------------------------------------------- -static OptionDefinition g_breakpoint_name_options[] = { +static constexpr OptionDefinition g_breakpoint_name_options[] = { // clang-format off - {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, - {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."}, - {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, - {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A help string describing the purpose of this name."}, + {LLDB_OPT_SET_1, false, "name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Specifies a breakpoint name to use."}, + {LLDB_OPT_SET_2, false, "breakpoint-id", 'B', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointID, "Specify a breakpoint ID to use."}, + {LLDB_OPT_SET_3, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Operate on Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets."}, + {LLDB_OPT_SET_4, false, "help-string", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A help string describing the purpose of this name."}, // clang-format on }; class BreakpointNameOptionGroup : public OptionGroup { @@ -1757,23 +1807,20 @@ public: OptionValueString m_help_string; }; -static OptionDefinition g_breakpoint_access_options[] = { +static constexpr OptionDefinition g_breakpoint_access_options[] = { // clang-format off - {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."}, - {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."}, - {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."}, + {LLDB_OPT_SET_1, false, "allow-list", 'L', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint will show up in break list if not referred to explicitly."}, + {LLDB_OPT_SET_2, false, "allow-disable", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be disabled by name or when all breakpoints are disabled."}, + {LLDB_OPT_SET_3, false, "allow-delete", 'D', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Determines whether the breakpoint can be deleted by name or when all breakpoints are deleted."}, // clang-format on }; -class BreakpointAccessOptionGroup : public OptionGroup -{ +class BreakpointAccessOptionGroup : public OptionGroup { public: - BreakpointAccessOptionGroup() : - OptionGroup() - {} - + BreakpointAccessOptionGroup() : OptionGroup() {} + ~BreakpointAccessOptionGroup() override = default; - + llvm::ArrayRef GetDefinitions() override { return llvm::makeArrayRef(g_breakpoint_access_options); } @@ -2229,10 +2276,10 @@ public: // CommandObjectBreakpointRead //------------------------------------------------------------------------- #pragma mark Read::CommandOptions -static OptionDefinition g_breakpoint_read_options[] = { +static constexpr OptionDefinition g_breakpoint_read_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." }, - {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."}, + {LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." }, + {LLDB_OPT_SET_ALL, false, "breakpoint-name", 'N', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBreakpointName, "Only read in breakpoints with this name."}, // clang-format on }; @@ -2319,7 +2366,8 @@ protected: std::unique_lock lock; target->GetBreakpointList().GetListMutex(lock); - FileSpec input_spec(m_options.m_filename, true); + FileSpec input_spec(m_options.m_filename); + FileSystem::Instance().Resolve(input_spec); BreakpointIDList new_bps; Status error = target->CreateBreakpointsFromFile( input_spec, m_options.m_names, new_bps); @@ -2359,10 +2407,10 @@ private: // CommandObjectBreakpointWrite //------------------------------------------------------------------------- #pragma mark Write::CommandOptions -static OptionDefinition g_breakpoint_write_options[] = { +static constexpr OptionDefinition g_breakpoint_write_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." }, - { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."}, + { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the breakpoints." }, + { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved breakpoints file if it exists."}, // clang-format on }; @@ -2453,8 +2501,10 @@ protected: return false; } } - Status error = target->SerializeBreakpointsToFile( - FileSpec(m_options.m_filename, true), valid_bp_ids, m_options.m_append); + FileSpec file_spec(m_options.m_filename); + FileSystem::Instance().Resolve(file_spec); + Status error = target->SerializeBreakpointsToFile(file_spec, valid_bp_ids, + m_options.m_append); if (!error.Success()) { result.AppendErrorWithFormat("error serializing breakpoints: %s.", error.AsCString()); diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.h index 5e1026a6b7ea..d0026f90e30c 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpoint.h @@ -10,14 +10,10 @@ #ifndef liblldb_CommandObjectBreakpoint_h_ #define liblldb_CommandObjectBreakpoint_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" #include "lldb/Breakpoint/BreakpointName.h" #include "lldb/Core/Address.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp index f2546cbed848..991b174980e1 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "CommandObjectBreakpointCommand.h" #include "CommandObjectBreakpoint.h" #include "lldb/Breakpoint/Breakpoint.h" @@ -18,13 +14,13 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Core/State.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/STLExtras.h" @@ -40,21 +36,24 @@ using namespace lldb_private; // language to lldb and have it pickable here without having to change this // enumeration by hand and rebuild lldb proper. -static OptionEnumValueElement g_script_option_enumeration[4] = { +static constexpr OptionEnumValueElement g_script_option_enumeration[] = { {eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"}, {eScriptLanguagePython, "python", "Commands are in the Python language."}, {eSortOrderByName, "default-script", - "Commands are in the default scripting language."}, - {0, nullptr, nullptr}}; + "Commands are in the default scripting language."} }; -static OptionDefinition g_breakpoint_add_options[] = { +static constexpr OptionEnumValues ScriptOptionEnum() { + return OptionEnumValues(g_script_option_enumeration); +} + +static constexpr OptionDefinition g_breakpoint_add_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Specify whether breakpoint command execution should terminate on error." }, - { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." }, - { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate." }, - { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, + { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, + { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether breakpoint command execution should terminate on error." }, + { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, ScriptOptionEnum(), 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." }, + { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this breakpoint. Be sure to give a module name if appropriate." }, + { LLDB_OPT_SET_ALL, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Sets Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, // clang-format on }; @@ -475,9 +474,9 @@ const char *CommandObjectBreakpointCommandAdd::g_reader_instructions = // CommandObjectBreakpointCommandDelete //------------------------------------------------------------------------- -static OptionDefinition g_breakpoint_delete_options[] = { +static constexpr OptionDefinition g_breakpoint_delete_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, + { LLDB_OPT_SET_1, false, "dummy-breakpoints", 'D', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete commands from Dummy breakpoints - i.e. breakpoints set before a file is provided, which prime new targets." }, // clang-format on }; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.h index 048cc5e07c1b..96d212138282 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBreakpointCommand.h @@ -10,11 +10,7 @@ #ifndef liblldb_CommandObjectBreakpointCommand_h_ #define liblldb_CommandObjectBreakpointCommand_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.cpp index 7ba8ab945eae..dc4b9ef302c0 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.cpp @@ -9,13 +9,9 @@ #include "CommandObjectBugreport.h" -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupOutputFile.h" @@ -72,8 +68,6 @@ protected: const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue(); if (outfile_spec) { - char path[PATH_MAX]; - outfile_spec.GetPath(path, sizeof(path)); uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate | @@ -84,10 +78,13 @@ protected: open_options |= File::eOpenOptionTruncate; StreamFileSP outfile_stream = std::make_shared(); - Status error = outfile_stream->GetFile().Open(path, open_options); + File &file = outfile_stream->GetFile(); + Status error = + FileSystem::Instance().Open(file, outfile_spec, open_options); if (error.Fail()) { + auto path = outfile_spec.GetPath(); result.AppendErrorWithFormat("Failed to open file '%s' for %s: %s\n", - path, append ? "append" : "write", + path.c_str(), append ? "append" : "write", error.AsCString()); result.SetStatus(eReturnStatusFailed); return false; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.h index 281ea2dd203e..1d9aea59925a 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectBugreport.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectBugreport_h_ #define liblldb_CommandObjectBugreport_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectCommands.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectCommands.cpp index 333f72056cbc..01e1c4269bba 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectCommands.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectCommands.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/StringRef.h" -// Project includes #include "CommandObjectCommands.h" #include "CommandObjectHelp.h" #include "lldb/Core/Debugger.h" @@ -38,12 +34,12 @@ using namespace lldb_private; // CommandObjectCommandsSource //------------------------------------------------------------------------- -static OptionDefinition g_history_options[] = { +static constexpr OptionDefinition g_history_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "How many history commands to print." }, - { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)." }, - { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands." }, - { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clears the current command history." }, + { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "How many history commands to print." }, + { LLDB_OPT_SET_1, false, "start-index", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to start printing history commands (or end to mean tail mode)." }, + { LLDB_OPT_SET_1, false, "end-index", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Index at which to stop printing history commands." }, + { LLDB_OPT_SET_2, false, "clear", 'C', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeBoolean, "Clears the current command history." }, // clang-format on }; @@ -197,11 +193,11 @@ protected: // CommandObjectCommandsSource //------------------------------------------------------------------------- -static OptionDefinition g_source_options[] = { +static constexpr OptionDefinition g_source_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on error." }, - { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, stop executing commands on continue." }, - { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true don't echo commands while executing." }, + { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on error." }, + { LLDB_OPT_SET_ALL, false, "stop-on-continue", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, stop executing commands on continue." }, + { LLDB_OPT_SET_ALL, false, "silent-run", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true don't echo commands while executing." }, // clang-format on }; @@ -308,7 +304,8 @@ protected: return false; } - FileSpec cmd_file(command[0].ref, true); + FileSpec cmd_file(command[0].ref); + FileSystem::Instance().Resolve(cmd_file); ExecutionContext *exe_ctx = nullptr; // Just use the default context. // If any options were set, then use them @@ -319,8 +316,15 @@ protected: CommandInterpreterRunOptions options; options.SetStopOnContinue(m_options.m_stop_on_continue.GetCurrentValue()); options.SetStopOnError(m_options.m_stop_on_error.GetCurrentValue()); - options.SetEchoCommands(!m_options.m_silent_run.GetCurrentValue()); - options.SetPrintResults(!m_options.m_silent_run.GetCurrentValue()); + + // Individual silent setting is override for global command echo settings. + if (m_options.m_silent_run.GetCurrentValue()) { + options.SetSilent(true); + } else { + options.SetPrintResults(true); + options.SetEchoCommands(m_interpreter.GetEchoCommands()); + options.SetEchoCommentCommands(m_interpreter.GetEchoCommentCommands()); + } m_interpreter.HandleCommandsFromFile(cmd_file, exe_ctx, options, result); } else { @@ -340,10 +344,10 @@ protected: // CommandObjectCommandsAlias //------------------------------------------------------------------------- -static OptionDefinition g_alias_options[] = { +static constexpr OptionDefinition g_alias_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Help text for this command" }, - { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "Long help text for this command" }, + { LLDB_OPT_SET_ALL, false, "help", 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Help text for this command" }, + { LLDB_OPT_SET_ALL, false, "long-help", 'H', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "Long help text for this command" }, // clang-format on }; @@ -914,10 +918,10 @@ protected: // CommandObjectCommandsAddRegex //------------------------------------------------------------------------- -static OptionDefinition g_regex_options[] = { +static constexpr OptionDefinition g_regex_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The help text to display for this command." }, - { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "A syntax string showing the typical usage syntax." }, + { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The help text to display for this command." }, + { LLDB_OPT_SET_1, false, "syntax", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "A syntax string showing the typical usage syntax." }, // clang-format on }; @@ -1394,9 +1398,9 @@ private: // CommandObjectCommandsScriptImport //------------------------------------------------------------------------- -OptionDefinition g_script_import_options[] = { +static constexpr OptionDefinition g_script_import_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not." }, + { LLDB_OPT_SET_1, false, "allow-reload", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow the script to be loaded even if it was already loaded before. This argument exists for backwards compatibility, but reloading is always allowed, whether you specify it or not." }, // clang-format on }; @@ -1519,22 +1523,24 @@ protected: //------------------------------------------------------------------------- // CommandObjectCommandsScriptAdd //------------------------------------------------------------------------- +static constexpr OptionEnumValueElement g_script_synchro_type[] = { + {eScriptedCommandSynchronicitySynchronous, "synchronous", + "Run synchronous"}, + {eScriptedCommandSynchronicityAsynchronous, "asynchronous", + "Run asynchronous"}, + {eScriptedCommandSynchronicityCurrentValue, "current", + "Do not alter current setting"} }; -static OptionEnumValueElement g_script_synchro_type[] = { - {eScriptedCommandSynchronicitySynchronous, "synchronous", - "Run synchronous"}, - {eScriptedCommandSynchronicityAsynchronous, "asynchronous", - "Run asynchronous"}, - {eScriptedCommandSynchronicityCurrentValue, "current", - "Do not alter current setting"}, - {0, nullptr, nullptr}}; +static constexpr OptionEnumValues ScriptSynchroType() { + return OptionEnumValues(g_script_synchro_type); +} -static OptionDefinition g_script_add_options[] = { +static constexpr OptionDefinition g_script_add_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name." }, - { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name." }, - { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeHelpText, "The help text to display for this command." }, - { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, g_script_synchro_type, 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system." }, + { LLDB_OPT_SET_1, false, "function", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Name of the Python function to bind to this command name." }, + { LLDB_OPT_SET_2, false, "class", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Name of the Python class to bind to this command name." }, + { LLDB_OPT_SET_1, false, "help" , 'h', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeHelpText, "The help text to display for this command." }, + { LLDB_OPT_SET_ALL, false, "synchronicity", 's', OptionParser::eRequiredArgument, nullptr, ScriptSynchroType(), 0, eArgTypeScriptedCommandSynchronicity, "Set the synchronicity of this command's executions with regard to LLDB event system." }, // clang-format on }; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectCommands.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectCommands.h index a5ef777aa982..57ae8f27efec 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectCommands.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectCommands.h @@ -11,10 +11,6 @@ #ifndef liblldb_CommandObjectCommands_h_ #define liblldb_CommandObjectCommands_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/STLUtils.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectDisassemble.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectDisassemble.cpp index 519e5e2dcdb0..f8ee46121851 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectDisassemble.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectDisassemble.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "CommandObjectDisassemble.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Disassembler.h" @@ -35,30 +31,30 @@ using namespace lldb; using namespace lldb_private; -static OptionDefinition g_disassemble_options[] = { +static constexpr OptionDefinition g_disassemble_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "bytes", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show opcode bytes when disassembling." }, - { LLDB_OPT_SET_ALL, false, "context", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNumLines, "Number of context lines of source to show." }, - { LLDB_OPT_SET_ALL, false, "mixed", 'm', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable mixed source and assembly display." }, - { LLDB_OPT_SET_ALL, false, "raw", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print raw disassembly with no symbol information." }, - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use." }, - { LLDB_OPT_SET_ALL, false, "flavor", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. " + { LLDB_OPT_SET_ALL, false, "bytes", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show opcode bytes when disassembling." }, + { LLDB_OPT_SET_ALL, false, "context", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumLines, "Number of context lines of source to show." }, + { LLDB_OPT_SET_ALL, false, "mixed", 'm', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable mixed source and assembly display." }, + { LLDB_OPT_SET_ALL, false, "raw", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print raw disassembly with no symbol information." }, + { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the disassembler plugin you want to use." }, + { LLDB_OPT_SET_ALL, false, "flavor", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeDisassemblyFlavor, "Name of the disassembly flavor you want to use. " "Currently the only valid options are default, and for Intel " "architectures, att and intel." }, - { LLDB_OPT_SET_ALL, false, "arch", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture, "Specify the architecture to use from cross disassembly." }, + { LLDB_OPT_SET_ALL, false, "arch", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, "Specify the architecture to use from cross disassembly." }, { LLDB_OPT_SET_1 | - LLDB_OPT_SET_2, true, "start-address", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Address at which to start disassembling." }, - { LLDB_OPT_SET_1, false, "end-address", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling." }, + LLDB_OPT_SET_2, true, "start-address", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Address at which to start disassembling." }, + { LLDB_OPT_SET_1, false, "end-address", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Address at which to end disassembling." }, { LLDB_OPT_SET_2 | LLDB_OPT_SET_3 | LLDB_OPT_SET_4 | - LLDB_OPT_SET_5, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNumLines, "Number of instructions to display." }, - { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name." }, - { LLDB_OPT_SET_4, false, "frame", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disassemble from the start of the current frame's function." }, - { LLDB_OPT_SET_5, false, "pc", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disassemble around the current pc." }, - { LLDB_OPT_SET_6, false, "line", 'l', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line " + LLDB_OPT_SET_5, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumLines, "Number of instructions to display." }, + { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Disassemble entire contents of the given function name." }, + { LLDB_OPT_SET_4, false, "frame", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble from the start of the current frame's function." }, + { LLDB_OPT_SET_5, false, "pc", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble around the current pc." }, + { LLDB_OPT_SET_6, false, "line", 'l', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Disassemble the current frame's current source line instructions if there is debug line " "table information, else disassemble around the pc." }, - { LLDB_OPT_SET_7, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address." }, + { LLDB_OPT_SET_7, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Disassemble function containing this address." }, // clang-format on }; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectDisassemble.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectDisassemble.h index af15d45eb76b..04c4cc247ee9 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectDisassemble.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectDisassemble.h @@ -65,7 +65,6 @@ public: // "at_pc". This should be set // in SetOptionValue if anything the selects a location is set. lldb::addr_t symbol_containing_addr; - static OptionDefinition g_option_table[]; }; CommandObjectDisassemble(CommandInterpreter &interpreter); diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.cpp index 08959ff8473d..e87d68a53da4 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.cpp @@ -7,13 +7,9 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -// Project includes #include "CommandObjectExpression.h" #include "Plugins/ExpressionParser/Clang/ClangExpressionVariable.h" #include "lldb/Core/Debugger.h" @@ -43,29 +39,32 @@ CommandObjectExpression::CommandOptions::CommandOptions() : OptionGroup() {} CommandObjectExpression::CommandOptions::~CommandOptions() = default; -static OptionEnumValueElement g_description_verbosity_type[] = { +static constexpr OptionEnumValueElement g_description_verbosity_type[] = { {eLanguageRuntimeDescriptionDisplayVerbosityCompact, "compact", "Only show the description string"}, {eLanguageRuntimeDescriptionDisplayVerbosityFull, "full", - "Show the full output, including persistent variable's name and type"}, - {0, nullptr, nullptr}}; + "Show the full output, including persistent variable's name and type"} }; -static OptionDefinition g_expression_options[] = { +static constexpr OptionEnumValues DescriptionVerbosityTypes() { + return OptionEnumValues(g_description_verbosity_type); +} + +static constexpr OptionDefinition g_expression_options[] = { // clang-format off - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. " + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "all-threads", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Should we run all threads if the execution doesn't complete on one thread."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "ignore-breakpoints", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Ignore breakpoint hits while running expressions"}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Timeout value (in microseconds) for running the expression."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "unwind-on-error", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, or raises a signal. " "Note, unlike gdb hitting a breakpoint is controlled by another option (-i)."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction " + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "debug", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "When specified, debug the JIT code by setting a breakpoint on the first instruction " "and forcing breakpoints to not be ignored (-i0) and no unwinding to happen on error (-u0)."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language " + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specifies the Language to use when parsing the expression. If not set the target.language " "setting is used." }, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." }, - {LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, g_description_verbosity_type, 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Interpret the expression as a complete translation unit, without injecting it into the local " + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "apply-fixits", 'X', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "If true, simple fix-it hints will be automatically applied to the expression." }, + {LLDB_OPT_SET_1, false, "description-verbosity", 'v', OptionParser::eOptionalArgument, nullptr, DescriptionVerbosityTypes(), 0, eArgTypeDescriptionVerbosity, "How verbose should the output of this expression be, if the object description is asked for."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "top-level", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Interpret the expression as a complete translation unit, without injecting it into the local " "context. Allows declaration of persistent, top-level entities without a $ prefix."}, - {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by " + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "allow-jit", 'j', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Controls whether the expression can fall back to being JITted if it's not supported by " "the interpreter (defaults to true)."} // clang-format on }; @@ -307,6 +306,72 @@ CommandObjectExpression::~CommandObjectExpression() = default; Options *CommandObjectExpression::GetOptions() { return &m_option_group; } +int CommandObjectExpression::HandleCompletion(CompletionRequest &request) { + EvaluateExpressionOptions options; + options.SetCoerceToId(m_varobj_options.use_objc); + options.SetLanguage(m_command_options.language); + options.SetExecutionPolicy(lldb_private::eExecutionPolicyNever); + options.SetAutoApplyFixIts(false); + options.SetGenerateDebugInfo(false); + + // We need a valid execution context with a frame pointer for this + // completion, so if we don't have one we should try to make a valid + // execution context. + if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr) + m_interpreter.UpdateExecutionContext(nullptr); + + // This didn't work, so let's get out before we start doing things that + // expect a valid frame pointer. + if (m_interpreter.GetExecutionContext().GetFramePtr() == nullptr) + return 0; + + ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); + + Target *target = exe_ctx.GetTargetPtr(); + + if (!target) + target = GetDummyTarget(); + + if (!target) + return 0; + + unsigned cursor_pos = request.GetRawCursorPos(); + llvm::StringRef code = request.GetRawLine(); + + const std::size_t original_code_size = code.size(); + + // Remove the first token which is 'expr' or some alias/abbreviation of that. + code = llvm::getToken(code).second.ltrim(); + OptionsWithRaw args(code); + code = args.GetRawPart(); + + // The position where the expression starts in the command line. + assert(original_code_size >= code.size()); + std::size_t raw_start = original_code_size - code.size(); + + // Check if the cursor is actually in the expression string, and if not, we + // exit. + // FIXME: We should complete the options here. + if (cursor_pos < raw_start) + return 0; + + // Make the cursor_pos again relative to the start of the code string. + assert(cursor_pos >= raw_start); + cursor_pos -= raw_start; + + auto language = exe_ctx.GetFrameRef().GetLanguage(); + + Status error; + lldb::UserExpressionSP expr(target->GetUserExpressionForLanguage( + code, llvm::StringRef(), language, UserExpression::eResultTypeAny, + options, error)); + if (error.Fail()) + return 0; + + expr->Complete(exe_ctx, request, cursor_pos); + return request.GetNumberOfMatches(); +} + static lldb_private::Status CanBeUsedForElementCountPrinting(ValueObject &valobj) { CompilerType type(valobj.GetCompilerType()); @@ -355,8 +420,7 @@ bool CommandObjectExpression::EvaluateExpression(llvm::StringRef expr, if (m_command_options.auto_apply_fixits == eLazyBoolCalculate) auto_apply_fixits = target->GetEnableAutoApplyFixIts(); else - auto_apply_fixits = - m_command_options.auto_apply_fixits == eLazyBoolYes ? true : false; + auto_apply_fixits = m_command_options.auto_apply_fixits == eLazyBoolYes; options.SetAutoApplyFixIts(auto_apply_fixits); diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.h index 710f87140977..2eeca0da0578 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectExpression.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectExpression_h_ #define liblldb_CommandObjectExpression_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/IOHandler.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/OptionGroupBoolean.h" @@ -39,9 +35,6 @@ public: void OptionParsingStarting(ExecutionContext *execution_context) override; - // Options table: Required for subclasses of Options. - - static OptionDefinition g_option_table[]; bool top_level; bool unwind_on_error; bool ignore_breakpoints; @@ -62,6 +55,8 @@ public: Options *GetOptions() override; + int HandleCompletion(CompletionRequest &request) override; + protected: //------------------------------------------------------------------ // IOHandler::Delegate functions diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectFrame.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectFrame.cpp index 64de14f2edbf..f8318a38e28d 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectFrame.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectFrame.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "CommandObjectFrame.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -24,6 +20,7 @@ #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/Host.h" #include "lldb/Host/OptionParser.h" +#include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionGroupFormat.h" @@ -40,6 +37,7 @@ #include "lldb/Symbol/VariableList.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" @@ -61,11 +59,11 @@ using namespace lldb_private; // CommandObjectFrameDiagnose //------------------------------------------------------------------------- -static OptionDefinition g_frame_diag_options[] = { +static constexpr OptionDefinition g_frame_diag_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "register", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegisterName, "A register to diagnose." }, - { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddress, "An address to diagnose." }, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "An optional offset. Requires --register." } + { LLDB_OPT_SET_1, false, "register", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegisterName, "A register to diagnose." }, + { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddress, "An address to diagnose." }, + { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "An optional offset. Requires --register." } // clang-format on }; @@ -251,7 +249,7 @@ protected: static OptionDefinition g_frame_select_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "A relative frame index offset from the current frame index." }, + { LLDB_OPT_SET_1, false, "relative", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "A relative frame index offset from the current frame index." }, // clang-format on }; @@ -427,7 +425,17 @@ public: "arguments and local variables in scope. Names of argument, " "local, file static and file global variables can be specified. " "Children of aggregate variables can be specified such as " - "'var->child.x'.", + "'var->child.x'. The -> and [] operators in 'frame variable' do " + "not invoke operator overloads if they exist, but directly access " + "the specified element. If you want to trigger operator overloads " + "use the expression command to print the variable instead." + "\nIt is worth noting that except for overloaded " + "operators, when printing local variables 'expr local_var' and " + "'frame var local_var' produce the same " + "results. However, 'frame variable' is more efficient, since it " + "uses debug information and memory reads directly, rather than " + "parsing and evaluating an expression, which may even involve " + "JITing and running code in the target program.", nullptr, eCommandRequiresFrame | eCommandTryTargetAPILock | eCommandProcessMustBeLaunched | eCommandProcessMustBePaused | eCommandRequiresProcess), @@ -705,6 +713,23 @@ protected: result.SetStatus(eReturnStatusSuccessFinishResult); } + if (m_option_variable.show_recognized_args) { + auto recognized_frame = frame->GetRecognizedFrame(); + if (recognized_frame) { + ValueObjectListSP recognized_arg_list = + recognized_frame->GetRecognizedArguments(); + if (recognized_arg_list) { + for (auto &rec_value_sp : recognized_arg_list->GetObjects()) { + options.SetFormat(m_option_format.GetFormat()); + options.SetVariableFormatDisplayLanguage( + rec_value_sp->GetPreferredDisplayLanguage()); + options.SetRootValueObjectName(rec_value_sp->GetName().AsCString()); + rec_value_sp->Dump(result.GetOutputStream(), options); + } + } + } + } + if (m_interpreter.TruncationWarningNecessary()) { result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), m_cmd_name.c_str()); @@ -728,6 +753,370 @@ protected: OptionGroupValueObjectDisplay m_varobj_options; }; +#pragma mark CommandObjectFrameRecognizer + +static OptionDefinition g_frame_recognizer_add_options[] = { + // clang-format off + { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Name of the module or shared library that this recognizer applies to." }, + { LLDB_OPT_SET_ALL, false, "function", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeName, "Name of the function that this recognizer applies to." }, + { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Give the name of a Python class to use for this frame recognizer." }, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Function name and module name are actually regular expressions." } + // clang-format on +}; + +class CommandObjectFrameRecognizerAdd : public CommandObjectParsed { +private: + class CommandOptions : public Options { + public: + CommandOptions() : Options() {} + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'l': + m_class_name = std::string(option_arg); + break; + case 's': + m_module = std::string(option_arg); + break; + case 'n': + m_function = std::string(option_arg); + break; + case 'x': + m_regex = true; + break; + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", + short_option); + break; + } + + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_module = ""; + m_function = ""; + m_class_name = ""; + m_regex = false; + } + + llvm::ArrayRef GetDefinitions() override { + return llvm::makeArrayRef(g_frame_recognizer_add_options); + } + + // Instance variables to hold the values for command options. + std::string m_class_name; + std::string m_module; + std::string m_function; + bool m_regex; + }; + + CommandOptions m_options; + + Options *GetOptions() override { return &m_options; } + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override; + +public: + CommandObjectFrameRecognizerAdd(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "frame recognizer add", + "Add a new frame recognizer.", nullptr), + m_options() { + SetHelpLong(R"( +Frame recognizers allow for retrieving information about special frames based on +ABI, arguments or other special properties of that frame, even without source +code or debug info. Currently, one use case is to extract function arguments +that would otherwise be unaccesible, or augment existing arguments. + +Adding a custom frame recognizer is possible by implementing a Python class +and using the 'frame recognizer add' command. The Python class should have a +'get_recognized_arguments' method and it will receive an argument of type +lldb.SBFrame representing the current frame that we are trying to recognize. +The method should return a (possibly empty) list of lldb.SBValue objects that +represent the recognized arguments. + +An example of a recognizer that retrieves the file descriptor values from libc +functions 'read', 'write' and 'close' follows: + + class LibcFdRecognizer(object): + def get_recognized_arguments(self, frame): + if frame.name in ["read", "write", "close"]: + fd = frame.EvaluateExpression("$arg1").unsigned + value = lldb.target.CreateValueFromExpression("fd", "(int)%d" % fd) + return [value] + return [] + +The file containing this implementation can be imported via 'command script +import' and then we can register this recognizer with 'frame recognizer add'. +It's important to restrict the recognizer to the libc library (which is +libsystem_kernel.dylib on macOS) to avoid matching functions with the same name +in other modules: + +(lldb) command script import .../fd_recognizer.py +(lldb) frame recognizer add -l fd_recognizer.LibcFdRecognizer -n read -s libsystem_kernel.dylib + +When the program is stopped at the beginning of the 'read' function in libc, we +can view the recognizer arguments in 'frame variable': + +(lldb) b read +(lldb) r +Process 1234 stopped +* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.3 + frame #0: 0x00007fff06013ca0 libsystem_kernel.dylib`read +(lldb) frame variable +(int) fd = 3 + + )"); + } + ~CommandObjectFrameRecognizerAdd() override = default; +}; + +bool CommandObjectFrameRecognizerAdd::DoExecute(Args &command, + CommandReturnObject &result) { +#ifndef LLDB_DISABLE_PYTHON + if (m_options.m_class_name.empty()) { + result.AppendErrorWithFormat( + "%s needs a Python class name (-l argument).\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (m_options.m_module.empty()) { + result.AppendErrorWithFormat("%s needs a module name (-s argument).\n", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (m_options.m_function.empty()) { + result.AppendErrorWithFormat("%s needs a function name (-n argument).\n", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + ScriptInterpreter *interpreter = m_interpreter.GetScriptInterpreter(); + + if (interpreter && + !interpreter->CheckObjectExists(m_options.m_class_name.c_str())) { + result.AppendWarning( + "The provided class does not exist - please define it " + "before attempting to use this frame recognizer"); + } + + StackFrameRecognizerSP recognizer_sp = + StackFrameRecognizerSP(new ScriptedStackFrameRecognizer( + interpreter, m_options.m_class_name.c_str())); + if (m_options.m_regex) { + auto module = + RegularExpressionSP(new RegularExpression(m_options.m_module)); + auto func = + RegularExpressionSP(new RegularExpression(m_options.m_function)); + StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func); + } else { + auto module = ConstString(m_options.m_module); + auto func = ConstString(m_options.m_function); + StackFrameRecognizerManager::AddRecognizer(recognizer_sp, module, func); + } +#endif + + result.SetStatus(eReturnStatusSuccessFinishNoResult); + return result.Succeeded(); +} + +class CommandObjectFrameRecognizerClear : public CommandObjectParsed { +public: + CommandObjectFrameRecognizerClear(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "frame recognizer clear", + "Delete all frame recognizers.", nullptr) {} + + ~CommandObjectFrameRecognizerClear() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + StackFrameRecognizerManager::RemoveAllRecognizers(); + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + +class CommandObjectFrameRecognizerDelete : public CommandObjectParsed { + public: + CommandObjectFrameRecognizerDelete(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "frame recognizer delete", + "Delete an existing frame recognizer.", nullptr) {} + + ~CommandObjectFrameRecognizerDelete() override = default; + + protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (command.GetArgumentCount() == 0) { + if (!m_interpreter.Confirm( + "About to delete all frame recognizers, do you want to do that?", + true)) { + result.AppendMessage("Operation cancelled..."); + result.SetStatus(eReturnStatusFailed); + return false; + } + + StackFrameRecognizerManager::RemoveAllRecognizers(); + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } + + if (command.GetArgumentCount() != 1) { + result.AppendErrorWithFormat("'%s' takes zero or one arguments.\n", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + uint32_t recognizer_id = + StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); + + StackFrameRecognizerManager::RemoveRecognizerWithID(recognizer_id); + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + +class CommandObjectFrameRecognizerList : public CommandObjectParsed { + public: + CommandObjectFrameRecognizerList(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "frame recognizer list", + "Show a list of active frame recognizers.", + nullptr) {} + + ~CommandObjectFrameRecognizerList() override = default; + + protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + bool any_printed = false; + StackFrameRecognizerManager::ForEach( + [&result, &any_printed](uint32_t recognizer_id, std::string name, + std::string function, std::string symbol, + bool regexp) { + if (name == "") name = "(internal)"; + result.GetOutputStream().Printf( + "%d: %s, module %s, function %s%s\n", recognizer_id, name.c_str(), + function.c_str(), symbol.c_str(), regexp ? " (regexp)" : ""); + any_printed = true; + }); + + if (any_printed) + result.SetStatus(eReturnStatusSuccessFinishResult); + else { + result.GetOutputStream().PutCString("no matching results found.\n"); + result.SetStatus(eReturnStatusSuccessFinishNoResult); + } + return result.Succeeded(); + } +}; + +class CommandObjectFrameRecognizerInfo : public CommandObjectParsed { + public: + CommandObjectFrameRecognizerInfo(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "frame recognizer info", + "Show which frame recognizer is applied a stack frame (if any).", + nullptr) { + CommandArgumentEntry arg; + CommandArgumentData index_arg; + + // Define the first (and only) variant of this arg. + index_arg.arg_type = eArgTypeFrameIndex; + index_arg.arg_repetition = eArgRepeatPlain; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg.push_back(index_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg); + } + + ~CommandObjectFrameRecognizerInfo() override = default; + + protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + Process *process = m_exe_ctx.GetProcessPtr(); + if (process == nullptr) { + result.AppendError("no process"); + result.SetStatus(eReturnStatusFailed); + return false; + } + Thread *thread = m_exe_ctx.GetThreadPtr(); + if (thread == nullptr) { + result.AppendError("no thread"); + result.SetStatus(eReturnStatusFailed); + return false; + } + if (command.GetArgumentCount() != 1) { + result.AppendErrorWithFormat( + "'%s' takes exactly one frame index argument.\n", m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + uint32_t frame_index = + StringConvert::ToUInt32(command.GetArgumentAtIndex(0), 0, 0); + StackFrameSP frame_sp = thread->GetStackFrameAtIndex(frame_index); + if (!frame_sp) { + result.AppendErrorWithFormat("no frame with index %u", frame_index); + result.SetStatus(eReturnStatusFailed); + return false; + } + + auto recognizer = + StackFrameRecognizerManager::GetRecognizerForFrame(frame_sp); + + Stream &output_stream = result.GetOutputStream(); + output_stream.Printf("frame %d ", frame_index); + if (recognizer) { + output_stream << "is recognized by "; + output_stream << recognizer->GetName(); + } else { + output_stream << "not recognized by any recognizer"; + } + output_stream.EOL(); + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + +class CommandObjectFrameRecognizer : public CommandObjectMultiword { + public: + CommandObjectFrameRecognizer(CommandInterpreter &interpreter) + : CommandObjectMultiword( + interpreter, "frame recognizer", + "Commands for editing and viewing frame recognizers.", + "frame recognizer [] ") { + LoadSubCommand( + "add", + CommandObjectSP(new CommandObjectFrameRecognizerAdd(interpreter))); + LoadSubCommand( + "clear", + CommandObjectSP(new CommandObjectFrameRecognizerClear(interpreter))); + LoadSubCommand( + "delete", + CommandObjectSP(new CommandObjectFrameRecognizerDelete(interpreter))); + LoadSubCommand( + "list", + CommandObjectSP(new CommandObjectFrameRecognizerList(interpreter))); + LoadSubCommand( + "info", + CommandObjectSP(new CommandObjectFrameRecognizerInfo(interpreter))); + } + + ~CommandObjectFrameRecognizer() override = default; +}; + #pragma mark CommandObjectMultiwordFrame //------------------------------------------------------------------------- @@ -748,6 +1137,11 @@ CommandObjectMultiwordFrame::CommandObjectMultiwordFrame( CommandObjectSP(new CommandObjectFrameSelect(interpreter))); LoadSubCommand("variable", CommandObjectSP(new CommandObjectFrameVariable(interpreter))); +#ifndef LLDB_DISABLE_PYTHON + LoadSubCommand( + "recognizer", + CommandObjectSP(new CommandObjectFrameRecognizer(interpreter))); +#endif } CommandObjectMultiwordFrame::~CommandObjectMultiwordFrame() = default; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectGUI.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectGUI.cpp index d65e12e30982..ed834dcbe4fb 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectGUI.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectGUI.cpp @@ -9,10 +9,6 @@ #include "CommandObjectGUI.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectGUI.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectGUI.h index c71558fa1758..b20c3a7191ab 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectGUI.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectGUI.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectGUI_h_ #define liblldb_CommandObjectGUI_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectHelp.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectHelp.cpp index 903c6011b03f..1f1d63d72903 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectHelp.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectHelp.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "CommandObjectHelp.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandObjectMultiword.h" @@ -71,11 +67,11 @@ CommandObjectHelp::CommandObjectHelp(CommandInterpreter &interpreter) CommandObjectHelp::~CommandObjectHelp() = default; -static OptionDefinition g_help_options[] = { +static constexpr OptionDefinition g_help_options[] = { // clang-format off - {LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Hide aliases in the command list."}, - {LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Hide user-defined commands from the list."}, - {LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include commands prefixed with an underscore."}, + {LLDB_OPT_SET_ALL, false, "hide-aliases", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Hide aliases in the command list."}, + {LLDB_OPT_SET_ALL, false, "hide-user-commands", 'u', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Hide user-defined commands from the list."}, + {LLDB_OPT_SET_ALL, false, "show-hidden-commands", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Include commands prefixed with an underscore."}, // clang-format on }; @@ -171,10 +167,13 @@ bool CommandObjectHelp::DoExecute(Args &command, CommandReturnObject &result) { } sub_cmd_obj->GenerateHelpText(result); - - if (m_interpreter.AliasExists(command_name)) { + std::string alias_full_name; + // Don't use AliasExists here, that only checks exact name matches. If + // the user typed a shorter unique alias name, we should still tell them + // it was an alias. + if (m_interpreter.GetAliasFullName(command_name, alias_full_name)) { StreamString sstr; - m_interpreter.GetAlias(command_name)->GetAliasExpansion(sstr); + m_interpreter.GetAlias(alias_full_name)->GetAliasExpansion(sstr); result.GetOutputStream().Printf("\n'%s' is an abbreviation for %s\n", command[0].c_str(), sstr.GetData()); } diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectHelp.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectHelp.h index c78682dead1f..5d5b672a5fbd 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectHelp.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectHelp.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectHelp_h_ #define liblldb_CommandObjectHelp_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectLanguage.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectLanguage.h index b796c511b513..ef8e11863e7e 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectLanguage.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectLanguage.h @@ -10,11 +10,7 @@ #ifndef liblldb_CommandObjectLanguage_h_ #define liblldb_CommandObjectLanguage_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectLog.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectLog.cpp index 1389ff2bde02..b019336bdc92 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectLog.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectLog.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "CommandObjectLog.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -36,18 +32,18 @@ using namespace lldb; using namespace lldb_private; -static OptionDefinition g_log_options[] = { +static constexpr OptionDefinition g_log_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Set the destination file to log to." }, - { LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, - { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose logging." }, - { LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, - { LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, - { LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." }, - { LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." }, - { LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, - { LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Append to the log file instead of overwriting." }, - { LLDB_OPT_SET_1, false, "file-function",'F',OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Prepend the names of files and function that generate the logs." }, + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Set the destination file to log to." }, + { LLDB_OPT_SET_1, false, "threadsafe", 't', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable thread safe logging to avoid interweaved log lines." }, + { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose logging." }, + { LLDB_OPT_SET_1, false, "sequence", 's', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with an increasing integer sequence id." }, + { LLDB_OPT_SET_1, false, "timestamp", 'T', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with a timestamp." }, + { LLDB_OPT_SET_1, false, "pid-tid", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with the process and thread ID that generates the log line." }, + { LLDB_OPT_SET_1, false, "thread-name",'n', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend all log lines with the thread name for the thread that generates the log line." }, + { LLDB_OPT_SET_1, false, "stack", 'S', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append a stack backtrace to each log line." }, + { LLDB_OPT_SET_1, false, "append", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to the log file instead of overwriting." }, + { LLDB_OPT_SET_1, false, "file-function",'F',OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Prepend the names of files and function that generate the logs." }, // clang-format on }; @@ -101,7 +97,8 @@ public: switch (short_option) { case 'f': - log_file.SetFile(option_arg, true, FileSpec::Style::native); + log_file.SetFile(option_arg, FileSpec::Style::native); + FileSystem::Instance().Resolve(log_file); break; case 't': log_options |= LLDB_LOG_OPTION_THREADSAFE; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectLog.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectLog.h index 1e24a4b2ac67..f02a7be514ac 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectLog.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectLog.h @@ -10,13 +10,9 @@ #ifndef liblldb_CommandObjectLog_h_ #define liblldb_CommandObjectLog_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectMemory.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectMemory.cpp index e4a49e55857d..b1edb1afa5d2 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectMemory.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectMemory.cpp @@ -7,14 +7,10 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes -// Other libraries and framework includes #include "clang/AST/Decl.h" -// Project includes #include "CommandObjectMemory.h" #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" #include "lldb/Core/Debugger.h" @@ -50,16 +46,16 @@ using namespace lldb; using namespace lldb_private; -static OptionDefinition g_read_memory_options[] = { +static constexpr OptionDefinition g_read_memory_options[] = { // clang-format off - {LLDB_OPT_SET_1, false, "num-per-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNumberPerLine, "The number of items per line to display." }, - {LLDB_OPT_SET_2, false, "binary", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that " + {LLDB_OPT_SET_1, false, "num-per-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumberPerLine, "The number of items per line to display." }, + {LLDB_OPT_SET_2, false, "binary", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that " "uses the format, size, count and number per line settings." }, - {LLDB_OPT_SET_3, true , "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, "The name of a type to view memory as." }, - {LLDB_OPT_SET_3, false, "offset", 'E', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many elements of the specified type to skip before starting to display data." }, + {LLDB_OPT_SET_3, true , "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "The name of a type to view memory as." }, + {LLDB_OPT_SET_3, false, "offset", 'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many elements of the specified type to skip before starting to display data." }, {LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | - LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Necessary if reading over target.max-memory-read-size bytes." }, + LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Necessary if reading over target.max-memory-read-size bytes." }, // clang-format on }; @@ -386,7 +382,6 @@ protected: if (view_as_type_cstr && view_as_type_cstr[0]) { // We are viewing memory as a type - SymbolContext sc; const bool exact_match = false; TypeList type_list; uint32_t reference_count = 0; @@ -471,17 +466,13 @@ protected: llvm::DenseSet searched_symbol_files; ConstString lookup_type_name(type_str.c_str()); StackFrame *frame = m_exe_ctx.GetFramePtr(); + ModuleSP search_first; if (frame) { - sc = frame->GetSymbolContext(eSymbolContextModule); - if (sc.module_sp) { - sc.module_sp->FindTypes(sc, lookup_type_name, exact_match, 1, - searched_symbol_files, type_list); - } - } - if (type_list.GetSize() == 0) { - target->GetImages().FindTypes(sc, lookup_type_name, exact_match, 1, - searched_symbol_files, type_list); + search_first = frame->GetSymbolContext(eSymbolContextModule).module_sp; } + target->GetImages().FindTypes(search_first.get(), lookup_type_name, + exact_match, 1, searched_symbol_files, + type_list); if (type_list.GetSize() == 0 && lookup_type_name.GetCString() && *lookup_type_name.GetCString() == '$') { @@ -528,15 +519,15 @@ protected: --pointer_count; } - m_format_options.GetByteSizeValue() = clang_ast_type.GetByteSize(nullptr); - - if (m_format_options.GetByteSizeValue() == 0) { + llvm::Optional size = clang_ast_type.GetByteSize(nullptr); + if (!size) { result.AppendErrorWithFormat( "unable to get the byte size of the type '%s'\n", view_as_type_cstr); result.SetStatus(eReturnStatusFailed); return false; } + m_format_options.GetByteSizeValue() = *size; if (!m_format_options.GetCountValue().OptionWasSet()) m_format_options.GetCountValue() = 1; @@ -651,12 +642,15 @@ protected: if (!m_format_options.GetFormatValue().OptionWasSet()) m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault); - bytes_read = clang_ast_type.GetByteSize(nullptr) * - m_format_options.GetCountValue().GetCurrentValue(); + llvm::Optional size = clang_ast_type.GetByteSize(nullptr); + if (!size) { + result.AppendError("can't get size of type"); + return false; + } + bytes_read = *size * m_format_options.GetCountValue().GetCurrentValue(); if (argc > 0) - addr = addr + (clang_ast_type.GetByteSize(nullptr) * - m_memory_options.m_offset.GetCurrentValue()); + addr = addr + (*size * m_memory_options.m_offset.GetCurrentValue()); } else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString) { data_sp.reset(new DataBufferHeap(total_byte_size, '\0')); @@ -762,9 +756,9 @@ protected: Stream *output_stream = nullptr; const FileSpec &outfile_spec = m_outfile_options.GetFile().GetCurrentValue(); + + std::string path = outfile_spec.GetPath(); if (outfile_spec) { - char path[PATH_MAX]; - outfile_spec.GetPath(path, sizeof(path)); uint32_t open_options = File::eOpenOptionWrite | File::eOpenOptionCanCreate; @@ -772,19 +766,21 @@ protected: if (append) open_options |= File::eOpenOptionAppend; - if (outfile_stream.GetFile().Open(path, open_options).Success()) { + Status error = FileSystem::Instance().Open(outfile_stream.GetFile(), + outfile_spec, open_options); + if (error.Success()) { if (m_memory_options.m_output_as_binary) { const size_t bytes_written = outfile_stream.Write(data_sp->GetBytes(), bytes_read); if (bytes_written > 0) { result.GetOutputStream().Printf( "%zi bytes %s to '%s'\n", bytes_written, - append ? "appended" : "written", path); + append ? "appended" : "written", path.c_str()); return true; } else { result.AppendErrorWithFormat("Failed to write %" PRIu64 " bytes to '%s'.\n", - (uint64_t)bytes_read, path); + (uint64_t)bytes_read, path.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -794,8 +790,8 @@ protected: output_stream = &outfile_stream; } } else { - result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", path, - append ? "append" : "write"); + result.AppendErrorWithFormat("Failed to open file '%s' for %s.\n", + path.c_str(), append ? "append" : "write"); result.SetStatus(eReturnStatusFailed); return false; } @@ -884,12 +880,12 @@ protected: CompilerType m_prev_clang_ast_type; }; -OptionDefinition g_memory_find_option_table[] = { +static constexpr OptionDefinition g_memory_find_option_table[] = { // clang-format off - {LLDB_OPT_SET_1, true, "expression", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."}, - {LLDB_OPT_SET_2, true, "string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Use text to find a byte pattern."}, - {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many times to perform the search."}, - {LLDB_OPT_SET_ALL, false, "dump-offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."}, + {LLDB_OPT_SET_1, true, "expression", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "Evaluate an expression to obtain a byte pattern."}, + {LLDB_OPT_SET_2, true, "string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Use text to find a byte pattern."}, + {LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many times to perform the search."}, + {LLDB_OPT_SET_ALL, false, "dump-offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When dumping memory for a match, an offset from the match location to start dumping from."}, // clang-format on }; @@ -1068,7 +1064,11 @@ protected: m_memory_options.m_expr.GetStringValue(), frame, result_sp)) && result_sp) { uint64_t value = result_sp->GetValueAsUnsigned(0); - switch (result_sp->GetCompilerType().GetByteSize(nullptr)) { + llvm::Optional size = + result_sp->GetCompilerType().GetByteSize(nullptr); + if (!size) + return false; + switch (*size) { case 1: { uint8_t byte = (uint8_t)value; buffer.CopyData(&byte, 1); @@ -1179,10 +1179,10 @@ protected: OptionGroupFindMemory m_memory_options; }; -OptionDefinition g_memory_write_option_table[] = { +static constexpr OptionDefinition g_memory_write_option_table[] = { // clang-format off - {LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Write memory using the contents of a file."}, - {LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."}, + {LLDB_OPT_SET_1, true, "infile", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Write memory using the contents of a file."}, + {LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "Start writing bytes from an offset within the input file."}, // clang-format on }; @@ -1209,8 +1209,9 @@ public: switch (short_option) { case 'i': - m_infile.SetFile(option_value, true, FileSpec::Style::native); - if (!m_infile.Exists()) { + m_infile.SetFile(option_value, FileSpec::Style::native); + FileSystem::Instance().Resolve(m_infile); + if (!FileSystem::Instance().Exists(m_infile)) { m_infile.Clear(); error.SetErrorStringWithFormat("input file does not exist: '%s'", option_value.str().c_str()); @@ -1358,7 +1359,7 @@ protected: size_t length = SIZE_MAX; if (item_byte_size > 1) length = item_byte_size; - auto data_sp = DataBufferLLVM::CreateSliceFromPath( + auto data_sp = FileSystem::Instance().CreateDataBuffer( m_memory_options.m_infile.GetPath(), length, m_memory_options.m_infile_offset); if (data_sp) { @@ -1724,6 +1725,7 @@ protected: error = process_sp->GetMemoryRegionInfo(load_addr, range_info); if (error.Success()) { lldb_private::Address addr; + ConstString name = range_info.GetName(); ConstString section_name; if (process_sp->GetTarget().ResolveLoadAddress(load_addr, addr)) { SectionSP section_sp(addr.GetSection()); @@ -1735,13 +1737,14 @@ protected: } } result.AppendMessageWithFormat( - "[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") %c%c%c%s%s\n", + "[0x%16.16" PRIx64 "-0x%16.16" PRIx64 ") %c%c%c%s%s%s%s\n", range_info.GetRange().GetRangeBase(), range_info.GetRange().GetRangeEnd(), range_info.GetReadable() ? 'r' : '-', range_info.GetWritable() ? 'w' : '-', - range_info.GetExecutable() ? 'x' : '-', section_name ? " " : "", - section_name ? section_name.AsCString() : ""); + range_info.GetExecutable() ? 'x' : '-', + name ? " " : "", name.AsCString(""), + section_name ? " " : "", section_name.AsCString("")); m_prev_end_addr = range_info.GetRange().GetRangeEnd(); result.SetStatus(eReturnStatusSuccessFinishResult); } else { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectMemory.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectMemory.h index 9f3978baf76a..0fa5251e82ff 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectMemory.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectMemory.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectMemory_h_ #define liblldb_CommandObjectMemory_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectMultiword.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectMultiword.cpp index 19fcf60e557c..64c4f6686e6b 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectMultiword.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectMultiword.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Core/Debugger.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -193,9 +189,10 @@ int CommandObjectMultiword::HandleCompletion(CompletionRequest &request) { auto arg0 = request.GetParsedLine()[0].ref; if (request.GetCursorIndex() == 0) { - StringList new_matches; - AddNamesMatchingPartialString(m_subcommand_dict, arg0, new_matches); - request.AddCompletions(new_matches); + StringList new_matches, descriptions; + AddNamesMatchingPartialString(m_subcommand_dict, arg0, new_matches, + &descriptions); + request.AddCompletions(new_matches, descriptions); if (new_matches.GetSize() == 1 && new_matches.GetStringAtIndex(0) != nullptr && diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp index 22a9a169c7c8..fc442f5f4d5d 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.cpp @@ -7,11 +7,7 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "CommandObjectPlatform.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -63,19 +59,19 @@ static mode_t ParsePermissionString(llvm::StringRef permissions) { return user | group | world; } -static OptionDefinition g_permissions_options[] = { +static constexpr OptionDefinition g_permissions_options[] = { // clang-format off - {LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePermissionsNumber, "Give out the numeric value for permissions (e.g. 757)"}, - {LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePermissionsString, "Give out the string value for permissions (e.g. rwxr-xr--)."}, - {LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow user to read."}, - {LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow user to write."}, - {LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow user to execute."}, - {LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow group to read."}, - {LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow group to write."}, - {LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow group to execute."}, - {LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow world to read."}, - {LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow world to write."}, - {LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allow world to execute."}, + {LLDB_OPT_SET_ALL, false, "permissions-value", 'v', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePermissionsNumber, "Give out the numeric value for permissions (e.g. 757)"}, + {LLDB_OPT_SET_ALL, false, "permissions-string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePermissionsString, "Give out the string value for permissions (e.g. rwxr-xr--)."}, + {LLDB_OPT_SET_ALL, false, "user-read", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to read."}, + {LLDB_OPT_SET_ALL, false, "user-write", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to write."}, + {LLDB_OPT_SET_ALL, false, "user-exec", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow user to execute."}, + {LLDB_OPT_SET_ALL, false, "group-read", 'R', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to read."}, + {LLDB_OPT_SET_ALL, false, "group-write", 'W', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to write."}, + {LLDB_OPT_SET_ALL, false, "group-exec", 'X', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow group to execute."}, + {LLDB_OPT_SET_ALL, false, "world-read", 'd', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to read."}, + {LLDB_OPT_SET_ALL, false, "world-write", 't', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to write."}, + {LLDB_OPT_SET_ALL, false, "world-exec", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allow world to execute."}, // clang-format on }; @@ -491,8 +487,7 @@ public: else mode = lldb::eFilePermissionsUserRWX | lldb::eFilePermissionsGroupRWX | lldb::eFilePermissionsWorldRX; - Status error = - platform_sp->MakeDirectory(FileSpec{cmd_line, false}, mode); + Status error = platform_sp->MakeDirectory(FileSpec(cmd_line), mode); if (error.Success()) { result.SetStatus(eReturnStatusSuccessFinishResult); } else { @@ -545,7 +540,7 @@ public: perms = lldb::eFilePermissionsUserRW | lldb::eFilePermissionsGroupRW | lldb::eFilePermissionsWorldRead; lldb::user_id_t fd = platform_sp->OpenFile( - FileSpec(cmd_line, false), + FileSpec(cmd_line), File::eOpenOptionRead | File::eOpenOptionWrite | File::eOpenOptionAppend | File::eOpenOptionCanCreate, perms, error); @@ -614,10 +609,10 @@ public: // "platform fread" //---------------------------------------------------------------------- -static OptionDefinition g_platform_fread_options[] = { +static constexpr OptionDefinition g_platform_fread_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex, "Offset into the file at which to start reading." }, - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Number of bytes to read from the file." }, + { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Offset into the file at which to start reading." }, + { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Number of bytes to read from the file." }, // clang-format on }; @@ -709,10 +704,10 @@ protected: // "platform fwrite" //---------------------------------------------------------------------- -static OptionDefinition g_platform_fwrite_options[] = { +static constexpr OptionDefinition g_platform_fwrite_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex, "Offset into the file at which to start reading." }, - { LLDB_OPT_SET_1, false, "data", 'd', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeValue, "Text to write to the file." }, + { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Offset into the file at which to start reading." }, + { LLDB_OPT_SET_1, false, "data", 'd', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeValue, "Text to write to the file." }, // clang-format on }; @@ -883,8 +878,8 @@ public: if (platform_sp) { const char *remote_file_path = args.GetArgumentAtIndex(0); const char *local_file_path = args.GetArgumentAtIndex(1); - Status error = platform_sp->GetFile(FileSpec(remote_file_path, false), - FileSpec(local_file_path, false)); + Status error = platform_sp->GetFile(FileSpec(remote_file_path), + FileSpec(local_file_path)); if (error.Success()) { result.AppendMessageWithFormat( "successfully get-file from %s (remote) to %s (host)\n", @@ -949,8 +944,7 @@ public: m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); if (platform_sp) { std::string remote_file_path(args.GetArgumentAtIndex(0)); - user_id_t size = - platform_sp->GetFileSize(FileSpec(remote_file_path, false)); + user_id_t size = platform_sp->GetFileSize(FileSpec(remote_file_path)); if (size != UINT64_MAX) { result.AppendMessageWithFormat("File size of %s (remote): %" PRIu64 "\n", @@ -987,8 +981,9 @@ public: const char *src = args.GetArgumentAtIndex(0); const char *dst = args.GetArgumentAtIndex(1); - FileSpec src_fs(src, true); - FileSpec dst_fs(dst ? dst : src_fs.GetFilename().GetCString(), false); + FileSpec src_fs(src); + FileSystem::Instance().Resolve(src_fs); + FileSpec dst_fs(dst ? dst : src_fs.GetFilename().GetCString()); PlatformSP platform_sp( m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform()); @@ -1043,7 +1038,7 @@ protected: Module *exe_module = target->GetExecutableModulePointer(); if (exe_module) { m_options.launch_info.GetExecutableFile() = exe_module->GetFileSpec(); - llvm::SmallString exe_path; + llvm::SmallString<128> exe_path; m_options.launch_info.GetExecutableFile().GetPath(exe_path); if (!exe_path.empty()) m_options.launch_info.GetArguments().AppendArgument(exe_path); @@ -1102,22 +1097,22 @@ protected: // "platform process list" //---------------------------------------------------------------------- -OptionDefinition g_platform_process_list_options[] = { +static OptionDefinition g_platform_process_list_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "List the process info for a specific process ID." }, - { LLDB_OPT_SET_2, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "Find processes with executable basenames that match a string." }, - { LLDB_OPT_SET_3, true, "ends-with", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "Find processes with executable basenames that end with a string." }, - { LLDB_OPT_SET_4, true, "starts-with", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "Find processes with executable basenames that start with a string." }, - { LLDB_OPT_SET_5, true, "contains", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "Find processes with executable basenames that contain a string." }, - { LLDB_OPT_SET_6, true, "regex", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "parent", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "Find processes that have a matching parent process ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "uid", 'u', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Find processes that have a matching user ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "euid", 'U', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective user ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "gid", 'g', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Find processes that have a matching group ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "egid", 'G', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective group ID." }, - { LLDB_OPT_SET_FROM_TO(2, 6), false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeArchitecture, "Find processes that have a matching architecture." }, - { LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show process arguments instead of the process executable basename." }, - { LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose output." }, + { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "List the process info for a specific process ID." }, + { LLDB_OPT_SET_2, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that match a string." }, + { LLDB_OPT_SET_3, true, "ends-with", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that end with a string." }, + { LLDB_OPT_SET_4, true, "starts-with", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that start with a string." }, + { LLDB_OPT_SET_5, true, "contains", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "Find processes with executable basenames that contain a string." }, + { LLDB_OPT_SET_6, true, "regex", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "Find processes with executable basenames that match a regular expression." }, + { LLDB_OPT_SET_FROM_TO(2, 6), false, "parent", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "Find processes that have a matching parent process ID." }, + { LLDB_OPT_SET_FROM_TO(2, 6), false, "uid", 'u', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching user ID." }, + { LLDB_OPT_SET_FROM_TO(2, 6), false, "euid", 'U', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective user ID." }, + { LLDB_OPT_SET_FROM_TO(2, 6), false, "gid", 'g', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching group ID." }, + { LLDB_OPT_SET_FROM_TO(2, 6), false, "egid", 'G', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Find processes that have a matching effective group ID." }, + { LLDB_OPT_SET_FROM_TO(2, 6), false, "arch", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeArchitecture, "Find processes that have a matching architecture." }, + { LLDB_OPT_SET_FROM_TO(1, 6), false, "show-args", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show process arguments instead of the process executable basename." }, + { LLDB_OPT_SET_FROM_TO(1, 6), false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose output." }, // clang-format on }; @@ -1336,31 +1331,31 @@ protected: case 'n': match_info.GetProcessInfo().GetExecutableFile().SetFile( - option_arg, false, FileSpec::Style::native); + option_arg, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::Equals); break; case 'e': match_info.GetProcessInfo().GetExecutableFile().SetFile( - option_arg, false, FileSpec::Style::native); + option_arg, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::EndsWith); break; case 's': match_info.GetProcessInfo().GetExecutableFile().SetFile( - option_arg, false, FileSpec::Style::native); + option_arg, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::StartsWith); break; case 'c': match_info.GetProcessInfo().GetExecutableFile().SetFile( - option_arg, false, FileSpec::Style::native); + option_arg, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::Contains); break; case 'r': match_info.GetProcessInfo().GetExecutableFile().SetFile( - option_arg, false, FileSpec::Style::native); + option_arg, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::RegularExpression); break; @@ -1488,12 +1483,12 @@ protected: } }; -static OptionDefinition g_platform_process_attach_options[] = { +static constexpr OptionDefinition g_platform_process_attach_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to." }, - { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with to launch." }, + { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, + { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "The process ID of an existing process to attach to." }, + { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "The name of the process to attach to." }, + { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Wait for the process with to launch." }, // clang-format on }; @@ -1529,7 +1524,7 @@ public: break; case 'n': - attach_info.GetExecutableFile().SetFile(option_arg, false, + attach_info.GetExecutableFile().SetFile(option_arg, FileSpec::Style::native); break; @@ -1576,7 +1571,7 @@ public: ProcessInstanceInfoMatch match_info; if (partial_name) { match_info.GetProcessInfo().GetExecutableFile().SetFile( - partial_name, false, FileSpec::Style::native); + partial_name, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::StartsWith); } platform_sp->FindProcesses(match_info, process_infos); @@ -1673,9 +1668,9 @@ private: //---------------------------------------------------------------------- // "platform shell" //---------------------------------------------------------------------- -static OptionDefinition g_platform_shell_options[] = { +static constexpr OptionDefinition g_platform_shell_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command." }, + { LLDB_OPT_SET_ALL, false, "timeout", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeValue, "Seconds to wait for the remote host to finish running the command." }, // clang-format on }; @@ -1816,9 +1811,10 @@ public: return false; } // TODO: move the bulk of this code over to the platform itself - FileSpec src(args.GetArgumentAtIndex(0), true); - FileSpec dst(args.GetArgumentAtIndex(1), false); - if (!src.Exists()) { + FileSpec src(args.GetArgumentAtIndex(0)); + FileSystem::Instance().Resolve(src); + FileSpec dst(args.GetArgumentAtIndex(1)); + if (!FileSystem::Instance().Exists(src)) { result.AppendError("source location does not exist or is not accessible"); result.SetStatus(eReturnStatusFailed); return false; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.h index 03b8ca00c81d..e15df5a0441f 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlatform.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectPlatform_h_ #define liblldb_CommandObjectPlatform_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlugin.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlugin.cpp index 13ef6b227c5b..2e805bab9d6f 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlugin.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlugin.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "CommandObjectPlugin.h" #include "lldb/Host/Host.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -63,7 +59,8 @@ protected: Status error; - FileSpec dylib_fspec(command[0].ref, true); + FileSpec dylib_fspec(command[0].ref); + FileSystem::Instance().Resolve(dylib_fspec); if (m_interpreter.GetDebugger().LoadPlugin(dylib_fspec, error)) result.SetStatus(eReturnStatusSuccessFinishResult); diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlugin.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlugin.h index d67aa43365d5..cd39eb19b49d 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlugin.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectPlugin.h @@ -10,11 +10,7 @@ #ifndef liblldb_CommandObjectPlugin_h_ #define liblldb_CommandObjectPlugin_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp index eb5a19aa4d39..5b0e6d784a02 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.cpp @@ -7,17 +7,12 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "CommandObjectProcess.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/OptionParser.h" #include "lldb/Host/StringConvert.h" @@ -32,6 +27,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; @@ -304,14 +300,14 @@ protected: // CommandObjectProcessAttach //------------------------------------------------------------------------- -static OptionDefinition g_process_attach_options[] = { +static constexpr OptionDefinition g_process_attach_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "continue", 'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Immediately continue the process once attached." }, - { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, - { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePid, "The process ID of an existing process to attach to." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeProcessName, "The name of the process to attach to." }, - { LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Include existing processes when doing attach -w." }, - { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Wait for the process with to launch." }, + { LLDB_OPT_SET_ALL, false, "continue", 'c', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Immediately continue the process once attached." }, + { LLDB_OPT_SET_ALL, false, "plugin", 'P', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, + { LLDB_OPT_SET_1, false, "pid", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePid, "The process ID of an existing process to attach to." }, + { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeProcessName, "The name of the process to attach to." }, + { LLDB_OPT_SET_2, false, "include-existing", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Include existing processes when doing attach -w." }, + { LLDB_OPT_SET_2, false, "waitfor", 'w', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Wait for the process with to launch." }, // clang-format on }; @@ -352,7 +348,7 @@ public: break; case 'n': - attach_info.GetExecutableFile().SetFile(option_arg, false, + attach_info.GetExecutableFile().SetFile(option_arg, FileSpec::Style::native); break; @@ -403,7 +399,7 @@ public: ProcessInstanceInfoMatch match_info; if (partial_name) { match_info.GetProcessInfo().GetExecutableFile().SetFile( - partial_name, false, FileSpec::Style::native); + partial_name, FileSpec::Style::native); match_info.SetNameMatchType(NameMatch::StartsWith); } platform_sp->FindProcesses(match_info, process_infos); @@ -459,7 +455,7 @@ protected: Status error; error = m_interpreter.GetDebugger().GetTargetList().CreateTarget( - m_interpreter.GetDebugger(), "", "", false, + m_interpreter.GetDebugger(), "", "", eLoadDependentsNo, nullptr, // No platform options new_target_sp); target = new_target_sp.get(); @@ -556,9 +552,9 @@ protected: // CommandObjectProcessContinue //------------------------------------------------------------------------- -static OptionDefinition g_process_continue_options[] = { +static constexpr OptionDefinition g_process_continue_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeUnsignedInteger, "Ignore crossings of the breakpoint (if it exists) for the currently selected thread." } + { LLDB_OPT_SET_ALL, false, "ignore-count",'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeUnsignedInteger, "Ignore crossings of the breakpoint (if it exists) for the currently selected thread." } // clang-format on }; @@ -719,9 +715,9 @@ protected: //------------------------------------------------------------------------- // CommandObjectProcessDetach //------------------------------------------------------------------------- -static OptionDefinition g_process_detach_options[] = { +static constexpr OptionDefinition g_process_detach_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." }, + { LLDB_OPT_SET_1, false, "keep-stopped", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the process should be kept stopped on detach (if possible)." }, // clang-format on }; @@ -818,9 +814,9 @@ protected: // CommandObjectProcessConnect //------------------------------------------------------------------------- -static OptionDefinition g_process_connect_options[] = { +static constexpr OptionDefinition g_process_connect_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, + { LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use." }, // clang-format on }; @@ -947,9 +943,9 @@ public: // CommandObjectProcessLoad //------------------------------------------------------------------------- -static OptionDefinition g_process_load_options[] = { +static constexpr OptionDefinition g_process_load_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory." }, + { LLDB_OPT_SET_ALL, false, "install", 'i', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypePath, "Install the shared library to the target. If specified without an argument then the library will installed in the current working directory." }, // clang-format on }; @@ -975,7 +971,7 @@ public: case 'i': do_install = true; if (!option_arg.empty()) - install_path.SetFile(option_arg, false, FileSpec::Style::native); + install_path.SetFile(option_arg, FileSpec::Style::native); break; default: error.SetErrorStringWithFormat("invalid short option character '%c'", @@ -1023,18 +1019,20 @@ protected: uint32_t image_token = LLDB_INVALID_IMAGE_TOKEN; if (!m_options.do_install) { - FileSpec image_spec(image_path, false); + FileSpec image_spec(image_path); platform->ResolveRemotePath(image_spec, image_spec); image_token = platform->LoadImage(process, FileSpec(), image_spec, error); } else if (m_options.install_path) { - FileSpec image_spec(image_path, true); + FileSpec image_spec(image_path); + FileSystem::Instance().Resolve(image_spec); platform->ResolveRemotePath(m_options.install_path, m_options.install_path); image_token = platform->LoadImage(process, image_spec, m_options.install_path, error); } else { - FileSpec image_spec(image_path, true); + FileSpec image_spec(image_path); + FileSystem::Instance().Resolve(image_spec); image_token = platform->LoadImage(process, image_spec, FileSpec(), error); } @@ -1281,7 +1279,7 @@ protected: ProcessSP process_sp = m_exe_ctx.GetProcessSP(); if (process_sp) { if (command.GetArgumentCount() == 1) { - FileSpec output_file(command.GetArgumentAtIndex(0), false); + FileSpec output_file(command.GetArgumentAtIndex(0)); Status error = PluginManager::SaveCore(process_sp, output_file); if (error.Success()) { result.SetStatus(eReturnStatusSuccessFinishResult); @@ -1343,11 +1341,11 @@ public: // CommandObjectProcessHandle //------------------------------------------------------------------------- -static OptionDefinition g_process_handle_options[] = { +static constexpr OptionDefinition g_process_handle_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." }, - { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." }, - { LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." } + { LLDB_OPT_SET_1, false, "stop", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the process should be stopped if the signal is received." }, + { LLDB_OPT_SET_1, false, "notify", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the debugger should notify the user if the signal is received." }, + { LLDB_OPT_SET_1, false, "pass", 'p', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Whether or not the signal should be passed to the process." } // clang-format on }; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.h index 0f520f63e1dd..7325dce49683 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectProcess.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectProcess_h_ #define liblldb_CommandObjectProcess_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectQuit.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectQuit.cpp index 37ed12be358f..2c5b20bf5846 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectQuit.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectQuit.cpp @@ -9,10 +9,6 @@ #include "CommandObjectQuit.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Target/Process.h" @@ -35,7 +31,7 @@ CommandObjectQuit::~CommandObjectQuit() {} // if all alive processes will be detached when you quit and false if at least // one process will be killed instead bool CommandObjectQuit::ShouldAskForConfirmation(bool &is_a_detach) { - if (m_interpreter.GetPromptOnQuit() == false) + if (!m_interpreter.GetPromptOnQuit()) return false; bool should_prompt = false; is_a_detach = true; @@ -55,7 +51,7 @@ bool CommandObjectQuit::ShouldAskForConfirmation(bool &is_a_detach) { if (process_sp && process_sp->IsValid() && process_sp->IsAlive() && process_sp->WarnBeforeDetach()) { should_prompt = true; - if (process_sp->GetShouldDetach() == false) { + if (!process_sp->GetShouldDetach()) { // if we need to kill at least one process, just say so and return is_a_detach = false; return should_prompt; @@ -86,13 +82,6 @@ bool CommandObjectQuit::DoExecute(Args &command, CommandReturnObject &result) { return false; } - if (command.GetArgumentCount() > 1) { - result.AppendError("Too many arguments for 'quit'. Only an optional exit " - "code is allowed"); - result.SetStatus(eReturnStatusFailed); - return false; - } - // We parse the exit code argument if there is one. if (command.GetArgumentCount() == 1) { llvm::StringRef arg = command.GetArgumentAtIndex(0); diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectQuit.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectQuit.h index f2998f8690fb..0f9da62278d9 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectQuit.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectQuit.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectQuit_h_ #define liblldb_CommandObjectQuit_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.cpp index 4dadc5d68d20..ae8b5d0027c7 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.cpp @@ -10,8 +10,6 @@ #include "CommandObjectRegister.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/DumpRegisterValue.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -27,6 +25,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Errno.h" using namespace lldb; @@ -36,11 +36,11 @@ using namespace lldb_private; // "register read" //---------------------------------------------------------------------- -static OptionDefinition g_register_read_options[] = { +static constexpr OptionDefinition g_register_read_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display register names using the alternate register name if there is one." }, - { LLDB_OPT_SET_1, false, "set", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeIndex, "Specify which register sets to dump by index." }, - { LLDB_OPT_SET_2, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show all register sets." }, + { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display register names using the alternate register name if there is one." }, + { LLDB_OPT_SET_1, false, "set", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeIndex, "Specify which register sets to dump by index." }, + { LLDB_OPT_SET_2, false, "all", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show all register sets." }, // clang-format on }; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.h index 81f2f6bae223..96fc47af0a21 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectRegister.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectRegister_h_ #define liblldb_CommandObjectRegister_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectReproducer.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectReproducer.cpp new file mode 100644 index 000000000000..f393f17d9aec --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectReproducer.cpp @@ -0,0 +1,97 @@ +//===-- CommandObjectReproducer.cpp -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CommandObjectReproducer.h" + +#include "lldb/Utility/Reproducer.h" + +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupBoolean.h" + +using namespace lldb; +using namespace lldb_private; + +class CommandObjectReproducerGenerate : public CommandObjectParsed { +public: + CommandObjectReproducerGenerate(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "reproducer generate", + "Generate reproducer on disk.", nullptr) {} + + ~CommandObjectReproducerGenerate() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (!command.empty()) { + result.AppendErrorWithFormat("'%s' takes no arguments", + m_cmd_name.c_str()); + return false; + } + + auto &r = repro::Reproducer::Instance(); + if (auto generator = r.GetGenerator()) { + generator->Keep(); + } else { + result.AppendErrorWithFormat("Unable to get the reproducer generator"); + return false; + } + + result.GetOutputStream() + << "Reproducer written to '" << r.GetReproducerPath() << "'\n"; + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + +class CommandObjectReproducerStatus : public CommandObjectParsed { +public: + CommandObjectReproducerStatus(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "reproducer status", + "Show the current reproducer status.", nullptr) {} + + ~CommandObjectReproducerStatus() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + if (!command.empty()) { + result.AppendErrorWithFormat("'%s' takes no arguments", + m_cmd_name.c_str()); + return false; + } + + auto &r = repro::Reproducer::Instance(); + if (auto generator = r.GetGenerator()) { + result.GetOutputStream() << "Reproducer is in capture mode.\n"; + } else if (auto generator = r.GetLoader()) { + result.GetOutputStream() << "Reproducer is in replay mode.\n"; + } else { + + result.GetOutputStream() << "Reproducer is off.\n"; + } + + result.SetStatus(eReturnStatusSuccessFinishResult); + return result.Succeeded(); + } +}; + +CommandObjectReproducer::CommandObjectReproducer( + CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "reproducer", + "Commands controlling LLDB reproducers.", + "log []") { + LoadSubCommand( + "generate", + CommandObjectSP(new CommandObjectReproducerGenerate(interpreter))); + LoadSubCommand("status", CommandObjectSP( + new CommandObjectReproducerStatus(interpreter))); +} + +CommandObjectReproducer::~CommandObjectReproducer() = default; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectReproducer.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectReproducer.h new file mode 100644 index 000000000000..6691e8a8e626 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectReproducer.h @@ -0,0 +1,31 @@ +//===-- CommandObjectReproducer.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_CommandObjectReproducer_h_ +#define liblldb_CommandObjectReproducer_h_ + +#include "lldb/Interpreter/CommandObjectMultiword.h" +#include "lldb/Interpreter/Options.h" + +namespace lldb_private { + +//------------------------------------------------------------------------- +// CommandObjectReproducer +//------------------------------------------------------------------------- + +class CommandObjectReproducer : public CommandObjectMultiword { +public: + CommandObjectReproducer(CommandInterpreter &interpreter); + + ~CommandObjectReproducer() override; +}; + +} // namespace lldb_private + +#endif // liblldb_CommandObjectReproducer_h_ diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectSettings.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectSettings.cpp index 3db1e35cd702..967a009189e4 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectSettings.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectSettings.cpp @@ -9,12 +9,8 @@ #include "CommandObjectSettings.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/StringRef.h" -// Project includes #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -28,9 +24,10 @@ using namespace lldb_private; // CommandObjectSettingsSet //------------------------------------------------------------------------- -static OptionDefinition g_settings_set_options[] = { +static constexpr OptionDefinition g_settings_set_options[] = { // clang-format off - { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Apply the new value to the global default value." } + { LLDB_OPT_SET_2, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Apply the new value to the global default value." }, + { LLDB_OPT_SET_2, false, "force", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Force an empty value to be accepted as the default." } // clang-format on }; @@ -108,6 +105,9 @@ insert-before or insert-after."); const int short_option = m_getopt_table[option_idx].val; switch (short_option) { + case 'f': + m_force = true; + break; case 'g': m_global = true; break; @@ -122,6 +122,7 @@ insert-before or insert-after."); void OptionParsingStarting(ExecutionContext *execution_context) override { m_global = false; + m_force = false; } llvm::ArrayRef GetDefinitions() override { @@ -129,8 +130,8 @@ insert-before or insert-after."); } // Instance variables to hold the values for command options. - bool m_global; + bool m_force; }; int HandleArgumentCompletion( @@ -184,8 +185,10 @@ protected: if (!ParseOptions(cmd_args, result)) return false; + const size_t min_argc = m_options.m_force ? 1 : 2; const size_t argc = cmd_args.GetArgumentCount(); - if ((argc < 2) && (!m_options.m_global)) { + + if ((argc < min_argc) && (!m_options.m_global)) { result.AppendError("'settings set' takes more arguments"); result.SetStatus(eReturnStatusFailed); return false; @@ -199,6 +202,19 @@ protected: return false; } + // A missing value corresponds to clearing the setting when "force" is + // specified. + if (argc == 1 && m_options.m_force) { + Status error(m_interpreter.GetDebugger().SetPropertyValue( + &m_exe_ctx, eVarSetOperationClear, var_name, llvm::StringRef())); + if (error.Fail()) { + result.AppendError(error.AsCString()); + result.SetStatus(eReturnStatusFailed); + return false; + } + return result.Succeeded(); + } + // Split the raw command into var_name and value pair. llvm::StringRef raw_str(command); std::string var_value_string = raw_str.split(var_name).second.str(); @@ -300,6 +316,210 @@ protected: } }; +//------------------------------------------------------------------------- +// CommandObjectSettingsWrite -- Write settings to file +//------------------------------------------------------------------------- + +static constexpr OptionDefinition g_settings_write_options[] = { + // clang-format off + { LLDB_OPT_SET_ALL, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file into which to write the settings." }, + { LLDB_OPT_SET_ALL, false, "append",'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to saved settings file if it exists."}, + // clang-format on +}; + +class CommandObjectSettingsWrite : public CommandObjectParsed { +public: + CommandObjectSettingsWrite(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "settings export", + "Write matching debugger settings and their " + "current values to a file that can be read in with " + "\"settings read\". Defaults to writing all settings.", + nullptr), + m_options() { + CommandArgumentEntry arg1; + CommandArgumentData var_name_arg; + + // Define the first (and only) variant of this arg. + var_name_arg.arg_type = eArgTypeSettingVariableName; + var_name_arg.arg_repetition = eArgRepeatOptional; + + // There is only one variant this argument could be; put it into the + // argument entry. + arg1.push_back(var_name_arg); + + // Push the data for the first argument into the m_arguments vector. + m_arguments.push_back(arg1); + } + + ~CommandObjectSettingsWrite() override = default; + + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() : Options() {} + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'f': + m_filename.assign(option_arg); + break; + case 'a': + m_append = true; + break; + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", + short_option); + break; + } + + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_filename.clear(); + m_append = false; + } + + llvm::ArrayRef GetDefinitions() override { + return llvm::makeArrayRef(g_settings_write_options); + } + + // Instance variables to hold the values for command options. + std::string m_filename; + bool m_append = false; + }; + +protected: + bool DoExecute(Args &args, CommandReturnObject &result) override { + FileSpec file_spec(m_options.m_filename); + FileSystem::Instance().Resolve(file_spec); + std::string path(file_spec.GetPath()); + uint32_t options = File::OpenOptions::eOpenOptionWrite | + File::OpenOptions::eOpenOptionCanCreate; + if (m_options.m_append) + options |= File::OpenOptions::eOpenOptionAppend; + else + options |= File::OpenOptions::eOpenOptionTruncate; + + StreamFile out_file(path.c_str(), options, + lldb::eFilePermissionsFileDefault); + + if (!out_file.GetFile().IsValid()) { + result.AppendErrorWithFormat("%s: unable to write to file", path.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + + // Exporting should not be context sensitive. + ExecutionContext clean_ctx; + + if (args.empty()) { + m_interpreter.GetDebugger().DumpAllPropertyValues( + &clean_ctx, out_file, OptionValue::eDumpGroupExport); + return result.Succeeded(); + } + + for (const auto &arg : args) { + Status error(m_interpreter.GetDebugger().DumpPropertyValue( + &clean_ctx, out_file, arg.ref, OptionValue::eDumpGroupExport)); + if (!error.Success()) { + result.AppendError(error.AsCString()); + result.SetStatus(eReturnStatusFailed); + } + } + + return result.Succeeded(); + } + +private: + CommandOptions m_options; +}; + +//------------------------------------------------------------------------- +// CommandObjectSettingsRead -- Read settings from file +//------------------------------------------------------------------------- + +static constexpr OptionDefinition g_settings_read_options[] = { + // clang-format off + {LLDB_OPT_SET_ALL, true, "file",'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eDiskFileCompletion, eArgTypeFilename, "The file from which to read the breakpoints." }, + // clang-format on +}; + +class CommandObjectSettingsRead : public CommandObjectParsed { +public: + CommandObjectSettingsRead(CommandInterpreter &interpreter) + : CommandObjectParsed( + interpreter, "settings read", + "Read settings previously saved to a file with \"settings write\".", + nullptr), + m_options() {} + + ~CommandObjectSettingsRead() override = default; + + Options *GetOptions() override { return &m_options; } + + class CommandOptions : public Options { + public: + CommandOptions() : Options() {} + + ~CommandOptions() override = default; + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, + ExecutionContext *execution_context) override { + Status error; + const int short_option = m_getopt_table[option_idx].val; + + switch (short_option) { + case 'f': + m_filename.assign(option_arg); + break; + default: + error.SetErrorStringWithFormat("unrecognized option '%c'", + short_option); + break; + } + + return error; + } + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_filename.clear(); + } + + llvm::ArrayRef GetDefinitions() override { + return llvm::makeArrayRef(g_settings_read_options); + } + + // Instance variables to hold the values for command options. + std::string m_filename; + }; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + FileSpec file(m_options.m_filename); + FileSystem::Instance().Resolve(file); + ExecutionContext clean_ctx; + CommandInterpreterRunOptions options; + options.SetAddToHistory(false); + options.SetEchoCommands(false); + options.SetPrintResults(true); + options.SetStopOnError(false); + m_interpreter.HandleCommandsFromFile(file, &clean_ctx, options, result); + return result.Succeeded(); + } + +private: + CommandOptions m_options; +}; + //------------------------------------------------------------------------- // CommandObjectSettingsList -- List settable variables //------------------------------------------------------------------------- @@ -987,6 +1207,10 @@ CommandObjectMultiwordSettings::CommandObjectMultiwordSettings( CommandObjectSP(new CommandObjectSettingsAppend(interpreter))); LoadSubCommand("clear", CommandObjectSP(new CommandObjectSettingsClear(interpreter))); + LoadSubCommand("write", + CommandObjectSP(new CommandObjectSettingsWrite(interpreter))); + LoadSubCommand("read", + CommandObjectSP(new CommandObjectSettingsRead(interpreter))); } CommandObjectMultiwordSettings::~CommandObjectMultiwordSettings() = default; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectSettings.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectSettings.h index 3376cccd1799..df1338600456 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectSettings.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectSettings.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectSettings_h_ #define liblldb_CommandObjectSettings_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectSource.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectSource.cpp index 19e2e441c241..2fce34f9846e 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectSource.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectSource.cpp @@ -9,10 +9,6 @@ #include "CommandObjectSource.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/FileLineResolver.h" #include "lldb/Core/Module.h" @@ -41,15 +37,15 @@ using namespace lldb_private; // CommandObjectSourceInfo - debug line entries dumping command //---------------------------------------------------------------------- -static OptionDefinition g_source_info_options[] = { +static constexpr OptionDefinition g_source_info_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "The number of line entries to display." }, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source in the given module or shared library (can be specified more than once)." }, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." }, - { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "The line number at which to start the displaying lines." }, - { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "The line number at which to stop displaying lines." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." }, - { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, + { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of line entries to display." }, + { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source in the given module or shared library (can be specified more than once)." }, + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." }, + { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the displaying lines." }, + { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to stop displaying lines." }, + { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." }, + { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, // clang-format on }; @@ -517,7 +513,7 @@ protected: // Dump the line entries found in the file specified in the option. bool DumpLinesForFile(CommandReturnObject &result) { - FileSpec file_spec(m_options.file_name, false); + FileSpec file_spec(m_options.file_name); const char *filename = m_options.file_name.c_str(); Target *target = m_exe_ctx.GetTargetPtr(); const ModuleList &module_list = @@ -596,7 +592,7 @@ protected: m_module_list.Clear(); if (!m_options.modules.empty()) { for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) { - FileSpec module_file_spec(m_options.modules[i], false); + FileSpec module_file_spec(m_options.modules[i]); if (module_file_spec) { ModuleSpec module_spec(module_file_spec); if (target->GetImages().FindModules(module_spec, m_module_list) == 0) @@ -653,16 +649,16 @@ protected: // CommandObjectSourceList //------------------------------------------------------------------------- -static OptionDefinition g_source_list_options[] = { +static constexpr OptionDefinition g_source_list_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "The number of source lines to display." }, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library." }, - { LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints." }, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." }, - { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "The line number at which to start the display source." }, - { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." }, - { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, - { LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source." }, + { LLDB_OPT_SET_ALL, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "The number of source lines to display." }, + { LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Look up the source file in the given shared library." }, + { LLDB_OPT_SET_ALL, false, "show-breakpoints", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show the line table locations from the debug information that indicate valid places to set source level breakpoints." }, + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "The file from which to display source." }, + { LLDB_OPT_SET_1, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "The line number at which to start the display source." }, + { LLDB_OPT_SET_2, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeSymbol, "The name of a function whose source to display." }, + { LLDB_OPT_SET_3, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup the address and display the source information for the corresponding file and line." }, + { LLDB_OPT_SET_4, false, "reverse", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Reverse the listing to look backwards from the last displayed block of source." }, // clang-format on }; @@ -921,7 +917,7 @@ protected: if (num_modules > 0) { ModuleList matching_modules; for (size_t i = 0; i < num_modules; ++i) { - FileSpec module_file_spec(m_options.modules[i], false); + FileSpec module_file_spec(m_options.modules[i]); if (module_file_spec) { ModuleSpec module_spec(module_file_spec); matching_modules.Clear(); @@ -946,7 +942,7 @@ protected: if (num_modules > 0) { ModuleList matching_modules; for (size_t i = 0; i < num_modules; ++i) { - FileSpec module_file_spec(m_options.modules[i], false); + FileSpec module_file_spec(m_options.modules[i]); if (module_file_spec) { ModuleSpec module_spec(module_file_spec); matching_modules.Clear(); @@ -1203,14 +1199,16 @@ protected: if (!m_options.modules.empty()) { ModuleList matching_modules; for (size_t i = 0, e = m_options.modules.size(); i < e; ++i) { - FileSpec module_file_spec(m_options.modules[i], false); + FileSpec module_file_spec(m_options.modules[i]); if (module_file_spec) { ModuleSpec module_spec(module_file_spec); matching_modules.Clear(); target->GetImages().FindModules(module_spec, matching_modules); num_matches += matching_modules.ResolveSymbolContextForFilePath( filename, 0, check_inlines, - eSymbolContextModule | eSymbolContextCompUnit, sc_list); + SymbolContextItem(eSymbolContextModule | + eSymbolContextCompUnit), + sc_list); } } } else { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectSource.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectSource.h index e81ac1961d26..b2553832210d 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectSource.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectSource.h @@ -11,10 +11,6 @@ #ifndef liblldb_CommandObjectSource_h_ #define liblldb_CommandObjectSource_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/STLUtils.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectTarget.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectTarget.cpp index 8be43cbf9bb0..ee55b22c5ea2 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectTarget.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectTarget.cpp @@ -9,13 +9,11 @@ #include "CommandObjectTarget.h" -// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/OptionParser.h" @@ -51,13 +49,12 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Timer.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FormatAdapters.h" -// C Includes -// C++ Includes #include using namespace lldb; @@ -138,6 +135,71 @@ static uint32_t DumpTargetList(TargetList &target_list, return num_targets; } +// Note that the negation in the argument name causes a slightly confusing +// mapping of the enum values, +static constexpr OptionEnumValueElement g_dependents_enumaration[] = { + {eLoadDependentsDefault, "default", + "Only load dependents when the target is an executable."}, + {eLoadDependentsNo, "true", + "Don't load dependents, even if the target is an executable."}, + {eLoadDependentsYes, "false", + "Load dependents, even if the target is not an executable."}}; + +static constexpr OptionDefinition g_dependents_options[] = { + {LLDB_OPT_SET_1, false, "no-dependents", 'd', + OptionParser::eOptionalArgument, nullptr, + OptionEnumValues(g_dependents_enumaration), 0, eArgTypeValue, + "Whether or not to load dependents when creating a target. If the option " + "is not specified, the value is implicitly 'default'. If the option is " + "specified but without a value, the value is implicitly 'true'."}}; + +class OptionGroupDependents : public OptionGroup { +public: + OptionGroupDependents() {} + + ~OptionGroupDependents() override {} + + llvm::ArrayRef GetDefinitions() override { + return llvm::makeArrayRef(g_dependents_options); + } + + Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value, + ExecutionContext *execution_context) override { + Status error; + + // For compatibility no value means don't load dependents. + if (option_value.empty()) { + m_load_dependent_files = eLoadDependentsNo; + return error; + } + + const char short_option = g_dependents_options[option_idx].short_option; + if (short_option == 'd') { + LoadDependentFiles tmp_load_dependents; + tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum( + option_value, g_dependents_options[option_idx].enum_values, 0, error); + if (error.Success()) + m_load_dependent_files = tmp_load_dependents; + } else { + error.SetErrorStringWithFormat("unrecognized short option '%c'", + short_option); + } + + return error; + } + + Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete; + + void OptionParsingStarting(ExecutionContext *execution_context) override { + m_load_dependent_files = eLoadDependentsDefault; + } + + LoadDependentFiles m_load_dependent_files; + +private: + DISALLOW_COPY_AND_ASSIGN(OptionGroupDependents); +}; + #pragma mark CommandObjectTargetCreate //------------------------------------------------------------------------- @@ -158,16 +220,14 @@ public: eArgTypePath, "Path to the remote file to use for this target."), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0, - eArgTypeFilename, "Fullpath to a stand alone debug " - "symbols file for when debug symbols " - "are not in the executable."), + eArgTypeFilename, + "Fullpath to a stand alone debug " + "symbols file for when debug symbols " + "are not in the executable."), m_remote_file( LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename, "Fullpath to the file on the remote host if debugging remotely."), - m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd', - "Don't load dependent files when creating the target, " - "just add the specified executable.", - true, true) { + m_add_dependents() { CommandArgumentEntry arg; CommandArgumentData file_arg; @@ -211,13 +271,13 @@ protected: FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue()); if (core_file) { - if (!core_file.Exists()) { + if (!FileSystem::Instance().Exists(core_file)) { result.AppendErrorWithFormat("core file '%s' doesn't exist", core_file.GetPath().c_str()); result.SetStatus(eReturnStatusFailed); return false; } - if (!core_file.Readable()) { + if (!FileSystem::Instance().Readable(core_file)) { result.AppendErrorWithFormat("core file '%s' is not readable", core_file.GetPath().c_str()); result.SetStatus(eReturnStatusFailed); @@ -228,8 +288,8 @@ protected: if (argc == 1 || core_file || remote_file) { FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue()); if (symfile) { - if (symfile.Exists()) { - if (!symfile.Readable()) { + if (FileSystem::Instance().Exists(symfile)) { + if (!FileSystem::Instance().Readable(symfile)) { result.AppendErrorWithFormat("symbol file '%s' is not readable", symfile.GetPath().c_str()); result.SetStatus(eReturnStatusFailed); @@ -250,8 +310,10 @@ protected: Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path); FileSpec file_spec; - if (file_path) - file_spec.SetFile(file_path, true, FileSpec::Style::native); + if (file_path) { + file_spec.SetFile(file_path, FileSpec::Style::native); + FileSystem::Instance().Resolve(file_spec); + } bool must_set_platform_path = false; @@ -259,11 +321,9 @@ protected: TargetSP target_sp; llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName(); - const bool get_dependent_files = - m_add_dependents.GetOptionValue().GetCurrentValue(); Status error(debugger.GetTargetList().CreateTarget( - debugger, file_path, arch_cstr, get_dependent_files, nullptr, - target_sp)); + debugger, file_path, arch_cstr, + m_add_dependents.m_load_dependent_files, nullptr, target_sp)); if (target_sp) { // Only get the platform after we create the target because we might @@ -275,7 +335,7 @@ protected: if (remote_file) { if (platform_sp) { // I have a remote file.. two possible cases - if (file_spec && file_spec.Exists()) { + if (file_spec && FileSystem::Instance().Exists(file_spec)) { // if the remote file does not exist, push it there if (!platform_sp->GetFileExists(remote_file)) { Status err = platform_sp->PutFile(file_spec, remote_file); @@ -343,8 +403,8 @@ protected: if (core_file) { char core_path[PATH_MAX]; core_file.GetPath(core_path, sizeof(core_path)); - if (core_file.Exists()) { - if (!core_file.Readable()) { + if (FileSystem::Instance().Exists(core_file)) { + if (!FileSystem::Instance().Readable(core_file)) { result.AppendMessageWithFormat( "Core file '%s' is not readable.\n", core_path); result.SetStatus(eReturnStatusFailed); @@ -411,7 +471,7 @@ private: OptionGroupFile m_platform_path; OptionGroupFile m_symbol_file; OptionGroupFile m_remote_file; - OptionGroupBoolean m_add_dependents; + OptionGroupDependents m_add_dependents; }; #pragma mark CommandObjectTargetList @@ -1612,12 +1672,11 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm, const uint32_t max_num_matches = UINT32_MAX; size_t num_matches = 0; bool name_is_fully_qualified = false; - SymbolContext sc; ConstString name(name_cstr); llvm::DenseSet searched_symbol_files; num_matches = - module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, + module->FindTypes(name, name_is_fully_qualified, max_num_matches, searched_symbol_files, type_list); if (num_matches) { @@ -1655,11 +1714,8 @@ static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm, } static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm, - const SymbolContext &sym_ctx, - const char *name_cstr, bool name_is_regex) { - if (!sym_ctx.module_sp) - return 0; - + Module &module, const char *name_cstr, + bool name_is_regex) { TypeList type_list; const uint32_t max_num_matches = UINT32_MAX; size_t num_matches = 1; @@ -1667,14 +1723,13 @@ static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm, ConstString name(name_cstr); llvm::DenseSet searched_symbol_files; - num_matches = sym_ctx.module_sp->FindTypes( - sym_ctx, name, name_is_fully_qualified, max_num_matches, - searched_symbol_files, type_list); + num_matches = module.FindTypes(name, name_is_fully_qualified, max_num_matches, + searched_symbol_files, type_list); if (num_matches) { strm.Indent(); strm.PutCString("Best match found in "); - DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0); + DumpFullpath(strm, &module.GetFileSpec(), 0); strm.PutCString(":\n"); TypeSP type_sp(type_list.GetTypeAtIndex(0)); @@ -1732,7 +1787,7 @@ static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, static size_t FindModulesByName(Target *target, const char *module_name, ModuleList &module_list, bool check_global_list) { - FileSpec module_file_spec(module_name, false); + FileSpec module_file_spec(module_name); ModuleSpec module_spec(module_file_spec); const size_t initial_size = module_list.GetSize(); @@ -1922,16 +1977,15 @@ protected: #pragma mark CommandObjectTargetModulesDumpSymtab -static OptionEnumValueElement g_sort_option_enumeration[4] = { +static constexpr OptionEnumValueElement g_sort_option_enumeration[] = { {eSortOrderNone, "none", "No sorting, use the original symbol table order."}, {eSortOrderByAddress, "address", "Sort output by symbol address."}, - {eSortOrderByName, "name", "Sort output by symbol name."}, - {0, nullptr, nullptr}}; + {eSortOrderByName, "name", "Sort output by symbol name."} }; -static OptionDefinition g_target_modules_dump_symtab_options[] = { +static constexpr OptionDefinition g_target_modules_dump_symtab_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." } + { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, OptionEnumValues(g_sort_option_enumeration), 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." } // clang-format on }; @@ -2165,6 +2219,85 @@ protected: } }; +#pragma mark CommandObjectTargetModulesDumpSections + +//---------------------------------------------------------------------- +// Clang AST dumping command +//---------------------------------------------------------------------- + +class CommandObjectTargetModulesDumpClangAST + : public CommandObjectTargetModulesModuleAutoComplete { +public: + CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter) + : CommandObjectTargetModulesModuleAutoComplete( + interpreter, "target modules dump ast", + "Dump the clang ast for a given module's symbol file.", + //"target modules dump ast [ ...]") + nullptr) {} + + ~CommandObjectTargetModulesDumpClangAST() override = default; + +protected: + bool DoExecute(Args &command, CommandReturnObject &result) override { + Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); + if (target == nullptr) { + result.AppendError("invalid target, create a debug target using the " + "'target create' command"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + const size_t num_modules = target->GetImages().GetSize(); + if (num_modules == 0) { + result.AppendError("the target has no associated executable images"); + result.SetStatus(eReturnStatusFailed); + return false; + } + + if (command.GetArgumentCount() == 0) { + // Dump all ASTs for all modules images + result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64 + " modules.\n", + (uint64_t)num_modules); + for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { + if (m_interpreter.WasInterrupted()) + break; + Module *m = target->GetImages().GetModulePointerAtIndex(image_idx); + SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile(); + sf->DumpClangAST(result.GetOutputStream()); + } + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } + + // Dump specified ASTs (by basename or fullpath) + for (const Args::ArgEntry &arg : command.entries()) { + ModuleList module_list; + const size_t num_matches = + FindModulesByName(target, arg.c_str(), module_list, true); + if (num_matches == 0) { + // Check the global list + std::lock_guard guard( + Module::GetAllocationModuleCollectionMutex()); + + result.AppendWarningWithFormat( + "Unable to find an image that matches '%s'.\n", arg.c_str()); + continue; + } + + for (size_t i = 0; i < num_matches; ++i) { + if (m_interpreter.WasInterrupted()) + break; + Module *m = module_list.GetModulePointerAtIndex(i); + SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile(); + sf->DumpClangAST(result.GetOutputStream()); + } + } + result.SetStatus(eReturnStatusSuccessFinishResult); + return true; + } +}; + #pragma mark CommandObjectTargetModulesDumpSymfile //---------------------------------------------------------------------- @@ -2292,7 +2425,7 @@ protected: for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; ++arg_idx) { - FileSpec file_spec(arg_cstr, false); + FileSpec file_spec(arg_cstr); const ModuleList &target_modules = target->GetImages(); std::lock_guard guard(target_modules.GetMutex()); @@ -2340,12 +2473,13 @@ public: // Constructors and Destructors //------------------------------------------------------------------ CommandObjectTargetModulesDump(CommandInterpreter &interpreter) - : CommandObjectMultiword(interpreter, "target modules dump", - "Commands for dumping information about one or " - "more target modules.", - "target modules dump " - "[headers|symtab|sections|symfile|line-table] " - "[ ...]") { + : CommandObjectMultiword( + interpreter, "target modules dump", + "Commands for dumping information about one or " + "more target modules.", + "target modules dump " + "[headers|symtab|sections|ast|symfile|line-table] " + "[ ...]") { LoadSubCommand("objfile", CommandObjectSP( new CommandObjectTargetModulesDumpObjfile(interpreter))); @@ -2358,6 +2492,9 @@ public: LoadSubCommand("symfile", CommandObjectSP( new CommandObjectTargetModulesDumpSymfile(interpreter))); + LoadSubCommand( + "ast", CommandObjectSP( + new CommandObjectTargetModulesDumpClangAST(interpreter))); LoadSubCommand("line-table", CommandObjectSP(new CommandObjectTargetModulesDumpLineTable( interpreter))); @@ -2472,8 +2609,8 @@ protected: if (entry.ref.empty()) continue; - FileSpec file_spec(entry.ref, true); - if (file_spec.Exists()) { + FileSpec file_spec(entry.ref); + if (FileSystem::Instance().Exists(file_spec)) { ModuleSpec module_spec(file_spec); if (m_uuid_option_group.GetOptionValue().OptionWasSet()) module_spec.GetUUID() = @@ -2740,10 +2877,15 @@ protected: } if (set_pc) { ThreadList &thread_list = process->GetThreadList(); - ThreadSP curr_thread(thread_list.GetSelectedThread()); RegisterContextSP reg_context( - curr_thread->GetRegisterContext()); - reg_context->SetPC(file_entry.GetLoadAddress(target)); + thread_list.GetSelectedThread()->GetRegisterContext()); + addr_t file_entry_addr = file_entry.GetLoadAddress(target); + if (!reg_context->SetPC(file_entry_addr)) { + result.AppendErrorWithFormat("failed to set PC value to " + "0x%" PRIx64 "\n", + file_entry_addr); + result.SetStatus(eReturnStatusFailed); + } } } } else { @@ -2817,23 +2959,23 @@ protected: // List images with associated information //---------------------------------------------------------------------- -static OptionDefinition g_target_modules_list_options[] = { +static constexpr OptionDefinition g_target_modules_list_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." }, - { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images." }, - { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images." }, - { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise." }, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)." }, - { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images." }, - { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file." }, - { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." }, - { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." }, - { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." }, - { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." }, - { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module." }, - { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." }, - { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer." }, - { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." } + { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Display the image at this address." }, + { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the architecture when listing images." }, + { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the triple when listing images." }, + { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image base address as a load address if debugging, a file address otherwise." }, + { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image load address offset from the base file address (the slide amount)." }, + { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the UUID when listing images." }, + { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image object file." }, + { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." }, + { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." }, + { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." }, + { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." }, + { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the modification time with optional width of the module." }, + { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." }, + { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeNone, "Display the module pointer." }, + { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." } // clang-format on }; @@ -3082,13 +3224,13 @@ protected: ObjectFile *objfile = module->GetObjectFile(); if (objfile) { - Address header_addr(objfile->GetHeaderAddress()); - if (header_addr.IsValid()) { + Address base_addr(objfile->GetBaseAddress()); + if (base_addr.IsValid()) { if (target && !target->GetSectionLoadList().IsEmpty()) { - lldb::addr_t header_load_addr = - header_addr.GetLoadAddress(target); - if (header_load_addr == LLDB_INVALID_ADDRESS) { - header_addr.Dump(&strm, target, + lldb::addr_t load_addr = + base_addr.GetLoadAddress(target); + if (load_addr == LLDB_INVALID_ADDRESS) { + base_addr.Dump(&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); } else { @@ -3096,18 +3238,18 @@ protected: // Show the offset of slide for the image strm.Printf( "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, - header_load_addr - header_addr.GetFileAddress()); + load_addr - base_addr.GetFileAddress()); } else { // Show the load address of the image strm.Printf("0x%*.*" PRIx64, addr_nibble_width, - addr_nibble_width, header_load_addr); + addr_nibble_width, load_addr); } } break; } // The address was valid, but the image isn't loaded, output the // address in an appropriate format - header_addr.Dump(&strm, target, Address::DumpStyleFileAddress); + base_addr.Dump(&strm, target, Address::DumpStyleFileAddress); break; } } @@ -3183,10 +3325,10 @@ protected: // Lookup unwind information in images //---------------------------------------------------------------------- -static OptionDefinition g_target_modules_show_unwind_options[] = { +static constexpr OptionDefinition g_target_modules_show_unwind_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." }, - { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" } + { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." }, + { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" } // clang-format on }; @@ -3489,21 +3631,21 @@ protected: // Lookup information in images //---------------------------------------------------------------------- -static OptionDefinition g_target_modules_lookup_options[] = { +static constexpr OptionDefinition g_target_modules_lookup_options[] = { // clang-format off - { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." }, - { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When looking up an address subtract from any addresses before doing the lookup." }, + { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." }, + { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When looking up an address subtract from any addresses before doing the lookup." }, /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ - { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The argument for name lookups are regular expressions." }, - { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." }, - { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." }, - { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." }, - { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." }, - { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." }, - { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." }, - { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." }, - { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information." }, - { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." }, + { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "The argument for name lookups are regular expressions." }, + { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." }, + { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." }, + { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." }, + { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." }, + { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." }, + { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." }, + { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." }, + { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose lookup information." }, + { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." }, // clang-format on }; @@ -3551,7 +3693,7 @@ public: break; case 'f': - m_file.SetFile(option_arg, false, FileSpec::Style::native); + m_file.SetFile(option_arg, FileSpec::Style::native); m_type = eLookupTypeFileLine; break; @@ -3685,8 +3827,9 @@ public: return false; case eLookupTypeType: if (!m_options.m_str.empty()) { - if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx, - m_options.m_str.c_str(), m_options.m_use_regex)) { + if (LookupTypeHere(m_interpreter, result.GetOutputStream(), + *sym_ctx.module_sp, m_options.m_str.c_str(), + m_options.m_use_regex)) { result.SetStatus(eReturnStatusSuccessFinishResult); return true; } @@ -4190,7 +4333,8 @@ protected: ModuleSP frame_module_sp( frame->GetSymbolContext(eSymbolContextModule).module_sp); if (frame_module_sp) { - if (frame_module_sp->GetPlatformFileSpec().Exists()) { + if (FileSystem::Instance().Exists( + frame_module_sp->GetPlatformFileSpec())) { module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); module_spec.GetFileSpec() = @@ -4237,7 +4381,7 @@ protected: module_spec.GetArchitecture() = target->GetArchitecture(); } success |= module_spec.GetUUID().IsValid() || - module_spec.GetFileSpec().Exists(); + FileSystem::Instance().Exists(module_spec.GetFileSpec()); } } @@ -4282,8 +4426,9 @@ protected: for (auto &entry : args.entries()) { if (!entry.ref.empty()) { - module_spec.GetSymbolFileSpec().SetFile(entry.ref, true, - FileSpec::Style::native); + auto &symbol_file_spec = module_spec.GetSymbolFileSpec(); + symbol_file_spec.SetFile(entry.ref, FileSpec::Style::native); + FileSystem::Instance().Resolve(symbol_file_spec); if (file_option_set) { module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); @@ -4297,7 +4442,8 @@ protected: } ArchSpec arch; - bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); + bool symfile_exists = + FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec()); if (symfile_exists) { if (!AddModuleSymbols(target, module_spec, flush, result)) @@ -4369,19 +4515,19 @@ private: // CommandObjectTargetStopHookAdd //------------------------------------------------------------------------- -static OptionDefinition g_target_stop_hook_add_options[] = { +static constexpr OptionDefinition g_target_stop_hook_add_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." }, - { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." }, - { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." }, - { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." }, - { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." }, - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." }, - { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." }, - { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." }, - { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." }, - { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." }, + { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, + { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." }, + { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." }, + { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." }, + { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." }, + { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." }, + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." }, + { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." }, + { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." }, + { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." }, + { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." }, // clang-format on }; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp index 3be559963df1..e792887d4ff3 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.cpp @@ -9,12 +9,7 @@ #include "CommandObjectThread.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/SourceManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/Host.h" #include "lldb/Host/OptionParser.h" @@ -37,6 +32,7 @@ #include "lldb/Target/ThreadPlanStepInstruction.h" #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Target/ThreadPlanStepRange.h" +#include "lldb/Utility/State.h" #include "lldb/lldb-private.h" using namespace lldb; @@ -247,11 +243,11 @@ protected: // CommandObjectThreadBacktrace //------------------------------------------------------------------------- -static OptionDefinition g_thread_backtrace_options[] = { +static constexpr OptionDefinition g_thread_backtrace_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "How many frames to display (-1 for all)" }, - { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace" }, - { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Show the extended backtrace, if available" } + { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "How many frames to display (-1 for all)" }, + { LLDB_OPT_SET_1, false, "start", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFrameIndex, "Frame in which to start the backtrace" }, + { LLDB_OPT_SET_1, false, "extended", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Show the extended backtrace, if available" } // clang-format on }; @@ -402,28 +398,26 @@ protected: enum StepScope { eStepScopeSource, eStepScopeInstruction }; -static OptionEnumValueElement g_tri_running_mode[] = { +static constexpr OptionEnumValueElement g_tri_running_mode[] = { {eOnlyThisThread, "this-thread", "Run only this thread"}, {eAllThreads, "all-threads", "Run all threads"}, {eOnlyDuringStepping, "while-stepping", - "Run only this thread while stepping"}, - {0, nullptr, nullptr}}; + "Run only this thread while stepping"} }; -static OptionEnumValueElement g_duo_running_mode[] = { - {eOnlyThisThread, "this-thread", "Run only this thread"}, - {eAllThreads, "all-threads", "Run all threads"}, - {0, nullptr, nullptr}}; +static constexpr OptionEnumValues TriRunningModes() { + return OptionEnumValues(g_tri_running_mode); +} -static OptionDefinition g_thread_step_scope_options[] = { +static constexpr OptionDefinition g_thread_step_scope_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information." }, - { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information." }, - { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst." }, - { LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over. You can also pass the string 'block' to step to the end of the current block. This is particularly useful in conjunction with --step-target to step through a complex calling sequence." }, - { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, g_tri_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread." }, - { LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in." }, - { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into." }, - { LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step." } + { LLDB_OPT_SET_1, false, "step-in-avoids-no-debug", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "A boolean value that sets whether stepping into functions will step over functions with no debug information." }, + { LLDB_OPT_SET_1, false, "step-out-avoids-no-debug", 'A', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "A boolean value, if true stepping out of functions will continue to step out till it hits a function with debug information." }, + { LLDB_OPT_SET_1, false, "count", 'c', OptionParser::eRequiredArgument, nullptr, {}, 1, eArgTypeCount, "How many times to perform the stepping operation - currently only supported for step-inst and next-inst." }, + { LLDB_OPT_SET_1, false, "end-linenumber", 'e', OptionParser::eRequiredArgument, nullptr, {}, 1, eArgTypeLineNum, "The line at which to stop stepping - defaults to the next line and only supported for step-in and step-over. You can also pass the string 'block' to step to the end of the current block. This is particularly useful in conjunction with --step-target to step through a complex calling sequence." }, + { LLDB_OPT_SET_1, false, "run-mode", 'm', OptionParser::eRequiredArgument, nullptr, TriRunningModes(), 0, eArgTypeRunMode, "Determine how to run other threads while stepping the current thread." }, + { LLDB_OPT_SET_1, false, "step-over-regexp", 'r', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeRegularExpression, "A regular expression that defines function names to not to stop at when stepping in." }, + { LLDB_OPT_SET_1, false, "step-in-target", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "The name of the directly called function step in should stop at when stepping into." }, + { LLDB_OPT_SET_2, false, "python-class", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "The name of the class that will manage this step - only supported for Scripted Step." } // clang-format on }; @@ -483,8 +477,7 @@ public: break; case 'm': { - OptionEnumValueElement *enum_values = - GetDefinitions()[option_idx].enum_values; + auto enum_values = GetDefinitions()[option_idx].enum_values; m_run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum( option_arg, enum_values, eOnlyDuringStepping, error); } break; @@ -657,6 +650,7 @@ protected: bool_stop_other_threads = true; ThreadPlanSP new_plan_sp; + Status new_plan_status; if (m_step_type == eStepTypeInto) { StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); @@ -706,7 +700,7 @@ protected: abort_other_plans, range, frame->GetSymbolContext(eSymbolContextEverything), m_options.m_step_in_target.c_str(), stop_other_threads, - m_options.m_step_in_avoid_no_debug, + new_plan_status, m_options.m_step_in_avoid_no_debug, m_options.m_step_out_avoid_no_debug); if (new_plan_sp && !m_options.m_avoid_regexp.empty()) { @@ -716,7 +710,7 @@ protected: } } else new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( - false, abort_other_plans, bool_stop_other_threads); + false, abort_other_plans, bool_stop_other_threads, new_plan_status); } else if (m_step_type == eStepTypeOver) { StackFrame *frame = thread->GetStackFrameAtIndex(0).get(); @@ -725,25 +719,26 @@ protected: abort_other_plans, frame->GetSymbolContext(eSymbolContextEverything).line_entry, frame->GetSymbolContext(eSymbolContextEverything), - stop_other_threads, m_options.m_step_out_avoid_no_debug); + stop_other_threads, new_plan_status, + m_options.m_step_out_avoid_no_debug); else new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( - true, abort_other_plans, bool_stop_other_threads); + true, abort_other_plans, bool_stop_other_threads, new_plan_status); } else if (m_step_type == eStepTypeTrace) { new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( - false, abort_other_plans, bool_stop_other_threads); + false, abort_other_plans, bool_stop_other_threads, new_plan_status); } else if (m_step_type == eStepTypeTraceOver) { new_plan_sp = thread->QueueThreadPlanForStepSingleInstruction( - true, abort_other_plans, bool_stop_other_threads); + true, abort_other_plans, bool_stop_other_threads, new_plan_status); } else if (m_step_type == eStepTypeOut) { new_plan_sp = thread->QueueThreadPlanForStepOut( abort_other_plans, nullptr, false, bool_stop_other_threads, eVoteYes, - eVoteNoOpinion, thread->GetSelectedFrameIndex(), + eVoteNoOpinion, thread->GetSelectedFrameIndex(), new_plan_status, m_options.m_step_out_avoid_no_debug); } else if (m_step_type == eStepTypeScripted) { new_plan_sp = thread->QueueThreadPlanForStepScripted( abort_other_plans, m_options.m_class_name.c_str(), - bool_stop_other_threads); + bool_stop_other_threads, new_plan_status); } else { result.AppendError("step type is not supported"); result.SetStatus(eReturnStatusFailed); @@ -801,7 +796,7 @@ protected: result.SetStatus(eReturnStatusSuccessContinuingNoResult); } } else { - result.AppendError("Couldn't find thread plan to implement step type."); + result.SetError(new_plan_status); result.SetStatus(eReturnStatusFailed); } return result.Succeeded(); @@ -997,12 +992,20 @@ public: // CommandObjectThreadUntil //------------------------------------------------------------------------- -static OptionDefinition g_thread_until_options[] = { +static constexpr OptionEnumValueElement g_duo_running_mode[] = { + {eOnlyThisThread, "this-thread", "Run only this thread"}, + {eAllThreads, "all-threads", "Run all threads"} }; + +static constexpr OptionEnumValues DuoRunningModes() { + return OptionEnumValues(g_duo_running_mode); +} + +static constexpr OptionDefinition g_thread_until_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0" }, - { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation" }, - { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, g_duo_running_mode, 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one" }, - { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times." } + { LLDB_OPT_SET_1, false, "frame", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFrameIndex, "Frame index for until operation - defaults to 0" }, + { LLDB_OPT_SET_1, false, "thread", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "Thread index for the thread for until operation" }, + { LLDB_OPT_SET_1, false, "run-mode",'m', OptionParser::eRequiredArgument, nullptr, DuoRunningModes(), 0, eArgTypeRunMode, "Determine how to run other threads while stepping this one" }, + { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Run until we reach the specified address, or leave the function - can be specified multiple times." } // clang-format on }; @@ -1050,8 +1053,7 @@ public: } break; case 'm': { - OptionEnumValueElement *enum_values = - GetDefinitions()[option_idx].enum_values; + auto enum_values = GetDefinitions()[option_idx].enum_values; lldb::RunMode run_mode = (lldb::RunMode)OptionArgParser::ToOptionEnum( option_arg, enum_values, eOnlyDuringStepping, error); @@ -1190,6 +1192,7 @@ protected: } ThreadPlanSP new_plan_sp; + Status new_plan_status; if (frame->HasDebugInformation()) { // Finally we got here... Translate the given line number to a bunch @@ -1270,13 +1273,19 @@ protected: new_plan_sp = thread->QueueThreadPlanForStepUntil( abort_other_plans, &address_list.front(), address_list.size(), - m_options.m_stop_others, m_options.m_frame_idx); - // User level plans should be master plans so they can be interrupted - // (e.g. by hitting a breakpoint) and other plans executed by the user - // (stepping around the breakpoint) and then a "continue" will resume - // the original plan. - new_plan_sp->SetIsMasterPlan(true); - new_plan_sp->SetOkayToDiscard(false); + m_options.m_stop_others, m_options.m_frame_idx, new_plan_status); + if (new_plan_sp) { + // User level plans should be master plans so they can be interrupted + // (e.g. by hitting a breakpoint) and other plans executed by the + // user (stepping around the breakpoint) and then a "continue" will + // resume the original plan. + new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetOkayToDiscard(false); + } else { + result.SetError(new_plan_status); + result.SetStatus(eReturnStatusFailed); + return false; + } } else { result.AppendErrorWithFormat( "Frame index %u of thread %u has no debug information.\n", @@ -1419,10 +1428,10 @@ protected: // CommandObjectThreadInfo //------------------------------------------------------------------------- -static OptionDefinition g_thread_info_options[] = { +static constexpr OptionDefinition g_thread_info_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "json", 'j', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the thread info in JSON format." }, - { LLDB_OPT_SET_ALL, false, "stop-info", 's', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the extended stop info in JSON format." } + { LLDB_OPT_SET_ALL, false, "json", 'j', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the thread info in JSON format." }, + { LLDB_OPT_SET_ALL, false, "stop-info", 's', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the extended stop info in JSON format." } // clang-format on }; @@ -1510,13 +1519,58 @@ public: CommandOptions m_options; }; +//------------------------------------------------------------------------- +// CommandObjectThreadException +//------------------------------------------------------------------------- + +class CommandObjectThreadException : public CommandObjectIterateOverThreads { + public: + CommandObjectThreadException(CommandInterpreter &interpreter) + : CommandObjectIterateOverThreads( + interpreter, "thread exception", + "Display the current exception object for a thread. Defaults to " + "the current thread.", + "thread exception", + eCommandRequiresProcess | eCommandTryTargetAPILock | + eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {} + + ~CommandObjectThreadException() override = default; + + bool HandleOneThread(lldb::tid_t tid, CommandReturnObject &result) override { + ThreadSP thread_sp = + m_exe_ctx.GetProcessPtr()->GetThreadList().FindThreadByID(tid); + if (!thread_sp) { + result.AppendErrorWithFormat("thread no longer exists: 0x%" PRIx64 "\n", + tid); + result.SetStatus(eReturnStatusFailed); + return false; + } + + Stream &strm = result.GetOutputStream(); + ValueObjectSP exception_object_sp = thread_sp->GetCurrentException(); + if (exception_object_sp) { + exception_object_sp->Dump(strm); + } + + ThreadSP exception_thread_sp = thread_sp->GetCurrentExceptionBacktrace(); + if (exception_thread_sp && exception_thread_sp->IsValid()) { + const uint32_t num_frames_with_source = 0; + const bool stop_format = false; + exception_thread_sp->GetStatus(strm, 0, UINT32_MAX, + num_frames_with_source, stop_format); + } + + return true; + } +}; + //------------------------------------------------------------------------- // CommandObjectThreadReturn //------------------------------------------------------------------------- -static OptionDefinition g_thread_return_options[] = { +static constexpr OptionDefinition g_thread_return_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Return from the innermost expression evaluation." } + { LLDB_OPT_SET_ALL, false, "from-expression", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Return from the innermost expression evaluation." } // clang-format on }; @@ -1692,13 +1746,13 @@ protected: // CommandObjectThreadJump //------------------------------------------------------------------------- -static OptionDefinition g_thread_jump_options[] = { +static constexpr OptionDefinition g_thread_jump_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file to jump to." }, - { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Specifies the line number to jump to." }, - { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "Jumps by a relative line offset from the current line." }, - { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Jumps to a specific address." }, - { LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Allows the PC to leave the current function." } + { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specifies the source file to jump to." }, + { LLDB_OPT_SET_1, true, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Specifies the line number to jump to." }, + { LLDB_OPT_SET_2, true, "by", 'b', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "Jumps by a relative line offset from the current line." }, + { LLDB_OPT_SET_3, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Jumps to a specific address." }, + { LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "force", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Allows the PC to leave the current function." } // clang-format on }; @@ -1725,7 +1779,7 @@ public: switch (short_option) { case 'f': - m_filenames.AppendIfUnique(FileSpec(option_arg, false)); + m_filenames.AppendIfUnique(FileSpec(option_arg)); if (m_filenames.GetSize() > 1) return Status("only one source file expected."); break; @@ -1844,10 +1898,10 @@ protected: // CommandObjectThreadPlanList //------------------------------------------------------------------------- -static OptionDefinition g_thread_plan_list_options[] = { +static constexpr OptionDefinition g_thread_plan_list_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display more information about the thread plans" }, - { LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display internal as well as user thread plans" } + { LLDB_OPT_SET_1, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display more information about the thread plans" }, + { LLDB_OPT_SET_1, false, "internal", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display internal as well as user thread plans" } // clang-format on }; @@ -2055,6 +2109,9 @@ CommandObjectMultiwordThread::CommandObjectMultiwordThread( CommandObjectSP(new CommandObjectThreadUntil(interpreter))); LoadSubCommand("info", CommandObjectSP(new CommandObjectThreadInfo(interpreter))); + LoadSubCommand( + "exception", + CommandObjectSP(new CommandObjectThreadException(interpreter))); LoadSubCommand("step-in", CommandObjectSP(new CommandObjectThreadStepWithTypeAndScope( interpreter, "thread step-in", diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.h index 589031e0a038..5da31cec58e1 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectThread.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectThread_h_ #define liblldb_CommandObjectThread_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectType.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectType.cpp index 6bcc334198fc..815e563197b0 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectType.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectType.cpp @@ -9,16 +9,12 @@ #include "CommandObjectType.h" -// C Includes -// C++ Includes #include #include #include -// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Core/State.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -39,9 +35,9 @@ #include "lldb/Target/ThreadList.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StringList.h" -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" using namespace lldb; @@ -99,23 +95,23 @@ static bool WarnOnPotentialUnquotedUnsignedType(Args &command, return false; } -static OptionDefinition g_type_summary_add_options[] = { +static constexpr OptionDefinition g_type_summary_add_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one." }, - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, - { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type." }, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions." }, - { LLDB_OPT_SET_1, true, "inline-children", 'c', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, inline all child values into summary string." }, - { LLDB_OPT_SET_1, false, "omit-names", 'O', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If true, omit value names in the summary display." }, - { LLDB_OPT_SET_2, true, "summary-string", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSummaryString, "Summary string used to display text and object contents." }, - { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command." }, - { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type." }, - { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Input Python code to use for this type manually." }, - { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines." }, - { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "hide-empty", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Do not expand aggregate data types with no children." }, - { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "A name for this summary string." } + { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Add this to the given category instead of the default one." }, + { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, + { LLDB_OPT_SET_ALL, false, "no-value", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't show the value, just show the summary, for this type." }, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type names are actually regular expressions." }, + { LLDB_OPT_SET_1, true, "inline-children", 'c', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, inline all child values into summary string." }, + { LLDB_OPT_SET_1, false, "omit-names", 'O', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If true, omit value names in the summary display." }, + { LLDB_OPT_SET_2, true, "summary-string", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSummaryString, "Summary string used to display text and object contents." }, + { LLDB_OPT_SET_3, false, "python-script", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonScript, "Give a one-liner Python script as part of the command." }, + { LLDB_OPT_SET_3, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to use for this type." }, + { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Input Python code to use for this type manually." }, + { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "expand", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Expand aggregate data types to show children on separate lines." }, + { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "hide-empty", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Do not expand aggregate data types with no children." }, + { LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "A name for this summary string." } // clang-format on }; @@ -301,15 +297,15 @@ static const char *g_synth_addreader_instructions = " '''Optional'''\n" "class synthProvider:\n"; -static OptionDefinition g_type_synth_add_options[] = { +static constexpr OptionDefinition g_type_synth_add_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one." }, - { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children." }, - { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions." } + { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, + { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Add this to the given category instead of the default one." }, + { LLDB_OPT_SET_2, false, "python-class", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonClass, "Use this Python class to produce synthetic children." }, + { LLDB_OPT_SET_3, false, "input-python", 'P', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type Python code to generate a class that provides synthetic children." }, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type names are actually regular expressions." } // clang-format on }; @@ -531,14 +527,14 @@ public: // CommandObjectTypeFormatAdd //------------------------------------------------------------------------- -static OptionDefinition g_type_format_add_options[] = { +static constexpr OptionDefinition g_type_format_add_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one." }, - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions." }, - { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Format variables as if they were of this type." } + { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Add this to the given category instead of the default one." }, + { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type names are actually regular expressions." }, + { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Format variables as if they were of this type." } // clang-format on }; @@ -754,11 +750,11 @@ protected: } }; -static OptionDefinition g_type_formatter_delete_options[] = { +static constexpr OptionDefinition g_type_formatter_delete_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Delete from every category." }, - { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Delete from given category." }, - { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Delete from given language's category." } + { LLDB_OPT_SET_1, false, "all", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Delete from every category." }, + { LLDB_OPT_SET_2, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Delete from given category." }, + { LLDB_OPT_SET_3, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Delete from given language's category." } // clang-format on }; @@ -896,9 +892,9 @@ protected: } }; -static OptionDefinition g_type_formatter_clear_options[] = { +static constexpr OptionDefinition g_type_formatter_clear_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Clear every category." } + { LLDB_OPT_SET_ALL, false, "all", 'a', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Clear every category." } // clang-format on }; @@ -1013,6 +1009,14 @@ public: "type format clear", "Delete all existing format styles.") {} }; + +static constexpr OptionDefinition g_type_formatter_list_options[] = { + // clang-format off + {LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Only show categories matching this filter."}, + {LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Only show the category for a specific language."} + // clang-format on +}; + template class CommandObjectTypeFormatterList : public CommandObjectParsed { typedef typename FormatterType::SharedPointer FormatterSharedPointer; @@ -1055,13 +1059,7 @@ class CommandObjectTypeFormatterList : public CommandObjectParsed { } llvm::ArrayRef GetDefinitions() override { - static OptionDefinition g_option_table[] = { - // clang-format off - {LLDB_OPT_SET_1, false, "category-regex", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Only show categories matching this filter."}, - {LLDB_OPT_SET_2, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Only show the category for a specific language."} - // clang-format on - }; - return llvm::ArrayRef(g_option_table); + return llvm::makeArrayRef(g_type_formatter_list_options); } // Instance variables to hold the values for command options. @@ -1784,10 +1782,10 @@ protected: // CommandObjectTypeCategoryDefine //------------------------------------------------------------------------- -static OptionDefinition g_type_category_define_options[] = { +static constexpr OptionDefinition g_type_category_define_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "If specified, this category will be created enabled." }, - { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Specify the language that this category is supported for." } + { LLDB_OPT_SET_ALL, false, "enabled", 'e', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "If specified, this category will be created enabled." }, + { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Specify the language that this category is supported for." } // clang-format on }; @@ -1891,9 +1889,9 @@ protected: // CommandObjectTypeCategoryEnable //------------------------------------------------------------------------- -static OptionDefinition g_type_category_enable_options[] = { +static constexpr OptionDefinition g_type_category_enable_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Enable the category for this language." }, + { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Enable the category for this language." }, // clang-format on }; @@ -2068,9 +2066,9 @@ protected: // CommandObjectTypeCategoryDisable //------------------------------------------------------------------------- -OptionDefinition g_type_category_disable_options[] = { +OptionDefinition constexpr g_type_category_disable_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Enable the category for this language." } + { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Enable the category for this language." } // clang-format on }; @@ -2492,14 +2490,14 @@ bool CommandObjectTypeSynthAdd::AddSynth(ConstString type_name, #endif // LLDB_DISABLE_PYTHON -static OptionDefinition g_type_filter_add_options[] = { +static constexpr OptionDefinition g_type_filter_add_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, - { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, - { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Add this to the given category instead of the default one." }, - { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view." }, - { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Type names are actually regular expressions." } + { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "If true, cascade through typedef chains." }, + { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects." }, + { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Don't use this format for references-to-type objects." }, + { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Add this to the given category instead of the default one." }, + { LLDB_OPT_SET_ALL, false, "child", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpressionPath, "Include this expression path in the synthetic view." }, + { LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Type names are actually regular expressions." } // clang-format on }; @@ -2747,10 +2745,10 @@ protected: //---------------------------------------------------------------------- // "type lookup" //---------------------------------------------------------------------- -static OptionDefinition g_type_lookup_options[] = { +static constexpr OptionDefinition g_type_lookup_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "show-help", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display available help for types" }, - { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLanguage, "Which language's types should the search scope be" } + { LLDB_OPT_SET_ALL, false, "show-help", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display available help for types" }, + { LLDB_OPT_SET_ALL, false, "language", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage, "Which language's types should the search scope be" } // clang-format on }; @@ -2909,7 +2907,7 @@ public: if (StackFrame *frame = m_exe_ctx.GetFramePtr()) { guessed_language = GuessLanguage(frame); if (guessed_language != eLanguageTypeUnknown) { - std::sort( + llvm::sort( languages.begin(), languages.end(), [guessed_language](Language *lang1, Language *lang2) -> bool { if (!lang1 || !lang2) diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectType.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectType.h index f2f9ce7c1b61..a9223f842b30 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectType.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectType.h @@ -10,11 +10,7 @@ #ifndef liblldb_CommandObjectType_h_ #define liblldb_CommandObjectType_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectVersion.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectVersion.cpp index 8b1f25bfc521..6155f49e9762 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectVersion.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectVersion.cpp @@ -9,10 +9,6 @@ #include "CommandObjectVersion.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectVersion.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectVersion.h index 5f661cc341c0..d1afafc69bf8 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectVersion.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectVersion.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectVersion_h_ #define liblldb_CommandObjectVersion_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.cpp index 96ae18b35743..d2600a462203 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.cpp @@ -10,14 +10,10 @@ #include "CommandObjectWatchpoint.h" #include "CommandObjectWatchpointCommand.h" -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/StringRef.h" -// Project includes #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Breakpoint/WatchpointList.h" #include "lldb/Core/ValueObject.h" @@ -142,11 +138,9 @@ bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( return false; wp_ids.push_back(beg); } - // It is an error if after the loop, we're still in_range. - if (in_range) - return false; - return true; // Success! + // It is an error if after the loop, we're still in_range. + return !in_range; } //------------------------------------------------------------------------- @@ -158,11 +152,11 @@ bool CommandObjectMultiwordWatchpoint::VerifyWatchpointIDs( //------------------------------------------------------------------------- #pragma mark List::CommandOptions -static OptionDefinition g_watchpoint_list_options[] = { +static constexpr OptionDefinition g_watchpoint_list_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a brief description of the watchpoint (no location info)." }, - { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Give a full description of the watchpoint and its locations." }, - { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Explain everything we know about the watchpoint (for debugging debugger bugs)." } + { LLDB_OPT_SET_1, false, "brief", 'b', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a brief description of the watchpoint (no location info)." }, + { LLDB_OPT_SET_2, false, "full", 'f', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Give a full description of the watchpoint and its locations." }, + { LLDB_OPT_SET_3, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Explain everything we know about the watchpoint (for debugging debugger bugs)." } // clang-format on }; @@ -529,9 +523,9 @@ protected: //------------------------------------------------------------------------- #pragma mark Ignore::CommandOptions -static OptionDefinition g_watchpoint_ignore_options[] = { +static constexpr OptionDefinition g_watchpoint_ignore_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." } + { LLDB_OPT_SET_ALL, true, "ignore-count", 'i', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Set the number of times this watchpoint is skipped before stopping." } // clang-format on }; @@ -651,9 +645,9 @@ private: #pragma mark Modify::CommandOptions -static OptionDefinition g_watchpoint_modify_options[] = { +static constexpr OptionDefinition g_watchpoint_modify_options[] = { // clang-format off - { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true." } + { LLDB_OPT_SET_ALL, false, "condition", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeExpression, "The watchpoint stops only if this condition expression evaluates to true." } // clang-format on }; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.h index adc0a81fa69c..bc0a2c0c6a7d 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpoint.h @@ -10,11 +10,7 @@ #ifndef liblldb_CommandObjectWatchpoint_h_ #define liblldb_CommandObjectWatchpoint_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/OptionGroupWatchpoint.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpointCommand.cpp b/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpointCommand.cpp index 74015a433831..3a9ebfbd15d0 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpointCommand.cpp +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpointCommand.cpp @@ -7,24 +7,20 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "CommandObjectWatchpoint.h" #include "CommandObjectWatchpointCommand.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/IOHandler.h" -#include "lldb/Core/State.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; @@ -38,20 +34,23 @@ using namespace lldb_private; // language to lldb and have it pickable here without having to change this // enumeration by hand and rebuild lldb proper. -static OptionEnumValueElement g_script_option_enumeration[4] = { +static constexpr OptionEnumValueElement g_script_option_enumeration[] = { {eScriptLanguageNone, "command", "Commands are in the lldb command interpreter language"}, {eScriptLanguagePython, "python", "Commands are in the Python language."}, {eSortOrderByName, "default-script", - "Commands are in the default scripting language."}, - {0, nullptr, nullptr}}; + "Commands are in the default scripting language."} }; -static OptionDefinition g_watchpoint_command_add_options[] = { +static constexpr OptionEnumValues ScriptOptionEnum() { + return OptionEnumValues(g_script_option_enumeration); +} + +static constexpr OptionDefinition g_watchpoint_command_add_options[] = { // clang-format off - { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, "Specify a one-line watchpoint command inline. Be sure to surround it with quotes." }, - { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, "Specify whether watchpoint command execution should terminate on error." }, - { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, g_script_option_enumeration, 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." }, - { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate." } + { LLDB_OPT_SET_1, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line watchpoint command inline. Be sure to surround it with quotes." }, + { LLDB_OPT_SET_ALL, false, "stop-on-error", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether watchpoint command execution should terminate on error." }, + { LLDB_OPT_SET_ALL, false, "script-type", 's', OptionParser::eRequiredArgument, nullptr, ScriptOptionEnum(), 0, eArgTypeNone, "Specify the language for the commands - if none is specified, the lldb command interpreter will be used." }, + { LLDB_OPT_SET_2, false, "python-function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePythonFunction, "Give the name of a Python function to run as command for this watchpoint. Be sure to give a module name if appropriate." } // clang-format on }; diff --git a/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpointCommand.h b/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpointCommand.h index 63152f2f68a6..e079220d0efe 100644 --- a/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpointCommand.h +++ b/contrib/llvm/tools/lldb/source/Commands/CommandObjectWatchpointCommand.h @@ -10,11 +10,7 @@ #ifndef liblldb_CommandObjectWatchpointCommand_h_ #define liblldb_CommandObjectWatchpointCommand_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/Options.h" diff --git a/contrib/llvm/tools/lldb/source/Core/Address.cpp b/contrib/llvm/tools/lldb/source/Core/Address.cpp index f183245f7d36..a4dc364b701b 100644 --- a/contrib/llvm/tools/lldb/source/Core/Address.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Address.cpp @@ -10,43 +10,43 @@ #include "lldb/Core/Address.h" #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" // for ModuleList +#include "lldb/Core/ModuleList.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/Block.h" -#include "lldb/Symbol/Declaration.h" // for Declaration -#include "lldb/Symbol/LineEntry.h" // for LineEntry +#include "lldb/Symbol/Declaration.h" +#include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/Symbol.h" // for Symbol -#include "lldb/Symbol/SymbolContext.h" // for SymbolContext +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolVendor.h" -#include "lldb/Symbol/Symtab.h" // for Symtab -#include "lldb/Symbol/Type.h" // for Type +#include "lldb/Symbol/Symtab.h" +#include "lldb/Symbol/Type.h" #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/ExecutionContextScope.h" // for ExecutionContextScope +#include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/Utility/DataExtractor.h" // for DataExtractor -#include "lldb/Utility/Endian.h" // for InlHostByteOrder -#include "lldb/Utility/FileSpec.h" // for FileSpec -#include "lldb/Utility/Status.h" // for Status -#include "lldb/Utility/Stream.h" // for Stream -#include "lldb/Utility/StreamString.h" // for StreamString +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/Stream.h" +#include "lldb/Utility/StreamString.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" -#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH +#include "llvm/Support/Compiler.h" -#include // for uint8_t, uint32_t -#include // for shared_ptr, operator!= -#include // for vector +#include +#include +#include -#include // for assert -#include // for PRIu64, PRIx64 -#include // for size_t, strlen +#include +#include +#include namespace lldb_private { class CompileUnit; @@ -779,8 +779,9 @@ bool Address::SectionWasDeletedPrivate() const { m_section_wp.owner_before(empty_section_wp); } -uint32_t Address::CalculateSymbolContext(SymbolContext *sc, - uint32_t resolve_scope) const { +uint32_t +Address::CalculateSymbolContext(SymbolContext *sc, + SymbolContextItem resolve_scope) const { sc->Clear(false); // Absolute addresses don't have enough information to reconstruct even their // target. @@ -987,8 +988,10 @@ AddressClass Address::GetAddressClass() const { if (module_sp) { ObjectFile *obj_file = module_sp->GetObjectFile(); if (obj_file) { - // Give the symbol vendor a chance to add to the unified section list. - module_sp->GetSymbolVendor(); + // Give the symbol vendor a chance to add to the unified section list + // and to symtab from symbol file + if (SymbolVendor *vendor = module_sp->GetSymbolVendor()) + vendor->GetSymtab(); return obj_file->GetAddressClass(GetFileAddress()); } } diff --git a/contrib/llvm/tools/lldb/source/Core/AddressRange.cpp b/contrib/llvm/tools/lldb/source/Core/AddressRange.cpp index e125b693d6f6..1afe4fa223db 100644 --- a/contrib/llvm/tools/lldb/source/Core/AddressRange.cpp +++ b/contrib/llvm/tools/lldb/source/Core/AddressRange.cpp @@ -10,16 +10,16 @@ #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Stream.h" -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS +#include "lldb/lldb-defines.h" -#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH +#include "llvm/Support/Compiler.h" -#include // for shared_ptr +#include -#include // for PRIx64 +#include namespace lldb_private { class SectionList; diff --git a/contrib/llvm/tools/lldb/source/Core/AddressResolverFileLine.cpp b/contrib/llvm/tools/lldb/source/Core/AddressResolverFileLine.cpp index 798a9b50079e..203ab2787fe3 100644 --- a/contrib/llvm/tools/lldb/source/Core/AddressResolverFileLine.cpp +++ b/contrib/llvm/tools/lldb/source/Core/AddressResolverFileLine.cpp @@ -9,21 +9,21 @@ #include "lldb/Core/AddressResolverFileLine.h" -#include "lldb/Core/Address.h" // for Address -#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" #include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/LineEntry.h" // for LineEntry +#include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/SymbolContext.h" -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet, LIB... -#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" -#include "lldb/lldb-enumerations.h" // for SymbolContextItem::eSymbolCon... -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-types.h" -#include // for PRIx64 -#include // for vector +#include +#include using namespace lldb; using namespace lldb_private; @@ -78,8 +78,8 @@ AddressResolverFileLine::SearchCallback(SearchFilter &filter, return Searcher::eCallbackReturnContinue; } -Searcher::Depth AddressResolverFileLine::GetDepth() { - return Searcher::eDepthCompUnit; +lldb::SearchDepth AddressResolverFileLine::GetDepth() { + return lldb::eSearchDepthCompUnit; } void AddressResolverFileLine::GetDescription(Stream *s) { diff --git a/contrib/llvm/tools/lldb/source/Core/AddressResolverName.cpp b/contrib/llvm/tools/lldb/source/Core/AddressResolverName.cpp index c3dab6d10810..7683e391e0cf 100644 --- a/contrib/llvm/tools/lldb/source/Core/AddressResolverName.cpp +++ b/contrib/llvm/tools/lldb/source/Core/AddressResolverName.cpp @@ -9,25 +9,25 @@ #include "lldb/Core/AddressResolverName.h" -#include "lldb/Core/Address.h" // for Address, operator== -#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet, LIB... -#include "lldb/Utility/Stream.h" // for Stream -#include "lldb/lldb-enumerations.h" // for SymbolType::eSymbolTypeCode -#include "lldb/lldb-forward.h" // for ModuleSP -#include "lldb/lldb-types.h" // for addr_t -#include "llvm/ADT/StringRef.h" // for StringRef +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" +#include "llvm/ADT/StringRef.h" -#include // for shared_ptr -#include // for string -#include // for vector +#include +#include +#include -#include // for uint32_t +#include using namespace lldb; using namespace lldb_private; @@ -186,8 +186,8 @@ AddressResolverName::SearchCallback(SearchFilter &filter, return Searcher::eCallbackReturnContinue; } -Searcher::Depth AddressResolverName::GetDepth() { - return Searcher::eDepthModule; +lldb::SearchDepth AddressResolverName::GetDepth() { + return lldb::eSearchDepthModule; } void AddressResolverName::GetDescription(Stream *s) { diff --git a/contrib/llvm/tools/lldb/source/Core/Communication.cpp b/contrib/llvm/tools/lldb/source/Core/Communication.cpp index 5ca338639de0..afdabc0c7ce5 100644 --- a/contrib/llvm/tools/lldb/source/Core/Communication.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Communication.cpp @@ -9,28 +9,28 @@ #include "lldb/Core/Communication.h" -#include "lldb/Core/Event.h" -#include "lldb/Core/Listener.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Utility/Connection.h" -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/Listener.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for LogIfAnyCategoriesSet, LIBLLDB... -#include "lldb/Utility/Status.h" // for Status +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/Status.h" -#include "llvm/ADT/None.h" // for None -#include "llvm/ADT/Optional.h" // for Optional -#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/Support/Compiler.h" -#include // for min -#include // for duration, seconds +#include +#include #include -#include // for shared_ptr +#include -#include // for EIO -#include // for PRIu64 -#include // for snprintf +#include +#include +#include using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Core/Debugger.cpp b/contrib/llvm/tools/lldb/source/Core/Debugger.cpp index 972d0bc0a6d7..765b59c8865e 100644 --- a/contrib/llvm/tools/lldb/source/Core/Debugger.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Debugger.cpp @@ -9,67 +9,71 @@ #include "lldb/Core/Debugger.h" -#include "lldb/Breakpoint/Breakpoint.h" // for Breakpoint, Brea... -#include "lldb/Core/Event.h" // for Event, EventData... +#include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Core/FormatEntity.h" -#include "lldb/Core/Listener.h" // for Listener -#include "lldb/Core/Mangled.h" // for Mangled -#include "lldb/Core/ModuleList.h" // for Mangled +#include "lldb/Core/Mangled.h" +#include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamAsynchronousIO.h" #include "lldb/Core/StreamFile.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/Expression/REPL.h" -#include "lldb/Host/File.h" // for File, File::kInv... +#include "lldb/Host/File.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/Terminal.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/OptionValue.h" // for OptionValue, Opt... +#include "lldb/Interpreter/OptionValue.h" #include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/OptionValueSInt64.h" #include "lldb/Interpreter/OptionValueString.h" -#include "lldb/Interpreter/Property.h" // for PropertyDefinition -#include "lldb/Interpreter/ScriptInterpreter.h" // for ScriptInterpreter +#include "lldb/Interpreter/Property.h" +#include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/SymbolContext.h" // for SymbolContext +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/StructuredDataPlugin.h" #include "lldb/Target/Target.h" #include "lldb/Target/TargetList.h" #include "lldb/Target/Thread.h" -#include "lldb/Target/ThreadList.h" // for ThreadList +#include "lldb/Target/ThreadList.h" #include "lldb/Utility/AnsiTerminal.h" -#include "lldb/Utility/Log.h" // for LLDB_LOG_OPTION_... -#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/Event.h" +#include "lldb/Utility/Listener.h" +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Reproducer.h" +#include "lldb/Utility/State.h" +#include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamCallback.h" #include "lldb/Utility/StreamString.h" #if defined(_WIN32) -#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX +#include "lldb/Host/windows/PosixApi.h" +#include "lldb/Host/windows/windows.h" #endif -#include "llvm/ADT/None.h" // for None -#include "llvm/ADT/STLExtras.h" // for make_unique +#include "llvm/ADT/None.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/iterator.h" // for iterator_facade_... +#include "llvm/ADT/iterator.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Process.h" #include "llvm/Support/Threading.h" -#include "llvm/Support/raw_ostream.h" // for raw_fd_ostream +#include "llvm/Support/raw_ostream.h" -#include // for list -#include // for make_shared +#include +#include #include -#include // for set -#include // for size_t, NULL -#include // for getenv -#include // for strcmp -#include // for string -#include // for error_code +#include +#include +#include +#include +#include +#include namespace lldb_private { class Address; @@ -89,7 +93,7 @@ static std::recursive_mutex *g_debugger_list_mutex_ptr = static DebuggerList *g_debugger_list_ptr = nullptr; // NOTE: intentional leak to avoid issues with C++ destructor chain -OptionEnumValueElement g_show_disassembly_enum_values[] = { +static constexpr OptionEnumValueElement g_show_disassembly_enum_values[] = { {Debugger::eStopDisassemblyTypeNever, "never", "Never show disassembly when displaying a stop context."}, {Debugger::eStopDisassemblyTypeNoDebugInfo, "no-debuginfo", @@ -98,16 +102,14 @@ OptionEnumValueElement g_show_disassembly_enum_values[] = { "Show disassembly when there is no source information, or the source file " "is missing when displaying a stop context."}, {Debugger::eStopDisassemblyTypeAlways, "always", - "Always show disassembly when displaying a stop context."}, - {0, nullptr, nullptr}}; + "Always show disassembly when displaying a stop context."} }; -OptionEnumValueElement g_language_enumerators[] = { +static constexpr OptionEnumValueElement g_language_enumerators[] = { {eScriptLanguageNone, "none", "Disable scripting languages."}, {eScriptLanguagePython, "python", "Select python as the default scripting language."}, {eScriptLanguageDefault, "default", - "Select the lldb default as the default scripting language."}, - {0, nullptr, nullptr}}; + "Select the lldb default as the default scripting language."} }; #define MODULE_WITH_FUNC \ "{ " \ @@ -119,9 +121,12 @@ OptionEnumValueElement g_language_enumerators[] = { "${module.file.basename}{`${function.name-without-args}" \ "{${frame.no-debug}${function.pc-offset}}}}" -#define FILE_AND_LINE "{ at ${line.file.basename}:${line.number}}" +#define FILE_AND_LINE \ + "{ at ${line.file.basename}:${line.number}{:${line.column}}}" #define IS_OPTIMIZED "{${function.is-optimized} [opt]}" +#define IS_ARTIFICIAL "{${frame.is-artificial} [artificial]}" + #define DEFAULT_THREAD_FORMAT \ "thread #${thread.index}: tid = ${thread.id%tid}" \ "{, ${frame.pc}}" MODULE_WITH_FUNC FILE_AND_LINE \ @@ -146,11 +151,11 @@ OptionEnumValueElement g_language_enumerators[] = { #define DEFAULT_FRAME_FORMAT \ "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC FILE_AND_LINE \ - IS_OPTIMIZED "\\n" + IS_OPTIMIZED IS_ARTIFICIAL "\\n" #define DEFAULT_FRAME_FORMAT_NO_ARGS \ "frame #${frame.index}: ${frame.pc}" MODULE_WITH_FUNC_NO_ARGS FILE_AND_LINE \ - IS_OPTIMIZED "\\n" + IS_OPTIMIZED IS_ARTIFICIAL "\\n" // Three parts to this disassembly format specification: // 1. If this is a new function/symbol (no previous symbol/function), print @@ -162,8 +167,8 @@ OptionEnumValueElement g_language_enumerators[] = { // address <+offset>: #define DEFAULT_DISASSEMBLY_FORMAT \ "{${function.initial-function}{${module.file.basename}`}{${function.name-" \ - "without-args}}:\n}{${function.changed}\n{${module.file.basename}`}{${" \ - "function.name-without-args}}:\n}{${current-pc-arrow} " \ + "without-args}}:\\n}{${function.changed}\\n{${module.file.basename}`}{${" \ + "function.name-without-args}}:\\n}{${current-pc-arrow} " \ "}${addr-file-or-load}{ " \ "<${function.concrete-only-addr-offset-no-padding}>}: " @@ -177,10 +182,7 @@ OptionEnumValueElement g_language_enumerators[] = { // args}}:\n}{${function.changed}\n{${module.file.basename}`}{${function.name- // without-args}}:\n}{${current-pc-arrow} }{${addr-file-or-load}}: -#define DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX "${ansi.underline}" -#define DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX "${ansi.normal}" - -static OptionEnumValueElement s_stop_show_column_values[] = { +static constexpr OptionEnumValueElement s_stop_show_column_values[] = { {eStopShowColumnAnsiOrCaret, "ansi-or-caret", "Highlight the stop column with ANSI terminal codes when color/ANSI mode " "is enabled; otherwise, fall back to using a text-only caret (^) as if " @@ -192,98 +194,95 @@ static OptionEnumValueElement s_stop_show_column_values[] = { "Highlight the stop column with a caret character (^) underneath the stop " "column. This method introduces a new line in source listings that " "display thread stop locations."}, - {eStopShowColumnNone, "none", "Do not highlight the stop column."}, - {0, nullptr, nullptr}}; + {eStopShowColumnNone, "none", "Do not highlight the stop column."}}; -static PropertyDefinition g_properties[] = { - {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, +static constexpr PropertyDefinition g_properties[] = { + {"auto-confirm", OptionValue::eTypeBoolean, true, false, nullptr, {}, "If true all confirmation prompts will receive their default reply."}, {"disassembly-format", OptionValue::eTypeFormatEntity, true, 0, - DEFAULT_DISASSEMBLY_FORMAT, nullptr, + DEFAULT_DISASSEMBLY_FORMAT, {}, "The default disassembly format " "string to use when disassembling " "instruction sequences."}, {"frame-format", OptionValue::eTypeFormatEntity, true, 0, - DEFAULT_FRAME_FORMAT, nullptr, + DEFAULT_FRAME_FORMAT, {}, "The default frame format string to use " "when displaying stack frame information " "for threads."}, - {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, nullptr, + {"notify-void", OptionValue::eTypeBoolean, true, false, nullptr, {}, "Notify the user explicitly if an expression returns void (default: " "false)."}, {"prompt", OptionValue::eTypeString, true, - OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", - nullptr, "The debugger command line prompt displayed for the user."}, + OptionValueString::eOptionEncodeCharacterEscapeSequences, "(lldb) ", {}, + "The debugger command line prompt displayed for the user."}, {"script-lang", OptionValue::eTypeEnum, true, eScriptLanguagePython, - nullptr, g_language_enumerators, + nullptr, OptionEnumValues(g_language_enumerators), "The script language to be used for evaluating user-written scripts."}, - {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr, - nullptr, + {"stop-disassembly-count", OptionValue::eTypeSInt64, true, 4, nullptr, {}, "The number of disassembly lines to show when displaying a " "stopped context."}, {"stop-disassembly-display", OptionValue::eTypeEnum, true, Debugger::eStopDisassemblyTypeNoDebugInfo, nullptr, - g_show_disassembly_enum_values, + OptionEnumValues(g_show_disassembly_enum_values), "Control when to display disassembly when displaying a stopped context."}, - {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr, - nullptr, + {"stop-line-count-after", OptionValue::eTypeSInt64, true, 3, nullptr, {}, "The number of sources lines to display that come after the " "current source line when displaying a stopped context."}, - {"stop-line-count-before", OptionValue::eTypeSInt64, true, 3, nullptr, - nullptr, + {"stop-line-count-before", OptionValue::eTypeSInt64, true, 3, nullptr, {}, "The number of sources lines to display that come before the " "current source line when displaying a stopped context."}, + {"highlight-source", OptionValue::eTypeBoolean, true, true, nullptr, {}, + "If true, LLDB will highlight the displayed source code."}, {"stop-show-column", OptionValue::eTypeEnum, false, - eStopShowColumnAnsiOrCaret, nullptr, s_stop_show_column_values, + eStopShowColumnAnsiOrCaret, nullptr, OptionEnumValues(s_stop_show_column_values), "If true, LLDB will use the column information from the debug info to " "mark the current position when displaying a stopped context."}, - {"stop-show-column-ansi-prefix", OptionValue::eTypeFormatEntity, true, 0, - DEFAULT_STOP_SHOW_COLUMN_ANSI_PREFIX, nullptr, + {"stop-show-column-ansi-prefix", OptionValue::eTypeString, true, 0, + "${ansi.underline}", {}, "When displaying the column marker in a color-enabled (i.e. ANSI) " "terminal, use the ANSI terminal code specified in this format at the " "immediately before the column to be marked."}, - {"stop-show-column-ansi-suffix", OptionValue::eTypeFormatEntity, true, 0, - DEFAULT_STOP_SHOW_COLUMN_ANSI_SUFFIX, nullptr, + {"stop-show-column-ansi-suffix", OptionValue::eTypeString, true, 0, + "${ansi.normal}", {}, "When displaying the column marker in a color-enabled (i.e. ANSI) " "terminal, use the ANSI terminal code specified in this format " "immediately after the column to be marked."}, - {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, nullptr, + {"term-width", OptionValue::eTypeSInt64, true, 80, nullptr, {}, "The maximum number of columns to use for displaying text."}, {"thread-format", OptionValue::eTypeFormatEntity, true, 0, - DEFAULT_THREAD_FORMAT, nullptr, + DEFAULT_THREAD_FORMAT, {}, "The default thread format string to use " "when displaying thread information."}, {"thread-stop-format", OptionValue::eTypeFormatEntity, true, 0, - DEFAULT_THREAD_STOP_FORMAT, nullptr, + DEFAULT_THREAD_STOP_FORMAT, {}, "The default thread format " "string to use when displaying thread " "information as part of the stop display."}, - {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr, - nullptr, "Whether to use an external editor or not."}, - {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, + {"use-external-editor", OptionValue::eTypeBoolean, true, false, nullptr, {}, + "Whether to use an external editor or not."}, + {"use-color", OptionValue::eTypeBoolean, true, true, nullptr, {}, "Whether to use Ansi color codes or not."}, {"auto-one-line-summaries", OptionValue::eTypeBoolean, true, true, nullptr, - nullptr, + {}, "If true, LLDB will automatically display small structs in " "one-liner format (default: true)."}, - {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, + {"auto-indent", OptionValue::eTypeBoolean, true, true, nullptr, {}, "If true, LLDB will auto indent/outdent code. Currently only supported in " "the REPL (default: true)."}, - {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, + {"print-decls", OptionValue::eTypeBoolean, true, true, nullptr, {}, "If true, LLDB will print the values of variables declared in an " "expression. Currently only supported in the REPL (default: true)."}, - {"tab-size", OptionValue::eTypeUInt64, true, 4, nullptr, nullptr, + {"tab-size", OptionValue::eTypeUInt64, true, 4, nullptr, {}, "The tab size to use when indenting code in multi-line input mode " "(default: 4)."}, {"escape-non-printables", OptionValue::eTypeBoolean, true, true, nullptr, - nullptr, + {}, "If true, LLDB will automatically escape non-printable and " "escape characters when formatting strings."}, {"frame-format-unique", OptionValue::eTypeFormatEntity, true, 0, - DEFAULT_FRAME_FORMAT_NO_ARGS, nullptr, + DEFAULT_FRAME_FORMAT_NO_ARGS, {}, "The default frame format string to use when displaying stack frame" - "information for threads from thread backtrace unique."}, - {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}}; + "information for threads from thread backtrace unique."}}; enum { ePropertyAutoConfirm = 0, @@ -296,6 +295,7 @@ enum { ePropertyStopDisassemblyDisplay, ePropertyStopLineCountAfter, ePropertyStopLineCountBefore, + ePropertyHighlightSource, ePropertyStopShowColumn, ePropertyStopShowColumnAnsiPrefix, ePropertyStopShowColumnAnsiSuffix, @@ -413,6 +413,11 @@ void Debugger::SetPrompt(llvm::StringRef p) { GetCommandInterpreter().UpdatePrompt(new_prompt); } +llvm::StringRef Debugger::GetReproducerPath() const { + auto &r = repro::Reproducer::Instance(); + return r.GetReproducerPath().GetCString(); +} + const FormatEntity::Entry *Debugger::GetThreadFormat() const { const uint32_t idx = ePropertyThreadFormat; return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); @@ -470,20 +475,26 @@ bool Debugger::SetUseColor(bool b) { return ret; } +bool Debugger::GetHighlightSource() const { + const uint32_t idx = ePropertyHighlightSource; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value); +} + StopShowColumn Debugger::GetStopShowColumn() const { const uint32_t idx = ePropertyStopShowColumn; return (lldb::StopShowColumn)m_collection_sp->GetPropertyAtIndexAsEnumeration( nullptr, idx, g_properties[idx].default_uint_value); } -const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiPrefix() const { +llvm::StringRef Debugger::GetStopShowColumnAnsiPrefix() const { const uint32_t idx = ePropertyStopShowColumnAnsiPrefix; - return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); } -const FormatEntity::Entry *Debugger::GetStopShowColumnAnsiSuffix() const { +llvm::StringRef Debugger::GetStopShowColumnAnsiSuffix() const { const uint32_t idx = ePropertyStopShowColumnAnsiSuffix; - return m_collection_sp->GetPropertyAtIndexAsFormatEntity(nullptr, idx); + return m_collection_sp->GetPropertyAtIndexAsString(nullptr, idx, ""); } uint32_t Debugger::GetStopSourceLineCount(bool before) const { @@ -600,16 +611,16 @@ bool Debugger::LoadPlugin(const FileSpec &spec, Status &error) { return false; } -static FileSpec::EnumerateDirectoryResult +static FileSystem::EnumerateDirectoryResult LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, - const FileSpec &file_spec) { + llvm::StringRef path) { Status error; static ConstString g_dylibext(".dylib"); static ConstString g_solibext(".so"); if (!baton) - return FileSpec::eEnumerateDirectoryResultQuit; + return FileSystem::eEnumerateDirectoryResultQuit; Debugger *debugger = (Debugger *)baton; @@ -620,18 +631,18 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, // file type information. if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) { - FileSpec plugin_file_spec(file_spec); - plugin_file_spec.ResolvePath(); + FileSpec plugin_file_spec(path); + FileSystem::Instance().Resolve(plugin_file_spec); if (plugin_file_spec.GetFileNameExtension() != g_dylibext && plugin_file_spec.GetFileNameExtension() != g_solibext) { - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; } Status plugin_load_error; debugger->LoadPlugin(plugin_file_spec, plugin_load_error); - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; } else if (ft == fs::file_type::directory_file || ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) { @@ -639,10 +650,10 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, // also do this for unknown as sometimes the directory enumeration might be // enumerating a file system that doesn't have correct file type // information. - return FileSpec::eEnumerateDirectoryResultEnter; + return FileSystem::eEnumerateDirectoryResultEnter; } - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; } void Debugger::InstanceInitialize() { @@ -651,16 +662,20 @@ void Debugger::InstanceInitialize() { const bool find_other = true; char dir_path[PATH_MAX]; if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) { - if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { - FileSpec::EnumerateDirectory(dir_path, find_directories, find_files, - find_other, LoadPluginCallback, this); + if (FileSystem::Instance().Exists(dir_spec) && + dir_spec.GetPath(dir_path, sizeof(dir_path))) { + FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, + find_files, find_other, + LoadPluginCallback, this); } } if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) { - if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { - FileSpec::EnumerateDirectory(dir_path, find_directories, find_files, - find_other, LoadPluginCallback, this); + if (FileSystem::Instance().Exists(dir_spec) && + dir_spec.GetPath(dir_path, sizeof(dir_path))) { + FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, + find_files, find_other, + LoadPluginCallback, this); } } @@ -795,6 +810,15 @@ Debugger::Debugger(lldb::LogOutputCallback log_callback, void *baton) const char *term = getenv("TERM"); if (term && !strcmp(term, "dumb")) SetUseColor(false); + // Turn off use-color if we don't write to a terminal with color support. + if (!m_output_file_sp->GetFile().GetIsTerminalWithColors()) + SetUseColor(false); + +#if defined(_WIN32) && defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) + // Enabling use of ANSI color codes because LLDB is using them to highlight + // text. + llvm::sys::Process::UseANSIEscapeCodes(true); +#endif } Debugger::~Debugger() { Clear(); } @@ -1068,7 +1092,8 @@ void Debugger::AdoptTopIOHandlerFilesIfInvalid(StreamFileSP &in, } } -void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) { +void Debugger::PushIOHandler(const IOHandlerSP &reader_sp, + bool cancel_top_handler) { if (!reader_sp) return; @@ -1089,7 +1114,8 @@ void Debugger::PushIOHandler(const IOHandlerSP &reader_sp) { // this new input reader take over if (top_reader_sp) { top_reader_sp->Deactivate(); - top_reader_sp->Cancel(); + if (cancel_top_handler) + top_reader_sp->Cancel(); } } diff --git a/contrib/llvm/tools/lldb/source/Core/Disassembler.cpp b/contrib/llvm/tools/lldb/source/Core/Disassembler.cpp index d41a19465280..a34b8038c589 100644 --- a/contrib/llvm/tools/lldb/source/Core/Disassembler.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Disassembler.cpp @@ -9,14 +9,14 @@ #include "lldb/Core/Disassembler.h" -#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/AddressRange.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/EmulateInstruction.h" -#include "lldb/Core/Mangled.h" // for Mangled, Mangled... +#include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" // for ModuleList +#include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/SourceManager.h" // for SourceManager +#include "lldb/Core/SourceManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Interpreter/OptionValueArray.h" @@ -25,31 +25,31 @@ #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Interpreter/OptionValueUInt64.h" #include "lldb/Symbol/Function.h" -#include "lldb/Symbol/Symbol.h" // for Symbol -#include "lldb/Symbol/SymbolContext.h" // for SymbolContext +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" // for Thread +#include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/Stream.h" // for Stream -#include "lldb/Utility/StreamString.h" // for StreamString +#include "lldb/Utility/Stream.h" +#include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" -#include "lldb/lldb-private-enumerations.h" // for InstructionType:... -#include "lldb/lldb-private-interfaces.h" // for DisassemblerCrea... -#include "lldb/lldb-private-types.h" // for RegisterInfo -#include "llvm/ADT/Triple.h" // for Triple, Triple::... -#include "llvm/Support/Compiler.h" // for LLVM_PRETTY_FUNC... +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-private-interfaces.h" +#include "lldb/lldb-private-types.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Compiler.h" -#include // for uint32_t, UINT32... +#include #include -#include // for pair +#include -#include // for assert +#include #define DEFAULT_DISASM_BYTE_SIZE 32 @@ -429,9 +429,9 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, const Address &addr = inst->GetAddress(); ModuleSP module_sp(addr.GetModule()); if (module_sp) { - const uint32_t resolve_mask = eSymbolContextFunction | - eSymbolContextSymbol | - eSymbolContextLineEntry; + const SymbolContextItem resolve_mask = eSymbolContextFunction | + eSymbolContextSymbol | + eSymbolContextLineEntry; uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc); if (resolved_mask) { @@ -452,8 +452,7 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, if (mixed_source_and_assembly && sc.line_entry.IsValid()) { if (sc.symbol != previous_symbol) { SourceLine decl_line = GetFunctionDeclLineEntry(sc); - if (ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, decl_line) == - false) + if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, decl_line)) AddLineToSourceLineTables(decl_line, source_lines_seen); } if (sc.line_entry.IsValid()) { @@ -461,8 +460,7 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, this_line.file = sc.line_entry.file; this_line.line = sc.line_entry.line; this_line.column = sc.line_entry.column; - if (ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, this_line) == - false) + if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, this_line)) AddLineToSourceLineTables(this_line, source_lines_seen); } } @@ -506,8 +504,8 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, previous_symbol = sc.symbol; if (sc.function && sc.line_entry.IsValid()) { LineEntry prologue_end_line = sc.line_entry; - if (ElideMixedSourceAndDisassemblyLine( - exe_ctx, sc, prologue_end_line) == false) { + if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, + prologue_end_line)) { FileSpec func_decl_file; uint32_t func_decl_line; sc.function->GetStartLineSourceInfo(func_decl_file, @@ -547,8 +545,8 @@ bool Disassembler::PrintInstructions(Disassembler *disasm_ptr, this_line.file = sc.line_entry.file; this_line.line = sc.line_entry.line; - if (ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, - this_line) == false) { + if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, + this_line)) { // Only print this source line if it is different from the // last source line we printed. There may have been inlined // functions between these lines that we elided, resulting in @@ -934,7 +932,7 @@ bool Instruction::TestEmulation(Stream *out_stream, const char *file_name) { out_stream->Printf("Instruction::TestEmulation: Missing file_name."); return false; } - FILE *test_file = FileSystem::Fopen(file_name, "r"); + FILE *test_file = FileSystem::Instance().Fopen(file_name, "r"); if (!test_file) { out_stream->Printf( "Instruction::TestEmulation: Attempt to open test file failed."); diff --git a/contrib/llvm/tools/lldb/source/Core/DumpDataExtractor.cpp b/contrib/llvm/tools/lldb/source/Core/DumpDataExtractor.cpp index 049f4d3805a1..43a026d0dcb2 100644 --- a/contrib/llvm/tools/lldb/source/Core/DumpDataExtractor.cpp +++ b/contrib/llvm/tools/lldb/source/Core/DumpDataExtractor.cpp @@ -9,12 +9,12 @@ #include "lldb/Core/DumpDataExtractor.h" -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-forward.h" // for TargetSP, DisassemblerSP +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" -#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Address.h" #include "lldb/Core/Disassembler.h" -#include "lldb/Core/ModuleList.h" // for ModuleList +#include "lldb/Core/ModuleList.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/ExecutionContextScope.h" @@ -23,22 +23,22 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Stream.h" -#include "clang/AST/ASTContext.h" // for ASTContext -#include "clang/AST/CanonicalType.h" // for CanQualType +#include "clang/AST/ASTContext.h" +#include "clang/AST/CanonicalType.h" -#include "llvm/ADT/APFloat.h" // for APFloat, APFloatBase:... -#include "llvm/ADT/APInt.h" // for APInt -#include "llvm/ADT/ArrayRef.h" // for ArrayRef -#include "llvm/ADT/SmallVector.h" // for SmallVector +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" -#include // for numeric_limits, numer... -#include // for shared_ptr -#include // for string, basic_string +#include +#include +#include -#include // for assert -#include // for isprint -#include // for PRIu64, PRIx64, PRIX64 -#include // for ldexpf +#include +#include +#include +#include #include #include diff --git a/contrib/llvm/tools/lldb/source/Core/DumpRegisterValue.cpp b/contrib/llvm/tools/lldb/source/Core/DumpRegisterValue.cpp index 99334ca78a6d..d7196a585667 100644 --- a/contrib/llvm/tools/lldb/source/Core/DumpRegisterValue.cpp +++ b/contrib/llvm/tools/lldb/source/Core/DumpRegisterValue.cpp @@ -9,8 +9,8 @@ #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-private-types.h" diff --git a/contrib/llvm/tools/lldb/source/Core/DynamicLoader.cpp b/contrib/llvm/tools/lldb/source/Core/DynamicLoader.cpp index 16f1ffca1a20..72ee3cfd6d5b 100644 --- a/contrib/llvm/tools/lldb/source/Core/DynamicLoader.cpp +++ b/contrib/llvm/tools/lldb/source/Core/DynamicLoader.cpp @@ -10,22 +10,22 @@ #include "lldb/Target/DynamicLoader.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" // for ModuleList +#include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Symbol/ObjectFile.h" // for ObjectFile +#include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/lldb-private-interfaces.h" // for DynamicLoaderCreateInstance +#include "lldb/Utility/ConstString.h" +#include "lldb/lldb-private-interfaces.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" -#include // for shared_ptr, unique_ptr +#include -#include // for assert +#include using namespace lldb; using namespace lldb_private; @@ -81,7 +81,7 @@ ModuleSP DynamicLoader::GetTargetExecutable() { ModuleSP executable = target.GetExecutableModule(); if (executable) { - if (executable->GetFileSpec().Exists()) { + if (FileSystem::Instance().Exists(executable->GetFileSpec())) { ModuleSpec module_spec(executable->GetFileSpec(), executable->GetArchitecture()); auto module_sp = std::make_shared(module_spec); @@ -101,8 +101,7 @@ ModuleSP DynamicLoader::GetTargetExecutable() { if (executable.get() != target.GetExecutableModulePointer()) { // Don't load dependent images since we are in dyld where we will // know and find out about all images that are loaded - const bool get_dependent_images = false; - target.SetExecutableModule(executable, get_dependent_images); + target.SetExecutableModule(executable, eLoadDependentsNo); } } } @@ -196,9 +195,8 @@ ModuleSP DynamicLoader::LoadModuleAtAddress(const FileSpec &file, if (error.Success() && memory_info.GetMapped() && memory_info.GetRange().GetRangeBase() == base_addr && !(memory_info.GetName().IsEmpty())) { - ModuleSpec new_module_spec( - FileSpec(memory_info.GetName().AsCString(), false), - target.GetArchitecture()); + ModuleSpec new_module_spec(FileSpec(memory_info.GetName().AsCString()), + target.GetArchitecture()); if ((module_sp = modules.FindFirstModule(new_module_spec))) { UpdateLoadedSections(module_sp, link_map_addr, base_addr, false); diff --git a/contrib/llvm/tools/lldb/source/Core/EmulateInstruction.cpp b/contrib/llvm/tools/lldb/source/Core/EmulateInstruction.cpp index 469022119c9e..0fcb2eb7e8ce 100644 --- a/contrib/llvm/tools/lldb/source/Core/EmulateInstruction.cpp +++ b/contrib/llvm/tools/lldb/source/Core/EmulateInstruction.cpp @@ -12,27 +12,27 @@ #include "lldb/Core/Address.h" #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/StreamFile.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" -#include "lldb/Target/StackFrame.h" // for StackFrame -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Target/StackFrame.h" +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/Stream.h" // for Stream, Stream::::eBinary +#include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" -#include "lldb/lldb-forward.h" // for ProcessSP -#include "lldb/lldb-private-interfaces.h" // for EmulateInstructionCreateIn... +#include "lldb/lldb-forward.h" +#include "lldb/lldb-private-interfaces.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" #include -#include // for shared_ptr +#include -#include // for PRIx64, PRId64, PRIu64 -#include // for stdout +#include +#include namespace lldb_private { class Target; diff --git a/contrib/llvm/tools/lldb/source/Core/FileLineResolver.cpp b/contrib/llvm/tools/lldb/source/Core/FileLineResolver.cpp index 7f0f440252e7..0f4120711b24 100644 --- a/contrib/llvm/tools/lldb/source/Core/FileLineResolver.cpp +++ b/contrib/llvm/tools/lldb/source/Core/FileLineResolver.cpp @@ -9,14 +9,13 @@ #include "lldb/Core/FileLineResolver.h" -// Project includes -#include "lldb/Core/FileSpecList.h" // for FileSpecList +#include "lldb/Core/FileSpecList.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/LineTable.h" -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Stream.h" -#include // for string +#include namespace lldb_private { class Address; @@ -68,8 +67,8 @@ FileLineResolver::SearchCallback(SearchFilter &filter, SymbolContext &context, return Searcher::eCallbackReturnContinue; } -Searcher::Depth FileLineResolver::GetDepth() { - return Searcher::eDepthCompUnit; +lldb::SearchDepth FileLineResolver::GetDepth() { + return lldb::eSearchDepthCompUnit; } void FileLineResolver::GetDescription(Stream *s) { diff --git a/contrib/llvm/tools/lldb/source/Core/FileSpecList.cpp b/contrib/llvm/tools/lldb/source/Core/FileSpecList.cpp index 66e27b197447..ae4831b6efa6 100644 --- a/contrib/llvm/tools/lldb/source/Core/FileSpecList.cpp +++ b/contrib/llvm/tools/lldb/source/Core/FileSpecList.cpp @@ -9,12 +9,12 @@ #include "lldb/Core/FileSpecList.h" -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Stream.h" -#include // for find +#include -#include // for UINT32_MAX +#include using namespace lldb_private; using namespace std; diff --git a/contrib/llvm/tools/lldb/source/Core/FormatEntity.cpp b/contrib/llvm/tools/lldb/source/Core/FormatEntity.cpp index 743c7c404994..200008dcff5f 100644 --- a/contrib/llvm/tools/lldb/source/Core/FormatEntity.cpp +++ b/contrib/llvm/tools/lldb/source/Core/FormatEntity.cpp @@ -10,29 +10,28 @@ #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Address.h" -#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/AddressRange.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" // for RegisterValue #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DataVisualization.h" -#include "lldb/DataFormatters/FormatClasses.h" // for TypeNameSpecifier... +#include "lldb/DataFormatters/FormatClasses.h" #include "lldb/DataFormatters/FormatManager.h" -#include "lldb/DataFormatters/TypeSummary.h" // for TypeSummaryImpl::... +#include "lldb/DataFormatters/TypeSummary.h" #include "lldb/Expression/ExpressionVariable.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/CompilerType.h" // for CompilerType +#include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/SymbolContext.h" // for SymbolContext +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/VariableList.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/ExecutionContextScope.h" // for ExecutionContextS... +#include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -42,31 +41,32 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/AnsiTerminal.h" -#include "lldb/Utility/ArchSpec.h" // for ArchSpec -#include "lldb/Utility/ConstString.h" // for ConstString, oper... +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" -#include "lldb/Utility/Log.h" // for Log -#include "lldb/Utility/Logging.h" // for GetLogIfAllCatego... -#include "lldb/Utility/SharingPtr.h" // for SharingPtr +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/SharingPtr.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" -#include "lldb/Utility/StringList.h" // for StringList -#include "lldb/Utility/StructuredData.h" // for StructuredData::O... -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-forward.h" // for ValueObjectSP +#include "lldb/Utility/StringList.h" +#include "lldb/Utility/StructuredData.h" +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" // for Triple, Triple::O... -#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH +#include "llvm/ADT/Triple.h" +#include "llvm/Support/Compiler.h" -#include // for isxdigit -#include // for PRIu64, PRIx64 -#include // for shared_ptr, opera... -#include // for sprintf -#include // for strtoul -#include // for size_t, strchr -#include // for move -#include // for pair +#include +#include +#include +#include +#include +#include +#include +#include namespace lldb_private { class ScriptInterpreter; @@ -128,6 +128,7 @@ static FormatEntity::Entry::Definition g_frame_child_entries[] = { ENTRY("flags", FrameRegisterFlags, UInt64), ENTRY("no-debug", FrameNoDebug, None), ENTRY_CHILDREN("reg", FrameRegisterByName, UInt64, g_string_entry), + ENTRY("is-artificial", FrameIsArtificial, UInt32), }; static FormatEntity::Entry::Definition g_function_child_entries[] = { @@ -146,6 +147,7 @@ static FormatEntity::Entry::Definition g_function_child_entries[] = { static FormatEntity::Entry::Definition g_line_child_entries[] = { ENTRY_CHILDREN("file", LineEntryFile, None, g_file_child_entries), ENTRY("number", LineEntryLineNumber, UInt32), + ENTRY("column", LineEntryColumn, UInt32), ENTRY("start-addr", LineEntryStartAddress, UInt64), ENTRY("end-addr", LineEntryEndAddress, UInt64), }; @@ -356,6 +358,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) { ENUM_TO_CSTR(FrameRegisterFP); ENUM_TO_CSTR(FrameRegisterFlags); ENUM_TO_CSTR(FrameRegisterByName); + ENUM_TO_CSTR(FrameIsArtificial); ENUM_TO_CSTR(ScriptFrame); ENUM_TO_CSTR(FunctionID); ENUM_TO_CSTR(FunctionDidChange); @@ -372,6 +375,7 @@ const char *FormatEntity::Entry::TypeToCString(Type t) { ENUM_TO_CSTR(FunctionIsOptimized); ENUM_TO_CSTR(LineEntryFile); ENUM_TO_CSTR(LineEntryLineNumber); + ENUM_TO_CSTR(LineEntryColumn); ENUM_TO_CSTR(LineEntryStartAddress); ENUM_TO_CSTR(LineEntryEndAddress); ENUM_TO_CSTR(CurrentPCArrow); @@ -1487,6 +1491,13 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, } return false; + case Entry::Type::FrameIsArtificial: { + if (exe_ctx) + if (StackFrame *frame = exe_ctx->GetFramePtr()) + return frame->IsArtificial(); + return false; + } + case Entry::Type::ScriptFrame: if (exe_ctx) { StackFrame *frame = exe_ctx->GetFramePtr(); @@ -1814,6 +1825,16 @@ bool FormatEntity::Format(const Entry &entry, Stream &s, } return false; + case Entry::Type::LineEntryColumn: + if (sc && sc->line_entry.IsValid() && sc->line_entry.column) { + const char *format = "%" PRIu32; + if (!entry.printf_format.empty()) + format = entry.printf_format.c_str(); + s.Printf(format, sc->line_entry.column); + return true; + } + return false; + case Entry::Type::LineEntryStartAddress: case Entry::Type::LineEntryEndAddress: if (sc && sc->line_entry.range.GetBaseAddress().IsValid()) { diff --git a/contrib/llvm/tools/lldb/source/Core/Highlighter.cpp b/contrib/llvm/tools/lldb/source/Core/Highlighter.cpp new file mode 100644 index 000000000000..c7dd0db83645 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Core/Highlighter.cpp @@ -0,0 +1,81 @@ +//===-- Highlighter.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/Highlighter.h" + +#include "lldb/Target/Language.h" +#include "lldb/Utility/AnsiTerminal.h" +#include "lldb/Utility/StreamString.h" + +using namespace lldb_private; + +void HighlightStyle::ColorStyle::Apply(Stream &s, llvm::StringRef value) const { + s << m_prefix << value << m_suffix; +} + +void HighlightStyle::ColorStyle::Set(llvm::StringRef prefix, + llvm::StringRef suffix) { + m_prefix = lldb_utility::ansi::FormatAnsiTerminalCodes(prefix); + m_suffix = lldb_utility::ansi::FormatAnsiTerminalCodes(suffix); +} + +void DefaultHighlighter::Highlight(const HighlightStyle &options, + llvm::StringRef line, + llvm::Optional cursor_pos, + llvm::StringRef previous_lines, + Stream &s) const { + // If we don't have a valid cursor, then we just print the line as-is. + if (!cursor_pos || *cursor_pos >= line.size()) { + s << line; + return; + } + + // If we have a valid cursor, we have to apply the 'selected' style around + // the character below the cursor. + + // Split the line around the character which is below the cursor. + size_t column = *cursor_pos; + // Print the characters before the cursor. + s << line.substr(0, column); + // Print the selected character with the defined color codes. + options.selected.Apply(s, line.substr(column, 1)); + // Print the rest of the line. + s << line.substr(column + 1U); +} + +static HighlightStyle::ColorStyle GetColor(const char *c) { + return HighlightStyle::ColorStyle(c, "${ansi.normal}"); +} + +HighlightStyle HighlightStyle::MakeVimStyle() { + HighlightStyle result; + result.comment = GetColor("${ansi.fg.purple}"); + result.scalar_literal = GetColor("${ansi.fg.red}"); + result.keyword = GetColor("${ansi.fg.green}"); + return result; +} + +const Highlighter & +HighlighterManager::getHighlighterFor(lldb::LanguageType language_type, + llvm::StringRef path) const { + Language *language = lldb_private::Language::FindPlugin(language_type, path); + if (language && language->GetHighlighter()) + return *language->GetHighlighter(); + return m_default; +} + +std::string Highlighter::Highlight(const HighlightStyle &options, + llvm::StringRef line, + llvm::Optional cursor_pos, + llvm::StringRef previous_lines) const { + StreamString s; + Highlight(options, line, cursor_pos, previous_lines, s); + s.Flush(); + return s.GetString().str(); +} diff --git a/contrib/llvm/tools/lldb/source/Core/IOHandler.cpp b/contrib/llvm/tools/lldb/source/Core/IOHandler.cpp index e7ebeea1b88d..5c0eea5ea1a3 100644 --- a/contrib/llvm/tools/lldb/source/Core/IOHandler.cpp +++ b/contrib/llvm/tools/lldb/source/Core/IOHandler.cpp @@ -9,28 +9,24 @@ #include "lldb/Core/IOHandler.h" -// C Includes #ifndef LLDB_DISABLE_CURSES #include #include #endif -// C++ Includes #if defined(__APPLE__) #include #endif #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/StreamFile.h" -#include "lldb/Host/File.h" // for File -#include "lldb/Host/Predicate.h" // for Predicate, ::eBroad... -#include "lldb/Utility/Status.h" // for Status -#include "lldb/Utility/StreamString.h" // for StreamString -#include "lldb/Utility/StringList.h" // for StringList -#include "lldb/lldb-forward.h" // for StreamFileSP +#include "lldb/Host/File.h" +#include "lldb/Utility/Predicate.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StringList.h" +#include "lldb/lldb-forward.h" #ifndef LLDB_DISABLE_LIBEDIT #include "lldb/Host/Editline.h" @@ -40,7 +36,6 @@ #ifndef LLDB_DISABLE_CURSES #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectRegister.h" #include "lldb/Symbol/Block.h" @@ -53,25 +48,26 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" #endif -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" #ifdef _MSC_VER #include "lldb/Host/windows/windows.h" #endif -#include // for shared_ptr -#include // for recursive_mutex +#include +#include -#include // for assert -#include // for isspace -#include // for EINTR, errno -#include // for setlocale -#include // for uint32_t, UINT32_MAX -#include // for size_t, fprintf, feof -#include // for strlen -#include // for move +#include +#include +#include +#include +#include +#include +#include +#include using namespace lldb; using namespace lldb_private; @@ -172,12 +168,10 @@ IOHandlerConfirm::IOHandlerConfirm(Debugger &debugger, llvm::StringRef prompt, IOHandlerConfirm::~IOHandlerConfirm() = default; -int IOHandlerConfirm::IOHandlerComplete(IOHandler &io_handler, - const char *current_line, - const char *cursor, - const char *last_char, - int skip_first_n_matches, - int max_matches, StringList &matches) { +int IOHandlerConfirm::IOHandlerComplete( + IOHandler &io_handler, const char *current_line, const char *cursor, + const char *last_char, int skip_first_n_matches, int max_matches, + StringList &matches, StringList &descriptions) { if (current_line == cursor) { if (m_default_response) { matches.AppendString("y"); @@ -223,12 +217,10 @@ void IOHandlerConfirm::IOHandlerInputComplete(IOHandler &io_handler, } } -int IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler, - const char *current_line, - const char *cursor, - const char *last_char, - int skip_first_n_matches, - int max_matches, StringList &matches) { +int IOHandlerDelegate::IOHandlerComplete( + IOHandler &io_handler, const char *current_line, const char *cursor, + const char *last_char, int skip_first_n_matches, int max_matches, + StringList &matches, StringList &descriptions) { switch (m_completion) { case Completion::None: break; @@ -236,14 +228,16 @@ int IOHandlerDelegate::IOHandlerComplete(IOHandler &io_handler, case Completion::LLDBCommand: return io_handler.GetDebugger().GetCommandInterpreter().HandleCompletion( current_line, cursor, last_char, skip_first_n_matches, max_matches, - matches); - + matches, descriptions); case Completion::Expression: { + CompletionResult result; CompletionRequest request(current_line, current_line - cursor, - skip_first_n_matches, max_matches, matches); + skip_first_n_matches, max_matches, result); CommandCompletions::InvokeCommonCompletionCallbacks( io_handler.GetDebugger().GetCommandInterpreter(), CommandCompletions::eVariablePathCompletion, request, nullptr); + result.GetMatches(matches); + result.GetDescriptions(descriptions); size_t num_matches = request.GetNumberOfMatches(); if (num_matches > 0) { @@ -432,17 +426,15 @@ int IOHandlerEditline::FixIndentationCallback(Editline *editline, *editline_reader, lines, cursor_position); } -int IOHandlerEditline::AutoCompleteCallback(const char *current_line, - const char *cursor, - const char *last_char, - int skip_first_n_matches, - int max_matches, - StringList &matches, void *baton) { +int IOHandlerEditline::AutoCompleteCallback( + const char *current_line, const char *cursor, const char *last_char, + int skip_first_n_matches, int max_matches, StringList &matches, + StringList &descriptions, void *baton) { IOHandlerEditline *editline_reader = (IOHandlerEditline *)baton; if (editline_reader) return editline_reader->m_delegate.IOHandlerComplete( *editline_reader, current_line, cursor, last_char, skip_first_n_matches, - max_matches, matches); + max_matches, matches, descriptions); return 0; } #endif @@ -1060,7 +1052,7 @@ public: Windows::iterator pos, end = m_subwindows.end(); size_t i = 0; for (pos = m_subwindows.begin(); pos != end; ++pos, ++i) { - if ((*pos)->m_name.compare(name) == 0) + if ((*pos)->m_name == name) return *pos; } return WindowSP(); @@ -1752,11 +1744,7 @@ public: void Initialize() { ::setlocale(LC_ALL, ""); ::setlocale(LC_CTYPE, ""); -#if 0 - ::initscr(); -#else m_screen = ::newterm(nullptr, m_out, m_in); -#endif ::start_color(); ::curs_set(0); ::noecho(); @@ -4340,6 +4328,7 @@ public: m_file_sp->GetFileSpec(), // Source file m_selected_line + 1, // Source line number (m_selected_line is zero based) + 0, // Unspecified column. 0, // No offset eLazyBoolCalculate, // Check inlines using global setting eLazyBoolCalculate, // Skip prologue using global setting, @@ -4379,6 +4368,7 @@ public: m_file_sp->GetFileSpec(), // Source file m_selected_line + 1, // Source line number (m_selected_line is zero based) + 0, // No column specified. 0, // No offset eLazyBoolCalculate, // Check inlines using global setting eLazyBoolCalculate, // Skip prologue using global setting, diff --git a/contrib/llvm/tools/lldb/source/Core/Mangled.cpp b/contrib/llvm/tools/lldb/source/Core/Mangled.cpp index 545ac51c870f..943df008edad 100644 --- a/contrib/llvm/tools/lldb/source/Core/Mangled.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Mangled.cpp @@ -16,6 +16,7 @@ #pragma comment(lib, "dbghelp.lib") #endif +#include "lldb/Core/RichManglingContext.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/Logging.h" @@ -195,7 +196,7 @@ void Mangled::Clear() { int Mangled::Compare(const Mangled &a, const Mangled &b) { return ConstString::Compare( a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled), - a.GetName(lldb::eLanguageTypeUnknown, ePreferMangled)); + b.GetName(lldb::eLanguageTypeUnknown, ePreferMangled)); } //---------------------------------------------------------------------- @@ -232,6 +233,130 @@ void Mangled::SetValue(const ConstString &name) { } } +//---------------------------------------------------------------------- +// Local helpers for different demangling implementations. +//---------------------------------------------------------------------- +static char *GetMSVCDemangledStr(const char *M) { +#if defined(_MSC_VER) + const size_t demangled_length = 2048; + char *demangled_cstr = static_cast(::malloc(demangled_length)); + ::ZeroMemory(demangled_cstr, demangled_length); + DWORD result = safeUndecorateName(M, demangled_cstr, demangled_length); + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (demangled_cstr && demangled_cstr[0]) + log->Printf("demangled msvc: %s -> \"%s\"", M, demangled_cstr); + else + log->Printf("demangled msvc: %s -> error: 0x%lu", M, result); + } + + if (result != 0) { + return demangled_cstr; + } else { + ::free(demangled_cstr); + return nullptr; + } +#else + return nullptr; +#endif +} + +static char *GetItaniumDemangledStr(const char *M) { + char *demangled_cstr = nullptr; + + llvm::ItaniumPartialDemangler ipd; + bool err = ipd.partialDemangle(M); + if (!err) { + // Default buffer and size (will realloc in case it's too small). + size_t demangled_size = 80; + demangled_cstr = static_cast(std::malloc(demangled_size)); + demangled_cstr = ipd.finishDemangle(demangled_cstr, &demangled_size); + + assert(demangled_cstr && + "finishDemangle must always succeed if partialDemangle did"); + assert(demangled_cstr[demangled_size - 1] == '\0' && + "Expected demangled_size to return length including trailing null"); + } + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (demangled_cstr) + log->Printf("demangled itanium: %s -> \"%s\"", M, demangled_cstr); + else + log->Printf("demangled itanium: %s -> 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( + RichManglingContext &context, SkipMangledNameFn *skip_mangled_name) { + // We need to generate and cache the demangled name. + static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); + Timer scoped_timer(func_cat, + "Mangled::DemangleWithRichNameIndexInfo (m_mangled = %s)", + m_mangled.GetCString()); + + // Others are not meant to arrive here. ObjC names or C's main() for example + // have their names stored in m_demangled, while m_mangled is empty. + assert(m_mangled); + + // Check whether or not we are interested in this name at all. + ManglingScheme scheme = cstring_mangling_scheme(m_mangled.GetCString()); + if (skip_mangled_name && skip_mangled_name(m_mangled.GetStringRef(), scheme)) + return false; + + switch (scheme) { + case eManglingSchemeNone: + // The current mangled_name_filter would allow llvm_unreachable here. + return false; + + case eManglingSchemeItanium: + // We want the rich mangling info here, so we don't care whether or not + // there is a demangled string in the pool already. + if (context.FromItaniumName(m_mangled)) { + // If we got an info, we have a name. Copy to string pool and connect the + // counterparts to accelerate later access in GetDemangledName(). + context.ParseFullName(); + m_demangled.SetStringWithMangledCounterpart(context.GetBufferRef(), + m_mangled); + return true; + } else { + m_demangled.SetCString(""); + return false; + } + + case eManglingSchemeMSVC: { + // We have no rich mangling for MSVC-mangled names yet, so first try to + // demangle it if necessary. + if (!m_demangled && !m_mangled.GetMangledCounterpart(m_demangled)) { + if (char *d = GetMSVCDemangledStr(m_mangled.GetCString())) { + // If we got an info, we have a name. Copy to string pool and connect + // the counterparts to accelerate later access in GetDemangledName(). + m_demangled.SetStringWithMangledCounterpart(llvm::StringRef(d), + m_mangled); + ::free(d); + } else { + m_demangled.SetCString(""); + } + } + + if (m_demangled.IsEmpty()) { + // Cannot demangle it, so don't try parsing. + return false; + } else { + // Demangled successfully, we can try and parse it with + // CPlusPlusLanguage::MethodName. + return context.FromCxxMethodName(m_demangled); + } + } + } + llvm_unreachable("Fully covered switch above!"); +} + //---------------------------------------------------------------------- // Generate the demangled name on demand using this accessor. Code in this // class will need to use this accessor if it wishes to decode the demangled @@ -242,14 +367,12 @@ const ConstString & Mangled::GetDemangledName(lldb::LanguageType language) const { // Check to make sure we have a valid mangled name and that we haven't // already decoded our mangled name. - if (m_mangled && !m_demangled) { + if (m_mangled && m_demangled.IsNull()) { // We need to generate and cache the demangled name. static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "Mangled::GetDemangledName (m_mangled = %s)", m_mangled.GetCString()); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE); - // Don't bother running anything that isn't mangled const char *mangled_name = m_mangled.GetCString(); ManglingScheme mangling_scheme{cstring_mangling_scheme(mangled_name)}; @@ -259,60 +382,23 @@ Mangled::GetDemangledName(lldb::LanguageType language) const { // add it to our map. char *demangled_name = nullptr; switch (mangling_scheme) { - case eManglingSchemeMSVC: { -#if defined(_MSC_VER) - if (log) - log->Printf("demangle msvc: %s", mangled_name); - const size_t demangled_length = 2048; - demangled_name = static_cast(::malloc(demangled_length)); - ::ZeroMemory(demangled_name, demangled_length); - DWORD result = - safeUndecorateName(mangled_name, demangled_name, demangled_length); - if (log) { - if (demangled_name && demangled_name[0]) - log->Printf("demangled msvc: %s -> \"%s\"", mangled_name, - demangled_name); - else - log->Printf("demangled msvc: %s -> error: 0x%lu", mangled_name, - result); - } - - if (result == 0) { - free(demangled_name); - demangled_name = nullptr; - } -#endif + case eManglingSchemeMSVC: + demangled_name = GetMSVCDemangledStr(mangled_name); break; - } case eManglingSchemeItanium: { - llvm::ItaniumPartialDemangler IPD; - bool demangle_err = IPD.partialDemangle(mangled_name); - if (!demangle_err) { - // Default buffer and size (realloc is used in case it's too small). - size_t demangled_size = 80; - demangled_name = static_cast(::malloc(demangled_size)); - demangled_name = IPD.finishDemangle(demangled_name, &demangled_size); - } - - if (log) { - if (demangled_name) - log->Printf("demangled itanium: %s -> \"%s\"", mangled_name, - demangled_name); - else - log->Printf("demangled itanium: %s -> error: failed to demangle", - mangled_name); - } + demangled_name = GetItaniumDemangledStr(mangled_name); break; } case eManglingSchemeNone: - break; + llvm_unreachable("eManglingSchemeNone was handled already"); } if (demangled_name) { - m_demangled.SetCStringWithMangledCounterpart(demangled_name, m_mangled); + m_demangled.SetStringWithMangledCounterpart( + llvm::StringRef(demangled_name), m_mangled); free(demangled_name); } } - if (!m_demangled) { + if (m_demangled.IsNull()) { // Set the demangled string to the empty string to indicate we tried to // parse it once and failed. m_demangled.SetCString(""); @@ -333,9 +419,7 @@ bool Mangled::NameMatches(const RegularExpression ®ex, return true; ConstString demangled = GetDemangledName(language); - if (demangled && regex.Execute(demangled.AsCString())) - return true; - return false; + return demangled && regex.Execute(demangled.AsCString()); } //---------------------------------------------------------------------- diff --git a/contrib/llvm/tools/lldb/source/Core/Module.cpp b/contrib/llvm/tools/lldb/source/Core/Module.cpp index 3b1a4fd7be0f..b48d3cca092b 100644 --- a/contrib/llvm/tools/lldb/source/Core/Module.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Module.cpp @@ -9,65 +9,65 @@ #include "lldb/Core/Module.h" -#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/AddressRange.h" #include "lldb/Core/AddressResolverFileLine.h" -#include "lldb/Core/Debugger.h" // for Debugger -#include "lldb/Core/FileSpecList.h" // for FileSpecList -#include "lldb/Core/Mangled.h" // for Mangled +#include "lldb/Core/Debugger.h" +#include "lldb/Core/FileSpecList.h" +#include "lldb/Core/Mangled.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/SearchFilter.h" // for SearchFilt... +#include "lldb/Core/SearchFilter.h" #include "lldb/Core/Section.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/Function.h" // for Function +#include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/Symbol.h" // for Symbol +#include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" -#include "lldb/Symbol/Symtab.h" // for Symtab -#include "lldb/Symbol/Type.h" // for Type -#include "lldb/Symbol/TypeList.h" // for TypeList +#include "lldb/Symbol/Symtab.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/Language.h" -#include "lldb/Target/Platform.h" // for Platform +#include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for GetLogIfAn... +#include "lldb/Utility/Logging.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #if defined(_WIN32) -#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX +#include "lldb/Host/windows/PosixApi.h" #endif #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" -#include "llvm/ADT/STLExtras.h" // for make_unique -#include "llvm/Support/Compiler.h" // for LLVM_PRETT... +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Signals.h" -#include "llvm/Support/raw_ostream.h" // for raw_string... +#include "llvm/Support/raw_ostream.h" -#include // for assert -#include // for uint32_t -#include // for PRIx64 -#include // for map -#include // for va_end -#include // for size_t -#include // for move -#include // for find, pair +#include +#include +#include +#include +#include +#include +#include +#include namespace lldb_private { class CompilerDeclContext; @@ -162,15 +162,19 @@ Module::Module(const ModuleSpec &module_spec) // fill any ivars in so we don't accidentally grab the wrong file later since // they don't match... ModuleSpec matching_module_spec; - if (modules_specs.FindMatchingModuleSpec(module_spec, matching_module_spec) == - 0) + if (!modules_specs.FindMatchingModuleSpec(module_spec, + matching_module_spec)) { + if (log) { + log->Printf("Found local object file but the specs didn't match"); + } return; + } if (module_spec.GetFileSpec()) - m_mod_time = FileSystem::GetModificationTime(module_spec.GetFileSpec()); + m_mod_time = FileSystem::Instance().GetModificationTime(module_spec.GetFileSpec()); else if (matching_module_spec.GetFileSpec()) m_mod_time = - FileSystem::GetModificationTime(matching_module_spec.GetFileSpec()); + FileSystem::Instance().GetModificationTime(matching_module_spec.GetFileSpec()); // Copy the architecture from the actual spec if we got one back, else use // the one that was specified @@ -215,7 +219,7 @@ Module::Module(const ModuleSpec &module_spec) Module::Module(const FileSpec &file_spec, const ArchSpec &arch, const ConstString *object_name, lldb::offset_t object_offset, const llvm::sys::TimePoint<> &object_mod_time) - : m_mod_time(FileSystem::GetModificationTime(file_spec)), m_arch(arch), + : m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), m_arch(arch), m_file(file_spec), m_object_offset(object_offset), m_object_mod_time(object_mod_time), m_file_has_changed(false), m_first_file_changed_log(false) { @@ -305,7 +309,7 @@ ObjectFile *Module::GetMemoryObjectFile(const lldb::ProcessSP &process_sp, // Once we get the object file, update our module with the object // file's architecture since it might differ in vendor/os if some // parts were unknown. - m_objfile_sp->GetArchitecture(m_arch); + m_arch = m_objfile_sp->GetArchitecture(); } else { error.SetErrorString("unable to find suitable object file plug-in"); } @@ -361,26 +365,24 @@ void Module::ParseAllDebugSymbols() { for (size_t cu_idx = 0; cu_idx < num_comp_units; cu_idx++) { sc.comp_unit = symbols->GetCompileUnitAtIndex(cu_idx).get(); - if (sc.comp_unit) { - sc.function = nullptr; + if (!sc.comp_unit) + continue; + + symbols->ParseVariablesForContext(sc); + + symbols->ParseFunctions(*sc.comp_unit); + + sc.comp_unit->ForeachFunction([&sc, &symbols](const FunctionSP &f) { + symbols->ParseBlocksRecursive(*f); + + // Parse the variables for this function and all its blocks + sc.function = f.get(); symbols->ParseVariablesForContext(sc); + return false; + }); - symbols->ParseCompileUnitFunctions(sc); - - for (size_t func_idx = 0; - (sc.function = sc.comp_unit->GetFunctionAtIndex(func_idx).get()) != - nullptr; - ++func_idx) { - symbols->ParseFunctionBlocks(sc); - - // Parse the variables for this function and all its blocks - symbols->ParseVariablesForContext(sc); - } - - // Parse all types for this compile unit - sc.function = nullptr; - symbols->ParseTypes(sc); - } + // Parse all types for this compile unit + symbols->ParseTypes(*sc.comp_unit); } } @@ -431,8 +433,8 @@ bool Module::ResolveFileAddress(lldb::addr_t vm_addr, Address &so_addr) { } uint32_t Module::ResolveSymbolContextForAddress( - const Address &so_addr, uint32_t resolve_scope, SymbolContext &sc, - bool resolve_tail_call_address) { + const Address &so_addr, lldb::SymbolContextItem resolve_scope, + SymbolContext &sc, bool resolve_tail_call_address) { std::lock_guard guard(m_mutex); uint32_t resolved_flags = 0; @@ -564,21 +566,17 @@ uint32_t Module::ResolveSymbolContextForAddress( return resolved_flags; } -uint32_t Module::ResolveSymbolContextForFilePath(const char *file_path, - uint32_t line, - bool check_inlines, - uint32_t resolve_scope, - SymbolContextList &sc_list) { - FileSpec file_spec(file_path, false); +uint32_t Module::ResolveSymbolContextForFilePath( + const char *file_path, uint32_t line, bool check_inlines, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { + FileSpec file_spec(file_path); return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, resolve_scope, sc_list); } -uint32_t Module::ResolveSymbolContextsForFileSpec(const FileSpec &file_spec, - uint32_t line, - bool check_inlines, - uint32_t resolve_scope, - SymbolContextList &sc_list) { +uint32_t Module::ResolveSymbolContextsForFileSpec( + const FileSpec &file_spec, uint32_t line, bool check_inlines, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { std::lock_guard guard(m_mutex); static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, @@ -637,9 +635,11 @@ size_t Module::FindCompileUnits(const FileSpec &path, bool append, return sc_list.GetSize() - start_size; } -Module::LookupInfo::LookupInfo(const ConstString &name, uint32_t name_type_mask, - lldb::LanguageType language) - : m_name(name), m_lookup_name(), m_language(language), m_name_type_mask(0), +Module::LookupInfo::LookupInfo(const ConstString &name, + FunctionNameType name_type_mask, + LanguageType language) + : m_name(name), m_lookup_name(), m_language(language), + m_name_type_mask(eFunctionNameTypeNone), m_match_name_after_lookup(false) { const char *name_cstr = name.GetCString(); llvm::StringRef basename; @@ -783,7 +783,7 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, qualified_name = cpp_method.GetBasename().str(); else qualified_name = cpp_method.GetScopeQualifiedName(); - if (qualified_name.compare(m_name.GetCString()) != 0) { + if (qualified_name != m_name.GetCString()) { sc_list.RemoveContextAtIndex(i); continue; } @@ -797,9 +797,9 @@ void Module::LookupInfo::Prune(SymbolContextList &sc_list, size_t Module::FindFunctions(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_symbols, - bool include_inlines, bool append, - SymbolContextList &sc_list) { + FunctionNameType name_type_mask, + bool include_symbols, bool include_inlines, + bool append, SymbolContextList &sc_list) { if (!append) sc_list.Clear(); @@ -943,33 +943,33 @@ void Module::FindAddressesForLine(const lldb::TargetSP target_sp, } size_t Module::FindTypes_Impl( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION); - if (!sc.module_sp || sc.module_sp.get() == this) { - SymbolVendor *symbols = GetSymbolVendor(); - if (symbols) - return symbols->FindTypes(sc, name, parent_decl_ctx, append, max_matches, - searched_symbol_files, types); - } + SymbolVendor *symbols = GetSymbolVendor(); + if (symbols) + return symbols->FindTypes(name, parent_decl_ctx, append, max_matches, + searched_symbol_files, types); return 0; } -size_t Module::FindTypesInNamespace(const SymbolContext &sc, - const ConstString &type_name, +size_t Module::FindTypesInNamespace(const ConstString &type_name, const CompilerDeclContext *parent_decl_ctx, size_t max_matches, TypeList &type_list) { const bool append = true; TypeMap types_map; llvm::DenseSet searched_symbol_files; size_t num_types = - FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches, + FindTypes_Impl(type_name, parent_decl_ctx, append, max_matches, searched_symbol_files, types_map); - if (num_types > 0) + if (num_types > 0) { + SymbolContext sc; + sc.module_sp = shared_from_this(); sc.SortTypeList(types_map, type_list); + } return num_types; } @@ -978,15 +978,14 @@ lldb::TypeSP Module::FindFirstType(const SymbolContext &sc, TypeList type_list; llvm::DenseSet searched_symbol_files; const size_t num_matches = - FindTypes(sc, name, exact_match, 1, searched_symbol_files, type_list); + FindTypes(name, exact_match, 1, searched_symbol_files, type_list); if (num_matches) return type_list.GetTypeAtIndex(0); return TypeSP(); } size_t Module::FindTypes( - const SymbolContext &sc, const ConstString &name, bool exact_match, - size_t max_matches, + const ConstString &name, bool exact_match, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeList &types) { size_t num_matches = 0; @@ -1006,8 +1005,8 @@ size_t Module::FindTypes( exact_match = type_scope.consume_front("::"); ConstString type_basename_const_str(type_basename); - if (FindTypes_Impl(sc, type_basename_const_str, nullptr, append, - max_matches, searched_symbol_files, typesmap)) { + if (FindTypes_Impl(type_basename_const_str, nullptr, append, max_matches, + searched_symbol_files, typesmap)) { typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, exact_match); num_matches = typesmap.GetSize(); @@ -1018,13 +1017,13 @@ size_t Module::FindTypes( if (type_class != eTypeClassAny && !type_basename.empty()) { // The "type_name_cstr" will have been modified if we have a valid type // class prefix (like "struct", "class", "union", "typedef" etc). - FindTypes_Impl(sc, ConstString(type_basename), nullptr, append, - UINT_MAX, searched_symbol_files, typesmap); + FindTypes_Impl(ConstString(type_basename), nullptr, append, UINT_MAX, + searched_symbol_files, typesmap); typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, exact_match); num_matches = typesmap.GetSize(); } else { - num_matches = FindTypes_Impl(sc, name, nullptr, append, UINT_MAX, + num_matches = FindTypes_Impl(name, nullptr, append, UINT_MAX, searched_symbol_files, typesmap); if (exact_match) { std::string name_str(name.AsCString("")); @@ -1034,8 +1033,11 @@ size_t Module::FindTypes( } } } - if (num_matches > 0) + if (num_matches > 0) { + SymbolContext sc; + sc.module_sp = shared_from_this(); sc.SortTypeList(typesmap, types); + } return num_matches; } @@ -1062,7 +1064,7 @@ void Module::SetFileSpecAndObjectName(const FileSpec &file, // Container objects whose paths do not specify a file directly can call this // function to correct the file and object names. m_file = file; - m_mod_time = FileSystem::GetModificationTime(file); + m_mod_time = FileSystem::Instance().GetModificationTime(file); m_object_name = object_name; } @@ -1125,7 +1127,7 @@ void Module::ReportError(const char *format, ...) { bool Module::FileHasChanged() const { if (!m_file_has_changed) m_file_has_changed = - (FileSystem::GetModificationTime(m_file) != m_mod_time); + (FileSystem::Instance().GetModificationTime(m_file) != m_mod_time); return m_file_has_changed; } @@ -1252,7 +1254,8 @@ ObjectFile *Module::GetObjectFile() { GetFileSpec().GetFilename().AsCString("")); DataBufferSP data_sp; lldb::offset_t data_offset = 0; - const lldb::offset_t file_size = m_file.GetByteSize(); + const lldb::offset_t file_size = + FileSystem::Instance().GetByteSize(m_file); if (file_size > m_object_offset) { m_did_load_objfile = true; m_objfile_sp = ObjectFile::FindPlugin( @@ -1264,9 +1267,7 @@ ObjectFile *Module::GetObjectFile() { // parts were unknown. But since the matching arch might already be // more specific than the generic COFF architecture, only merge in // those values that overwrite unspecified unknown values. - ArchSpec new_arch; - m_objfile_sp->GetArchitecture(new_arch); - m_arch.MergeFrom(new_arch); + m_arch.MergeFrom(m_objfile_sp->GetArchitecture()); } else { ReportError("failed to load objfile for %s", GetFileSpec().GetPath().c_str()); @@ -1417,7 +1418,7 @@ void Module::PreloadSymbols() { } void Module::SetSymbolFileFileSpec(const FileSpec &file) { - if (!file.Exists()) + if (!FileSystem::Instance().Exists(file)) return; if (m_symfile_ap) { // Remove any sections in the unified section list that come from the @@ -1447,7 +1448,7 @@ void Module::SetSymbolFileFileSpec(const FileSpec &file) { // ("/tmp/a.out.dSYM/Contents/Resources/DWARF/a.out"). So we need to // check this - if (llvm::sys::fs::is_directory(file.GetPath())) { + if (FileSystem::Instance().IsDirectory(file)) { std::string new_path(file.GetPath()); std::string old_path(obj_file->GetFileSpec().GetPath()); if (old_path.find(new_path) == 0) { @@ -1536,7 +1537,8 @@ bool Module::LoadScriptingResourceInTarget(Target *target, Status &error, if (script_interpreter) { for (uint32_t i = 0; i < num_specs; ++i) { FileSpec scripting_fspec(file_specs.GetFileSpecAtIndex(i)); - if (scripting_fspec && scripting_fspec.Exists()) { + if (scripting_fspec && + FileSystem::Instance().Exists(scripting_fspec)) { if (should_load == eLoadScriptFromSymFileWarn) { if (feedback_stream) feedback_stream->Printf( diff --git a/contrib/llvm/tools/lldb/source/Core/ModuleList.cpp b/contrib/llvm/tools/lldb/source/Core/ModuleList.cpp index d2896da1adca..b8de86f4eadc 100644 --- a/contrib/llvm/tools/lldb/source/Core/ModuleList.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ModuleList.cpp @@ -8,39 +8,39 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ModuleList.h" -#include "lldb/Core/FileSpecList.h" // for FileSpecList +#include "lldb/Core/FileSpecList.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Symbols.h" -#include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/OptionValueFileSpec.h" +#include "lldb/Interpreter/OptionValueProperties.h" #include "lldb/Interpreter/Property.h" #include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolContext.h" // for SymbolContextList, SymbolCon... +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/VariableList.h" -#include "lldb/Utility/ArchSpec.h" // for ArchSpec -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for GetLogIfAnyCategoriesSet -#include "lldb/Utility/UUID.h" // for UUID, operator!=, operator== -#include "lldb/lldb-defines.h" // for LLDB_INVALID_INDEX32 +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/UUID.h" +#include "lldb/lldb-defines.h" #if defined(_WIN32) -#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX +#include "lldb/Host/windows/PosixApi.h" #endif -#include "llvm/ADT/StringRef.h" // for StringRef +#include "clang/Driver/Driver.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Threading.h" -#include "llvm/Support/raw_ostream.h" // for fs -#include "clang/Driver/Driver.h" +#include "llvm/Support/raw_ostream.h" -#include // for operator!=, time_point -#include // for shared_ptr +#include +#include #include -#include // for string -#include // for distance +#include +#include namespace lldb_private { class Function; @@ -66,16 +66,22 @@ using namespace lldb_private; namespace { -PropertyDefinition g_properties[] = { +static constexpr PropertyDefinition g_properties[] = { {"enable-external-lookup", OptionValue::eTypeBoolean, true, true, nullptr, - nullptr, - "Control the use of external tools or libraries to locate symbol files. " - "On macOS, Spotlight is used to locate a matching .dSYM bundle based on " - "the UUID of the executable."}, + {}, + "Control the use of external tools and repositories to locate symbol " + "files. Directories listed in target.debug-file-search-paths and " + "directory of the executable are always checked first for separate debug " + "info files. Then depending on this setting: " + "On macOS, Spotlight would be also used to locate a matching .dSYM " + "bundle based on the UUID of the executable. " + "On NetBSD, directory /usr/libdata/debug would be also searched. " + "On platforms other than NetBSD directory /usr/lib/debug would be " + "also searched." + }, {"clang-modules-cache-path", OptionValue::eTypeFileSpec, true, 0, nullptr, - nullptr, - "The path to the clang modules cache directory (-fmodules-cache-path)."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + {}, + "The path to the clang modules cache directory (-fmodules-cache-path)."}}; enum { ePropertyEnableExternalLookup, ePropertyClangModulesCachePath }; @@ -339,8 +345,9 @@ ModuleSP ModuleList::GetModuleAtIndexUnlocked(size_t idx) const { } size_t ModuleList::FindFunctions(const ConstString &name, - uint32_t name_type_mask, bool include_symbols, - bool include_inlines, bool append, + FunctionNameType name_type_mask, + bool include_symbols, bool include_inlines, + bool append, SymbolContextList &sc_list) const { if (!append) sc_list.Clear(); @@ -374,7 +381,7 @@ size_t ModuleList::FindFunctions(const ConstString &name, } size_t ModuleList::FindFunctionSymbols(const ConstString &name, - uint32_t name_type_mask, + lldb::FunctionNameType name_type_mask, SymbolContextList &sc_list) { const size_t old_size = sc_list.GetSize(); @@ -535,7 +542,7 @@ ModuleSP ModuleList::FindModule(const UUID &uuid) const { } size_t -ModuleList::FindTypes(const SymbolContext &sc, const ConstString &name, +ModuleList::FindTypes(Module *search_first, const ConstString &name, bool name_is_fully_qualified, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeList &types) const { @@ -543,14 +550,12 @@ ModuleList::FindTypes(const SymbolContext &sc, const ConstString &name, size_t total_matches = 0; collection::const_iterator pos, end = m_modules.end(); - if (sc.module_sp) { - // The symbol context "sc" contains a module so we want to search that one - // first if it is in our list... + if (search_first) { for (pos = m_modules.begin(); pos != end; ++pos) { - if (sc.module_sp.get() == (*pos).get()) { + if (search_first == pos->get()) { total_matches += - (*pos)->FindTypes(sc, name, name_is_fully_qualified, max_matches, - searched_symbol_files, types); + search_first->FindTypes(name, name_is_fully_qualified, max_matches, + searched_symbol_files, types); if (total_matches >= max_matches) break; @@ -559,15 +564,14 @@ ModuleList::FindTypes(const SymbolContext &sc, const ConstString &name, } if (total_matches < max_matches) { - SymbolContext world_sc; for (pos = m_modules.begin(); pos != end; ++pos) { // Search the module if the module is not equal to the one in the symbol // context "sc". If "sc" contains a empty module shared pointer, then the // comparison will always be true (valid_module_ptr != nullptr). - if (sc.module_sp.get() != (*pos).get()) + if (search_first != pos->get()) total_matches += - (*pos)->FindTypes(world_sc, name, name_is_fully_qualified, - max_matches, searched_symbol_files, types); + (*pos)->FindTypes(name, name_is_fully_qualified, max_matches, + searched_symbol_files, types); if (total_matches >= max_matches) break; @@ -663,9 +667,10 @@ bool ModuleList::ResolveFileAddress(lldb::addr_t vm_addr, return false; } -uint32_t ModuleList::ResolveSymbolContextForAddress(const Address &so_addr, - uint32_t resolve_scope, - SymbolContext &sc) const { +uint32_t +ModuleList::ResolveSymbolContextForAddress(const Address &so_addr, + SymbolContextItem resolve_scope, + SymbolContext &sc) const { // The address is already section offset so it has a module uint32_t resolved_flags = 0; ModuleSP module_sp(so_addr.GetModule()); @@ -688,15 +693,15 @@ uint32_t ModuleList::ResolveSymbolContextForAddress(const Address &so_addr, uint32_t ModuleList::ResolveSymbolContextForFilePath( const char *file_path, uint32_t line, bool check_inlines, - uint32_t resolve_scope, SymbolContextList &sc_list) const { - FileSpec file_spec(file_path, false); + SymbolContextItem resolve_scope, SymbolContextList &sc_list) const { + FileSpec file_spec(file_path); return ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, resolve_scope, sc_list); } uint32_t ModuleList::ResolveSymbolContextsForFileSpec( const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, SymbolContextList &sc_list) const { + SymbolContextItem resolve_scope, SymbolContextList &sc_list) const { std::lock_guard guard(m_modules_mutex); collection::const_iterator pos, end = m_modules.end(); for (pos = m_modules.begin(); pos != end; ++pos) { @@ -856,14 +861,13 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, const auto num_directories = module_search_paths_ptr->GetSize(); for (size_t idx = 0; idx < num_directories; ++idx) { auto search_path_spec = module_search_paths_ptr->GetFileSpecAtIndex(idx); - if (!search_path_spec.ResolvePath()) - continue; + FileSystem::Instance().Resolve(search_path_spec); namespace fs = llvm::sys::fs; - if (!fs::is_directory(search_path_spec.GetPath())) + if (!FileSystem::Instance().IsDirectory(search_path_spec)) continue; search_path_spec.AppendPathComponent( module_spec.GetFileSpec().GetFilename().AsCString()); - if (!search_path_spec.Exists()) + if (!FileSystem::Instance().Exists(search_path_spec)) continue; auto resolved_module_spec(module_spec); @@ -904,13 +908,15 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, // Don't look for the file if it appears to be the same one we already // checked for above... if (located_binary_modulespec.GetFileSpec() != module_file_spec) { - if (!located_binary_modulespec.GetFileSpec().Exists()) { + if (!FileSystem::Instance().Exists( + located_binary_modulespec.GetFileSpec())) { located_binary_modulespec.GetFileSpec().GetPath(path, sizeof(path)); if (path[0] == '\0') module_file_spec.GetPath(path, sizeof(path)); // How can this check ever be true? This branch it is false, and we // haven't modified file_spec. - if (located_binary_modulespec.GetFileSpec().Exists()) { + if (FileSystem::Instance().Exists( + located_binary_modulespec.GetFileSpec())) { std::string uuid_str; if (uuid_ptr && uuid_ptr->IsValid()) uuid_str = uuid_ptr->GetAsString(); @@ -951,7 +957,7 @@ Status ModuleList::GetSharedModule(const ModuleSpec &module_spec, // If we didn't have a UUID in mind when looking for the object file, // then we should make sure the modification time hasn't changed! if (platform_module_spec.GetUUIDPtr() == nullptr) { - auto file_spec_mod_time = FileSystem::GetModificationTime( + auto file_spec_mod_time = FileSystem::Instance().GetModificationTime( located_binary_modulespec.GetFileSpec()); if (file_spec_mod_time != llvm::sys::TimePoint<>()) { if (file_spec_mod_time != module_sp->GetModificationTime()) { diff --git a/contrib/llvm/tools/lldb/source/Core/Opcode.cpp b/contrib/llvm/tools/lldb/source/Core/Opcode.cpp index d15fdb3b17be..ed8be78a6d67 100644 --- a/contrib/llvm/tools/lldb/source/Core/Opcode.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Opcode.cpp @@ -13,50 +13,51 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Stream.h" -#include "lldb/lldb-forward.h" // for DataBufferSP +#include "lldb/lldb-forward.h" -#include // for make_shared +#include -#include // for PRIx64 +#include using namespace lldb; using namespace lldb_private; int Opcode::Dump(Stream *s, uint32_t min_byte_width) { - int bytes_written = 0; + const uint32_t previous_bytes = s->GetWrittenBytes(); switch (m_type) { case Opcode::eTypeInvalid: - bytes_written = s->PutCString(""); + s->PutCString(""); break; case Opcode::eType8: - bytes_written = s->Printf("0x%2.2x", m_data.inst8); + s->Printf("0x%2.2x", m_data.inst8); break; case Opcode::eType16: - bytes_written = s->Printf("0x%4.4x", m_data.inst16); + s->Printf("0x%4.4x", m_data.inst16); break; case Opcode::eType16_2: case Opcode::eType32: - bytes_written = s->Printf("0x%8.8x", m_data.inst32); + s->Printf("0x%8.8x", m_data.inst32); break; case Opcode::eType64: - bytes_written = s->Printf("0x%16.16" PRIx64, m_data.inst64); + s->Printf("0x%16.16" PRIx64, m_data.inst64); break; case Opcode::eTypeBytes: for (uint32_t i = 0; i < m_data.inst.length; ++i) { if (i > 0) - bytes_written += s->PutChar(' '); - bytes_written += s->Printf("%2.2x", m_data.inst.bytes[i]); + s->PutChar(' '); + s->Printf("%2.2x", m_data.inst.bytes[i]); } break; } - // Add spaces to make sure bytes dispay comes out even in case opcodes aren't - // all the same size - if (static_cast(bytes_written) < min_byte_width) - bytes_written = s->Printf("%*s", min_byte_width - bytes_written, ""); - return bytes_written; + uint32_t bytes_written_so_far = s->GetWrittenBytes() - previous_bytes; + // Add spaces to make sure bytes display comes out even in case opcodes aren't + // all the same size. + if (bytes_written_so_far < min_byte_width) + s->Printf("%*s", min_byte_width - bytes_written_so_far, ""); + return s->GetWrittenBytes() - previous_bytes; } lldb::ByteOrder Opcode::GetDataByteOrder() const { diff --git a/contrib/llvm/tools/lldb/source/Core/PluginManager.cpp b/contrib/llvm/tools/lldb/source/Core/PluginManager.cpp index 55affb6a1030..fbb258039882 100644 --- a/contrib/llvm/tools/lldb/source/Core/PluginManager.cpp +++ b/contrib/llvm/tools/lldb/source/Core/PluginManager.cpp @@ -10,30 +10,31 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/Debugger.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/OptionValueProperties.h" -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" -#include "lldb/Utility/StringList.h" // for StringList +#include "lldb/Utility/StringList.h" #if defined(_WIN32) -#include "lldb/Host/windows/PosixApi.h" // for PATH_MAX +#include "lldb/Host/windows/PosixApi.h" #endif #include "llvm/ADT/StringRef.h" #include "llvm/Support/DynamicLibrary.h" -#include "llvm/Support/FileSystem.h" // for file_type, file_... -#include "llvm/Support/raw_ostream.h" // for fs +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/raw_ostream.h" -#include // for map<>::const_ite... -#include // for shared_ptr +#include +#include #include #include -#include // for pair +#include #include -#include // for assert +#include namespace lldb_private { class CommandInterpreter; @@ -89,9 +90,9 @@ template static FPtrTy CastToFPtr(void *VPtr) { return reinterpret_cast(reinterpret_cast(VPtr)); } -static FileSpec::EnumerateDirectoryResult +static FileSystem::EnumerateDirectoryResult LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, - const FileSpec &file_spec) { + llvm::StringRef path) { // PluginManager *plugin_manager = (PluginManager *)baton; Status error; @@ -102,11 +103,11 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, // file type information. if (ft == fs::file_type::regular_file || ft == fs::file_type::symlink_file || ft == fs::file_type::type_unknown) { - FileSpec plugin_file_spec(file_spec); - plugin_file_spec.ResolvePath(); + FileSpec plugin_file_spec(path); + FileSystem::Instance().Resolve(plugin_file_spec); if (PluginIsLoaded(plugin_file_spec)) - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; else { PluginInfo plugin_info; @@ -138,7 +139,7 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, // plug-in info so we don't try to load it again and again. SetPluginInfo(plugin_file_spec, plugin_info); - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; } } } @@ -149,10 +150,10 @@ LoadPluginCallback(void *baton, llvm::sys::fs::file_type ft, // also do this for unknown as sometimes the directory enumeration might be // enumerating a file system that doesn't have correct file type // information. - return FileSpec::eEnumerateDirectoryResultEnter; + return FileSystem::eEnumerateDirectoryResultEnter; } - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; } void PluginManager::Initialize() { @@ -162,16 +163,20 @@ void PluginManager::Initialize() { const bool find_other = true; char dir_path[PATH_MAX]; if (FileSpec dir_spec = HostInfo::GetSystemPluginDir()) { - if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { - FileSpec::EnumerateDirectory(dir_path, find_directories, find_files, - find_other, LoadPluginCallback, nullptr); + if (FileSystem::Instance().Exists(dir_spec) && + dir_spec.GetPath(dir_path, sizeof(dir_path))) { + FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, + find_files, find_other, + LoadPluginCallback, nullptr); } } if (FileSpec dir_spec = HostInfo::GetUserPluginDir()) { - if (dir_spec.Exists() && dir_spec.GetPath(dir_path, sizeof(dir_path))) { - FileSpec::EnumerateDirectory(dir_path, find_directories, find_files, - find_other, LoadPluginCallback, nullptr); + if (FileSystem::Instance().Exists(dir_spec) && + dir_spec.GetPath(dir_path, sizeof(dir_path))) { + FileSystem::Instance().EnumerateDirectory(dir_path, find_directories, + find_files, find_other, + LoadPluginCallback, nullptr); } } #endif @@ -281,7 +286,10 @@ struct ArchitectureInstance { typedef std::vector ArchitectureInstances; -static std::mutex g_architecture_mutex; +static std::mutex &GetArchitectureMutex() { + static std::mutex g_architecture_mutex; + return g_architecture_mutex; +} static ArchitectureInstances &GetArchitectureInstances() { static ArchitectureInstances g_instances; @@ -291,13 +299,13 @@ static ArchitectureInstances &GetArchitectureInstances() { void PluginManager::RegisterPlugin(const ConstString &name, llvm::StringRef description, ArchitectureCreateInstance create_callback) { - std::lock_guard guard(g_architecture_mutex); + std::lock_guard guard(GetArchitectureMutex()); GetArchitectureInstances().push_back({name, description, create_callback}); } void PluginManager::UnregisterPlugin( ArchitectureCreateInstance create_callback) { - std::lock_guard guard(g_architecture_mutex); + std::lock_guard guard(GetArchitectureMutex()); auto &instances = GetArchitectureInstances(); for (auto pos = instances.begin(), end = instances.end(); pos != end; ++pos) { @@ -311,7 +319,7 @@ void PluginManager::UnregisterPlugin( std::unique_ptr PluginManager::CreateArchitectureInstance(const ArchSpec &arch) { - std::lock_guard guard(g_architecture_mutex); + std::lock_guard guard(GetArchitectureMutex()); for (const auto &instances : GetArchitectureInstances()) { if (auto plugin_up = instances.create_callback(arch)) return plugin_up; diff --git a/contrib/llvm/tools/lldb/source/Core/RichManglingContext.cpp b/contrib/llvm/tools/lldb/source/Core/RichManglingContext.cpp new file mode 100644 index 000000000000..f5fbe38a49fb --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Core/RichManglingContext.cpp @@ -0,0 +1,175 @@ +//===-- RichManglingContext.cpp ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/RichManglingContext.h" + +#include "lldb/Utility/Log.h" +#include "lldb/Utility/Logging.h" + +#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" + +#include "llvm/ADT/StringRef.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// RichManglingContext +//---------------------------------------------------------------------- +void RichManglingContext::ResetProvider(InfoProvider new_provider) { + // If we want to support parsers for other languages some day, we need a + // switch here to delete the correct parser type. + if (m_cxx_method_parser.hasValue()) { + assert(m_provider == PluginCxxLanguage); + delete get(m_cxx_method_parser); + m_cxx_method_parser.reset(); + } + + assert(new_provider != None && "Only reset to a valid provider"); + m_provider = new_provider; +} + +bool RichManglingContext::FromItaniumName(const ConstString &mangled) { + bool err = m_ipd.partialDemangle(mangled.GetCString()); + if (!err) { + ResetProvider(ItaniumPartialDemangler); + } + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) { + if (!err) { + ParseFullName(); + LLDB_LOG(log, "demangled itanium: {0} -> \"{1}\"", mangled, m_ipd_buf); + } else { + LLDB_LOG(log, "demangled itanium: {0} -> error: failed to demangle", + mangled); + } + } + + return !err; // true == success +} + +bool RichManglingContext::FromCxxMethodName(const ConstString &demangled) { + ResetProvider(PluginCxxLanguage); + m_cxx_method_parser = new CPlusPlusLanguage::MethodName(demangled); + return true; +} + +bool RichManglingContext::IsCtorOrDtor() const { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: + return m_ipd.isCtorOrDtor(); + case PluginCxxLanguage: { + // We can only check for destructors here. + auto base_name = + get(m_cxx_method_parser)->GetBasename(); + return base_name.startswith("~"); + } + case None: + return false; + } + 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(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)) { + assert(res_size == m_ipd_buf_size && + "Failed IPD queries keep the original size in the N parameter"); + + m_ipd_buf[0] = '\0'; + m_buffer = llvm::StringRef(m_ipd_buf, 0); + return; + } + + // IPD's res_size includes null terminator. + assert(ipd_res[res_size - 1] == '\0' && + "IPD returns null-terminated strings and we rely on that"); + + // Update buffer/size on realloc. + if (LLVM_UNLIKELY(ipd_res != m_ipd_buf || res_size > m_ipd_buf_size)) { + m_ipd_buf = ipd_res; // std::realloc freed or reused the old buffer. + m_ipd_buf_size = res_size; // May actually be bigger, but we can't know. + + if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE)) + LLDB_LOG(log, "ItaniumPartialDemangler Realloc: new buffer size is {0}", + m_ipd_buf_size); + } + + // 99% case: Just remember the string length. + m_buffer = llvm::StringRef(m_ipd_buf, res_size - 1); +} + +void RichManglingContext::ParseFunctionBaseName() { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: { + auto n = m_ipd_buf_size; + auto buf = m_ipd.getFunctionBaseName(m_ipd_buf, &n); + processIPDStrResult(buf, n); + return; + } + case PluginCxxLanguage: + m_buffer = + get(m_cxx_method_parser)->GetBasename(); + return; + case None: + return; + } +} + +void RichManglingContext::ParseFunctionDeclContextName() { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: { + auto n = m_ipd_buf_size; + auto buf = m_ipd.getFunctionDeclContextName(m_ipd_buf, &n); + processIPDStrResult(buf, n); + return; + } + case PluginCxxLanguage: + m_buffer = + get(m_cxx_method_parser)->GetContext(); + return; + case None: + return; + } +} + +void RichManglingContext::ParseFullName() { + assert(m_provider != None && "Initialize a provider first"); + switch (m_provider) { + case ItaniumPartialDemangler: { + auto n = m_ipd_buf_size; + auto buf = m_ipd.finishDemangle(m_ipd_buf, &n); + processIPDStrResult(buf, n); + return; + } + case PluginCxxLanguage: + m_buffer = get(m_cxx_method_parser) + ->GetFullName() + .GetStringRef(); + return; + case None: + return; + } +} diff --git a/contrib/llvm/tools/lldb/source/Core/SearchFilter.cpp b/contrib/llvm/tools/lldb/source/Core/SearchFilter.cpp index 0701955233a1..5d26c715bec6 100644 --- a/contrib/llvm/tools/lldb/source/Core/SearchFilter.cpp +++ b/contrib/llvm/tools/lldb/source/Core/SearchFilter.cpp @@ -9,26 +9,27 @@ #include "lldb/Core/SearchFilter.h" -#include "lldb/Breakpoint/Breakpoint.h" // for Breakpoint +#include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" // for ModuleList +#include "lldb/Core/ModuleList.h" #include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/SymbolContext.h" // for SymbolContext +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/Utility/Status.h" // for Status -#include "lldb/Utility/Stream.h" // for Stream -#include "lldb/lldb-enumerations.h" // for SymbolContextItem::eSymbolCo... +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/Stream.h" +#include "lldb/lldb-enumerations.h" -#include "llvm/ADT/StringRef.h" // for StringRef -#include "llvm/Support/ErrorHandling.h" // for llvm_unreachable +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/ErrorHandling.h" -#include // for shared_ptr -#include // for recursive_mutex, lock_guard -#include // for string +#include +#include +#include -#include // for PRIu64 -#include // for size_t, strcmp +#include +#include namespace lldb_private { class Address; @@ -147,6 +148,15 @@ bool SearchFilter::CompUnitPasses(FileSpec &fileSpec) { return true; } bool SearchFilter::CompUnitPasses(CompileUnit &compUnit) { return true; } +bool SearchFilter::FunctionPasses(Function &function) { + // This is a slightly cheesy job, but since we don't have finer grained + // filters yet, just checking that the start address passes is probably + // good enough for the base class behavior. + Address addr = function.GetAddressRange().GetBaseAddress(); + return AddressPasses(addr); +} + + uint32_t SearchFilter::GetFilterRequiredItems() { return (lldb::SymbolContextItem)0; } @@ -207,7 +217,7 @@ void SearchFilter::Search(Searcher &searcher) { return; empty_sc.target_sp = m_target_sp; - if (searcher.GetDepth() == Searcher::eDepthTarget) + if (searcher.GetDepth() == lldb::eSearchDepthTarget) searcher.SearchCallback(*this, empty_sc, nullptr, false); else DoModuleIteration(empty_sc, searcher); @@ -220,7 +230,7 @@ void SearchFilter::SearchInModuleList(Searcher &searcher, ModuleList &modules) { return; empty_sc.target_sp = m_target_sp; - if (searcher.GetDepth() == Searcher::eDepthTarget) + if (searcher.GetDepth() == lldb::eSearchDepthTarget) searcher.SearchCallback(*this, empty_sc, nullptr, false); else { std::lock_guard guard(modules.GetMutex()); @@ -247,9 +257,9 @@ SearchFilter::DoModuleIteration(const lldb::ModuleSP &module_sp, Searcher::CallbackReturn SearchFilter::DoModuleIteration(const SymbolContext &context, Searcher &searcher) { - if (searcher.GetDepth() >= Searcher::eDepthModule) { + if (searcher.GetDepth() >= lldb::eSearchDepthModule) { if (context.module_sp) { - if (searcher.GetDepth() == Searcher::eDepthModule) { + if (searcher.GetDepth() == lldb::eSearchDepthModule) { SymbolContext matchingContext(context.module_sp.get()); searcher.SearchCallback(*this, matchingContext, nullptr, false); } else { @@ -267,7 +277,7 @@ SearchFilter::DoModuleIteration(const SymbolContext &context, if (!ModulePasses(module_sp)) continue; - if (searcher.GetDepth() == Searcher::eDepthModule) { + if (searcher.GetDepth() == lldb::eSearchDepthModule) { SymbolContext matchingContext(m_target_sp, module_sp); Searcher::CallbackReturn shouldContinue = @@ -301,7 +311,7 @@ SearchFilter::DoCUIteration(const ModuleSP &module_sp, if (!CompUnitPasses(*(cu_sp.get()))) continue; - if (searcher.GetDepth() == Searcher::eDepthCompUnit) { + if (searcher.GetDepth() == lldb::eSearchDepthCompUnit) { SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get()); shouldContinue = @@ -312,7 +322,30 @@ SearchFilter::DoCUIteration(const ModuleSP &module_sp, else if (shouldContinue == Searcher::eCallbackReturnStop) return shouldContinue; } else { - // FIXME Descend to block. + // First make sure this compile unit's functions are parsed + // since CompUnit::ForeachFunction only iterates over already + // parsed functions. + SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); + if (!sym_vendor) + continue; + if (!sym_vendor->ParseFunctions(*cu_sp)) + continue; + // If we got any functions, use ForeachFunction to do the iteration. + cu_sp->ForeachFunction([&](const FunctionSP &func_sp) { + if (!FunctionPasses(*func_sp.get())) + return false; // Didn't pass the filter, just keep going. + if (searcher.GetDepth() == lldb::eSearchDepthFunction) { + SymbolContext matchingContext(m_target_sp, module_sp, + cu_sp.get(), func_sp.get()); + shouldContinue = searcher.SearchCallback(*this, + matchingContext, + nullptr, false); + } else { + shouldContinue = DoFunctionIteration(func_sp.get(), context, + searcher); + } + return shouldContinue != Searcher::eCallbackReturnContinue; + }); } } } @@ -353,10 +386,7 @@ SearchFilterForUnconstrainedSearches::SerializeToStructuredData() { bool SearchFilterForUnconstrainedSearches::ModulePasses( const FileSpec &module_spec) { - if (m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_spec)) - return false; - else - return true; + return !m_target_sp->ModuleIsExcludedForUnconstrainedSearches(module_spec); } bool SearchFilterForUnconstrainedSearches::ModulePasses( @@ -421,7 +451,7 @@ void SearchFilterByModule::Search(Searcher &searcher) { if (!m_target_sp) return; - if (searcher.GetDepth() == Searcher::eDepthTarget) { + if (searcher.GetDepth() == lldb::eSearchDepthTarget) { SymbolContext empty_sc; empty_sc.target_sp = m_target_sp; searcher.SearchCallback(*this, empty_sc, nullptr, false); @@ -489,7 +519,7 @@ SearchFilterSP SearchFilterByModule::CreateFromStructuredData( error.SetErrorString("SFBM::CFSD: filter module item not a string."); return nullptr; } - FileSpec module_spec(module, false); + FileSpec module_spec(module); return std::make_shared(target.shared_from_this(), module_spec); @@ -535,22 +565,15 @@ bool SearchFilterByModuleList::ModulePasses(const ModuleSP &module_sp) { if (m_module_spec_list.GetSize() == 0) return true; - if (module_sp && - m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != - UINT32_MAX) - return true; - else - return false; + return module_sp && m_module_spec_list.FindFileIndex( + 0, module_sp->GetFileSpec(), false) != UINT32_MAX; } bool SearchFilterByModuleList::ModulePasses(const FileSpec &spec) { if (m_module_spec_list.GetSize() == 0) return true; - if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX) - return true; - else - return false; + return m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX; } bool SearchFilterByModuleList::AddressPasses(Address &address) { @@ -570,7 +593,7 @@ void SearchFilterByModuleList::Search(Searcher &searcher) { if (!m_target_sp) return; - if (searcher.GetDepth() == Searcher::eDepthTarget) { + if (searcher.GetDepth() == lldb::eSearchDepthTarget) { SymbolContext empty_sc; empty_sc.target_sp = m_target_sp; searcher.SearchCallback(*this, empty_sc, nullptr, false); @@ -645,7 +668,7 @@ SearchFilterSP SearchFilterByModuleList::CreateFromStructuredData( "SFBM::CFSD: filter module item %zu not a string.", i); return nullptr; } - modules.Append(FileSpec(module, false)); + modules.Append(FileSpec(module)); } } @@ -710,7 +733,7 @@ lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData( "SFBM::CFSD: filter module item %zu not a string.", i); return result_sp; } - modules.Append(FileSpec(module, false)); + modules.Append(FileSpec(module)); } } @@ -732,7 +755,7 @@ lldb::SearchFilterSP SearchFilterByModuleListAndCU::CreateFromStructuredData( "SFBM::CFSD: filter cu item %zu not a string.", i); return nullptr; } - cus.Append(FileSpec(cu, false)); + cus.Append(FileSpec(cu)); } return std::make_shared( @@ -748,7 +771,15 @@ SearchFilterByModuleListAndCU::SerializeToStructuredData() { } bool SearchFilterByModuleListAndCU::AddressPasses(Address &address) { - return true; + SymbolContext sym_ctx; + address.CalculateSymbolContext(&sym_ctx, eSymbolContextEverything); + if (!sym_ctx.comp_unit) { + if (m_cu_spec_list.GetSize() != 0) + return false; // Has no comp_unit so can't pass the file check. + } + if (m_cu_spec_list.FindFileIndex(0, sym_ctx.comp_unit, false) == UINT32_MAX) + return false; // Fails the file check + return SearchFilterByModuleList::ModulePasses(sym_ctx.module_sp); } bool SearchFilterByModuleListAndCU::CompUnitPasses(FileSpec &fileSpec) { @@ -773,7 +804,7 @@ void SearchFilterByModuleListAndCU::Search(Searcher &searcher) { if (!m_target_sp) return; - if (searcher.GetDepth() == Searcher::eDepthTarget) { + if (searcher.GetDepth() == lldb::eSearchDepthTarget) { SymbolContext empty_sc; empty_sc.target_sp = m_target_sp; searcher.SearchCallback(*this, empty_sc, nullptr, false); @@ -797,7 +828,7 @@ void SearchFilterByModuleListAndCU::Search(Searcher &searcher) { SymbolContext matchingContext(m_target_sp, module_sp); Searcher::CallbackReturn shouldContinue; - if (searcher.GetDepth() == Searcher::eDepthModule) { + if (searcher.GetDepth() == lldb::eSearchDepthModule) { shouldContinue = DoModuleIteration(matchingContext, searcher); if (shouldContinue == Searcher::eCallbackReturnStop) return; diff --git a/contrib/llvm/tools/lldb/source/Core/Section.cpp b/contrib/llvm/tools/lldb/source/Core/Section.cpp index d9c5d32ee13c..87f75e1f50ac 100644 --- a/contrib/llvm/tools/lldb/source/Core/Section.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Section.cpp @@ -8,18 +8,18 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/Section.h" -#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Address.h" #include "lldb/Core/Module.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/FileSpec.h" // for FileSpec -#include "lldb/Utility/Stream.h" // for Stream -#include "lldb/Utility/VMRange.h" // for VMRange +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Stream.h" +#include "lldb/Utility/VMRange.h" -#include // for PRIx64 -#include // for numeric_limits -#include // for distance +#include +#include +#include namespace lldb_private { class DataExtractor; @@ -61,6 +61,8 @@ const char *Section::GetTypeAsCString() const { return "objc-cfstrings"; case eSectionTypeDWARFDebugAbbrev: return "dwarf-abbrev"; + case eSectionTypeDWARFDebugAbbrevDwo: + return "dwarf-abbrev-dwo"; case eSectionTypeDWARFDebugAddr: return "dwarf-addr"; case eSectionTypeDWARFDebugAranges: @@ -71,10 +73,16 @@ const char *Section::GetTypeAsCString() const { return "dwarf-frame"; case eSectionTypeDWARFDebugInfo: return "dwarf-info"; + case eSectionTypeDWARFDebugInfoDwo: + return "dwarf-info-dwo"; case eSectionTypeDWARFDebugLine: return "dwarf-line"; + case eSectionTypeDWARFDebugLineStr: + return "dwarf-line-str"; case eSectionTypeDWARFDebugLoc: return "dwarf-loc"; + case eSectionTypeDWARFDebugLocLists: + return "dwarf-loclists"; case eSectionTypeDWARFDebugMacInfo: return "dwarf-macinfo"; case eSectionTypeDWARFDebugMacro: @@ -85,10 +93,16 @@ const char *Section::GetTypeAsCString() const { return "dwarf-pubtypes"; case eSectionTypeDWARFDebugRanges: return "dwarf-ranges"; + case eSectionTypeDWARFDebugRngLists: + return "dwarf-rnglists"; case eSectionTypeDWARFDebugStr: return "dwarf-str"; + case eSectionTypeDWARFDebugStrDwo: + return "dwarf-str-dwo"; case eSectionTypeDWARFDebugStrOffsets: return "dwarf-str-offsets"; + case eSectionTypeDWARFDebugStrOffsetsDwo: + return "dwarf-str-offsets-dwo"; case eSectionTypeDWARFDebugTypes: return "dwarf-types"; case eSectionTypeDWARFDebugNames: diff --git a/contrib/llvm/tools/lldb/source/Core/SourceManager.cpp b/contrib/llvm/tools/lldb/source/Core/SourceManager.cpp index a6afd64f3054..fe603c5a44e6 100644 --- a/contrib/llvm/tools/lldb/source/Core/SourceManager.cpp +++ b/contrib/llvm/tools/lldb/source/Core/SourceManager.cpp @@ -9,33 +9,34 @@ #include "lldb/Core/SourceManager.h" -#include "lldb/Core/Address.h" // for Address -#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/FormatEntity.h" // for FormatEntity +#include "lldb/Core/FormatEntity.h" +#include "lldb/Core/Highlighter.h" #include "lldb/Core/Module.h" -#include "lldb/Core/ModuleList.h" // for ModuleList +#include "lldb/Core/ModuleList.h" #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" -#include "lldb/Symbol/LineEntry.h" // for LineEntry +#include "lldb/Symbol/LineEntry.h" #include "lldb/Symbol/SymbolContext.h" -#include "lldb/Target/PathMappingList.h" // for PathMappingList +#include "lldb/Target/PathMappingList.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Stream.h" -#include "lldb/lldb-enumerations.h" // for StopShowColumn::eStopSho... +#include "lldb/lldb-enumerations.h" -#include "llvm/ADT/Twine.h" // for Twine +#include "llvm/ADT/Twine.h" #include -#include // for pair +#include -#include // for assert -#include // for size_t, NULL, snprintf +#include +#include namespace lldb_private { class ExecutionContext; @@ -91,7 +92,7 @@ SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { file_sp->UpdateIfNeeded(); // If file_sp is no good or it points to a non-existent file, reset it. - if (!file_sp || !file_sp->GetFileSpec().Exists()) { + if (!file_sp || !FileSystem::Instance().Exists(file_sp->GetFileSpec())) { if (target_sp) file_sp = std::make_shared(file_spec, target_sp.get()); else @@ -103,6 +104,18 @@ SourceManager::FileSP SourceManager::GetFile(const FileSpec &file_spec) { return file_sp; } +static bool should_highlight_source(DebuggerSP debugger_sp) { + if (!debugger_sp) + return false; + + // We don't use ANSI stop column formatting if the debugger doesn't think it + // should be using color. + if (!debugger_sp->GetUseColor()) + return false; + + return debugger_sp->GetHighlightSource(); +} + static bool should_show_stop_column_with_ansi(DebuggerSP debugger_sp) { // We don't use ANSI stop column formatting if we can't lookup values from // the debugger. @@ -145,7 +158,9 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( const SymbolContextList *bp_locs) { if (count == 0) return 0; - size_t return_value = 0; + + Stream::ByteDelta delta(*s); + if (start_line == 0) { if (m_last_line != 0 && m_last_line != UINT32_MAX) start_line = m_last_line + m_last_count; @@ -180,31 +195,37 @@ size_t SourceManager::DisplaySourceLinesWithLineNumbersUsingLastFile( ::snprintf(prefix, sizeof(prefix), " "); } - return_value += - s->Printf("%s%2.2s %-4u\t", prefix, - line == curr_line ? current_line_cstr : "", line); - size_t this_line_size = m_last_file_sp->DisplaySourceLines( - line, line == curr_line ? column : 0, 0, 0, s); + s->Printf("%s%2.2s %-4u\t", prefix, + line == curr_line ? current_line_cstr : "", line); + + // So far we treated column 0 as a special 'no column value', but + // DisplaySourceLines starts counting columns from 0 (and no column is + // expressed by passing an empty optional). + llvm::Optional columnToHighlight; + if (line == curr_line && column) + columnToHighlight = column - 1; + + size_t this_line_size = + m_last_file_sp->DisplaySourceLines(line, columnToHighlight, 0, 0, s); if (column != 0 && line == curr_line && should_show_stop_column_with_caret(m_debugger_wp.lock())) { // Display caret cursor. std::string src_line; m_last_file_sp->GetLine(line, src_line); - return_value += s->Printf(" \t"); + s->Printf(" \t"); // Insert a space for every non-tab character in the source line. for (size_t i = 0; i + 1 < column && i < src_line.length(); ++i) - return_value += s->PutChar(src_line[i] == '\t' ? '\t' : ' '); + s->PutChar(src_line[i] == '\t' ? '\t' : ' '); // Now add the caret. - return_value += s->Printf("^\n"); + s->Printf("^\n"); } if (this_line_size == 0) { m_last_line = UINT32_MAX; break; - } else - return_value += this_line_size; + } } } - return return_value; + return *delta; } size_t SourceManager::DisplaySourceLinesWithLineNumbers( @@ -349,14 +370,14 @@ void SourceManager::FindLinesMatchingRegex(FileSpec &file_spec, SourceManager::File::File(const FileSpec &file_spec, lldb::DebuggerSP debugger_sp) : m_file_spec_orig(file_spec), m_file_spec(file_spec), - m_mod_time(FileSystem::GetModificationTime(file_spec)), + m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), m_debugger_wp(debugger_sp) { CommonInitializer(file_spec, nullptr); } SourceManager::File::File(const FileSpec &file_spec, Target *target) : m_file_spec_orig(file_spec), m_file_spec(file_spec), - m_mod_time(FileSystem::GetModificationTime(file_spec)), + m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), m_debugger_wp(target ? target->GetDebugger().shared_from_this() : DebuggerSP()) { CommonInitializer(file_spec, target); @@ -376,7 +397,8 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath( file_spec.GetFilename().AsCString(), 0, check_inlines, - lldb::eSymbolContextModule | lldb::eSymbolContextCompUnit, + SymbolContextItem(eSymbolContextModule | + eSymbolContextCompUnit), sc_list); bool got_multiple = false; if (num_matches != 0) { @@ -400,12 +422,12 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, SymbolContext sc; sc_list.GetContextAtIndex(0, sc); m_file_spec = sc.comp_unit; - m_mod_time = FileSystem::GetModificationTime(m_file_spec); + m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); } } } // Try remapping if m_file_spec does not correspond to an existing file. - if (!m_file_spec.Exists()) { + if (!FileSystem::Instance().Exists(m_file_spec)) { FileSpec new_file_spec; // Check target specific source remappings first, then fall back to // modules objects can have individual path remappings that were @@ -413,14 +435,14 @@ void SourceManager::File::CommonInitializer(const FileSpec &file_spec, if (target->GetSourcePathMap().FindFile(m_file_spec, new_file_spec) || target->GetImages().FindSourceFile(m_file_spec, new_file_spec)) { m_file_spec = new_file_spec; - m_mod_time = FileSystem::GetModificationTime(m_file_spec); + m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); } } } } if (m_mod_time != llvm::sys::TimePoint<>()) - m_data_sp = DataBufferLLVM::CreateFromPath(m_file_spec.GetPath()); + m_data_sp = FileSystem::Instance().CreateDataBuffer(m_file_spec); } uint32_t SourceManager::File::GetLineOffset(uint32_t line) { @@ -464,7 +486,7 @@ uint32_t SourceManager::File::GetLineLength(uint32_t line, if (end_offset > start_offset) { uint32_t length = end_offset - start_offset; - if (include_newline_chars == false) { + if (!include_newline_chars) { const char *line_start = (const char *)m_data_sp->GetBytes() + start_offset; while (length > 0) { @@ -493,17 +515,18 @@ void SourceManager::File::UpdateIfNeeded() { // TODO: use host API to sign up for file modifications to anything in our // source cache and only update when we determine a file has been updated. // For now we check each time we want to display info for the file. - auto curr_mod_time = FileSystem::GetModificationTime(m_file_spec); + auto curr_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec); if (curr_mod_time != llvm::sys::TimePoint<>() && m_mod_time != curr_mod_time) { m_mod_time = curr_mod_time; - m_data_sp = DataBufferLLVM::CreateFromPath(m_file_spec.GetPath()); + m_data_sp = FileSystem::Instance().CreateDataBuffer(m_file_spec); m_offsets.clear(); } } -size_t SourceManager::File::DisplaySourceLines(uint32_t line, uint32_t column, +size_t SourceManager::File::DisplaySourceLines(uint32_t line, + llvm::Optional column, uint32_t context_before, uint32_t context_after, Stream *s) { @@ -515,6 +538,27 @@ size_t SourceManager::File::DisplaySourceLines(uint32_t line, uint32_t column, if (!m_data_sp) return 0; + size_t bytes_written = s->GetWrittenBytes(); + + auto debugger_sp = m_debugger_wp.lock(); + + HighlightStyle style; + // Use the default Vim style if source highlighting is enabled. + if (should_highlight_source(debugger_sp)) + style = HighlightStyle::MakeVimStyle(); + + // If we should mark the stop column with color codes, then copy the prefix + // and suffix to our color style. + if (should_show_stop_column_with_ansi(debugger_sp)) + style.selected.Set(debugger_sp->GetStopShowColumnAnsiPrefix(), + debugger_sp->GetStopShowColumnAnsiSuffix()); + + HighlighterManager mgr; + std::string path = GetFileSpec().GetPath(/*denormalize*/ false); + // FIXME: Find a way to get the definitive language this file was written in + // and pass it to the highlighter. + const auto &h = mgr.getHighlighterFor(lldb::eLanguageTypeUnknown, path); + const uint32_t start_line = line <= context_before ? 1 : line - context_before; const uint32_t start_line_offset = GetLineOffset(start_line); @@ -525,71 +569,20 @@ size_t SourceManager::File::DisplaySourceLines(uint32_t line, uint32_t column, end_line_offset = m_data_sp->GetByteSize(); assert(start_line_offset <= end_line_offset); - size_t bytes_written = 0; if (start_line_offset < end_line_offset) { size_t count = end_line_offset - start_line_offset; const uint8_t *cstr = m_data_sp->GetBytes() + start_line_offset; - bool displayed_line = false; + auto ref = llvm::StringRef(reinterpret_cast(cstr), count); - if (column && (column < count)) { - auto debugger_sp = m_debugger_wp.lock(); - if (should_show_stop_column_with_ansi(debugger_sp) && debugger_sp) { - // Check if we have any ANSI codes with which to mark this column. If - // not, no need to do this work. - auto ansi_prefix_entry = debugger_sp->GetStopShowColumnAnsiPrefix(); - auto ansi_suffix_entry = debugger_sp->GetStopShowColumnAnsiSuffix(); - - // We only bother breaking up the line to format the marked column if - // there is any marking specified on both sides of the marked column. - // In ANSI-terminal-sequence land, there must be a post if there is a - // pre format, and vice versa. - if (ansi_prefix_entry && ansi_suffix_entry) { - // Mark the current column with the desired escape sequence for - // formatting the column (e.g. underline, inverse, etc.) - - // First print the part before the column to mark. - bytes_written = s->Write(cstr, column - 1); - - // Write the pre escape sequence. - const SymbolContext *sc = nullptr; - const ExecutionContext *exe_ctx = nullptr; - const Address addr = LLDB_INVALID_ADDRESS; - ValueObject *valobj = nullptr; - const bool function_changed = false; - const bool initial_function = false; - - FormatEntity::Format(*ansi_prefix_entry, *s, sc, exe_ctx, &addr, - valobj, function_changed, initial_function); - - // Write the marked column. - bytes_written += s->Write(cstr + column - 1, 1); - - // Write the post escape sequence. - FormatEntity::Format(*ansi_suffix_entry, *s, sc, exe_ctx, &addr, - valobj, function_changed, initial_function); - - // And finish up with the rest of the line. - bytes_written += s->Write(cstr + column, count - column); - - // Keep track of the fact that we just wrote the line. - displayed_line = true; - } - } - } - - // If we didn't end up displaying the line with ANSI codes for whatever - // reason, display it now sans codes. - if (!displayed_line) - bytes_written = s->Write(cstr, count); + h.Highlight(style, ref, column, "", *s); // Ensure we get an end of line character one way or another. - if (!is_newline_char(cstr[count - 1])) - bytes_written += s->EOL(); + if (!is_newline_char(ref.back())) + s->EOL(); } - return bytes_written; } - return 0; + return s->GetWrittenBytes() - bytes_written; } void SourceManager::File::FindLinesMatchingRegex( diff --git a/contrib/llvm/tools/lldb/source/Core/StreamAsynchronousIO.cpp b/contrib/llvm/tools/lldb/source/Core/StreamAsynchronousIO.cpp index aae8636bff09..b8938bd3fc4e 100644 --- a/contrib/llvm/tools/lldb/source/Core/StreamAsynchronousIO.cpp +++ b/contrib/llvm/tools/lldb/source/Core/StreamAsynchronousIO.cpp @@ -10,7 +10,7 @@ #include "lldb/Core/StreamAsynchronousIO.h" #include "lldb/Core/Debugger.h" -#include "lldb/lldb-enumerations.h" // for ByteOrder::eByteOrderBig +#include "lldb/lldb-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -31,7 +31,7 @@ void StreamAsynchronousIO::Flush() { } } -size_t StreamAsynchronousIO::Write(const void *s, size_t length) { +size_t StreamAsynchronousIO::WriteImpl(const void *s, size_t length) { m_data.append((const char *)s, length); return length; } diff --git a/contrib/llvm/tools/lldb/source/Core/StreamFile.cpp b/contrib/llvm/tools/lldb/source/Core/StreamFile.cpp index f59415485021..d24634598c36 100644 --- a/contrib/llvm/tools/lldb/source/Core/StreamFile.cpp +++ b/contrib/llvm/tools/lldb/source/Core/StreamFile.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/StreamFile.h" +#include "lldb/Host/FileSystem.h" #include @@ -28,20 +29,24 @@ StreamFile::StreamFile(int fd, bool transfer_ownership) StreamFile::StreamFile(FILE *fh, bool transfer_ownership) : Stream(), m_file(fh, transfer_ownership) {} -StreamFile::StreamFile(const char *path) - : Stream(), - m_file(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate | - File::eOpenOptionCloseOnExec, - lldb::eFilePermissionsFileDefault) {} +StreamFile::StreamFile(const char *path) : Stream(), m_file() { + FileSystem::Instance().Open(m_file, FileSpec(path), + File::eOpenOptionWrite | + File::eOpenOptionCanCreate | + File::eOpenOptionCloseOnExec); +} StreamFile::StreamFile(const char *path, uint32_t options, uint32_t permissions) - : Stream(), m_file(path, options, permissions) {} + : Stream(), m_file() { + + FileSystem::Instance().Open(m_file, FileSpec(path), options, permissions); +} StreamFile::~StreamFile() {} void StreamFile::Flush() { m_file.Flush(); } -size_t StreamFile::Write(const void *s, size_t length) { +size_t StreamFile::WriteImpl(const void *s, size_t length) { m_file.Write(s, length); return length; } diff --git a/contrib/llvm/tools/lldb/source/Core/UserSettingsController.cpp b/contrib/llvm/tools/lldb/source/Core/UserSettingsController.cpp index a4661a6c9e8c..4406057ca6b9 100644 --- a/contrib/llvm/tools/lldb/source/Core/UserSettingsController.cpp +++ b/contrib/llvm/tools/lldb/source/Core/UserSettingsController.cpp @@ -13,7 +13,7 @@ #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" -#include // for shared_ptr +#include namespace lldb_private { class CommandInterpreter; diff --git a/contrib/llvm/tools/lldb/source/Core/Value.cpp b/contrib/llvm/tools/lldb/source/Core/Value.cpp index 254c9008babb..8e18458b90c2 100644 --- a/contrib/llvm/tools/lldb/source/Core/Value.cpp +++ b/contrib/llvm/tools/lldb/source/Core/Value.cpp @@ -9,9 +9,8 @@ #include "lldb/Core/Value.h" -#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Address.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" @@ -21,20 +20,21 @@ #include "lldb/Target/Process.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/ConstString.h" // for ConstString +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/Endian.h" // for InlHostByteOrder -#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-forward.h" // for DataBufferSP, ModuleSP -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" -#include // for make_shared -#include // for string +#include +#include -#include // for PRIx64 +#include using namespace lldb; using namespace lldb_private; @@ -210,34 +210,31 @@ bool Value::ValueOf(ExecutionContext *exe_ctx) { } uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) { - uint64_t byte_size = 0; - switch (m_context_type) { case eContextTypeRegisterInfo: // RegisterInfo * - if (GetRegisterInfo()) - byte_size = GetRegisterInfo()->byte_size; + if (GetRegisterInfo()) { + if (error_ptr) + error_ptr->Clear(); + return GetRegisterInfo()->byte_size; + } break; case eContextTypeInvalid: case eContextTypeLLDBType: // Type * case eContextTypeVariable: // Variable * { - const CompilerType &ast_type = GetCompilerType(); - if (ast_type.IsValid()) - byte_size = ast_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); - } break; - } - - if (error_ptr) { - if (byte_size == 0) { - if (error_ptr->Success()) - error_ptr->SetErrorString("Unable to determine byte size."); - } else { - error_ptr->Clear(); + auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; + if (llvm::Optional size = GetCompilerType().GetByteSize(scope)) { + if (error_ptr) + error_ptr->Clear(); + return *size; } + break; } - return byte_size; + } + if (error_ptr && error_ptr->Success()) + error_ptr->SetErrorString("Unable to determine byte size."); + return 0; } const CompilerType &Value::GetCompilerType() { @@ -344,10 +341,9 @@ Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, uint32_t limit_byte_size = UINT32_MAX; - if (ast_type.IsValid()) { - limit_byte_size = ast_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); - } + if (llvm::Optional size = ast_type.GetByteSize( + exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)) + limit_byte_size = *size; if (limit_byte_size <= m_value.GetByteSize()) { if (m_value.GetData(data, limit_byte_size)) diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObject.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObject.cpp index 244ea2936fb4..95e944b22b87 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObject.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObject.cpp @@ -9,9 +9,8 @@ #include "lldb/Core/ValueObject.h" -#include "lldb/Core/Address.h" // for Address +#include "lldb/Core/Address.h" #include "lldb/Core/Module.h" -#include "lldb/Core/Scalar.h" // for Scalar #include "lldb/Core/ValueObjectCast.h" #include "lldb/Core/ValueObjectChild.h" #include "lldb/Core/ValueObjectConstResult.h" @@ -19,51 +18,52 @@ #include "lldb/Core/ValueObjectMemory.h" #include "lldb/Core/ValueObjectSyntheticFilter.h" #include "lldb/DataFormatters/DataVisualization.h" -#include "lldb/DataFormatters/DumpValueObjectOptions.h" // for DumpValueObj... -#include "lldb/DataFormatters/FormatManager.h" // for FormatManager +#include "lldb/DataFormatters/DumpValueObjectOptions.h" +#include "lldb/DataFormatters/FormatManager.h" #include "lldb/DataFormatters/StringPrinter.h" -#include "lldb/DataFormatters/TypeFormat.h" // for TypeFormatImpl_F... -#include "lldb/DataFormatters/TypeSummary.h" // for TypeSummaryOptions -#include "lldb/DataFormatters/TypeValidator.h" // for TypeValidatorImp... +#include "lldb/DataFormatters/TypeFormat.h" +#include "lldb/DataFormatters/TypeSummary.h" +#include "lldb/DataFormatters/TypeValidator.h" #include "lldb/DataFormatters/ValueObjectPrinter.h" -#include "lldb/Expression/ExpressionVariable.h" // for ExpressionVariable +#include "lldb/Expression/ExpressionVariable.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/Declaration.h" // for Declaration -#include "lldb/Symbol/SymbolContext.h" // for SymbolContext +#include "lldb/Symbol/Declaration.h" +#include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/Type.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Language.h" #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" -#include "lldb/Target/StackFrame.h" // for StackFrame +#include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" -#include "lldb/Target/ThreadList.h" // for ThreadList -#include "lldb/Utility/DataBuffer.h" // for DataBuffer +#include "lldb/Target/ThreadList.h" +#include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/Flags.h" // for Flags +#include "lldb/Utility/Flags.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for GetLogIfAllCateg... -#include "lldb/Utility/SharingPtr.h" // for SharingPtr -#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/SharingPtr.h" +#include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" -#include "lldb/lldb-private-types.h" // for RegisterInfo +#include "lldb/lldb-private-types.h" -#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH +#include "llvm/Support/Compiler.h" -#include // for min -#include // for uint32_t, uint64_t -#include // for size_t, NULL -#include // for shared_ptr, oper... -#include // for tie, tuple +#include +#include +#include +#include +#include -#include // for assert -#include // for PRIu64, PRIx64 -#include // for snprintf -#include // for memcpy, memcmp +#include +#include +#include +#include namespace lldb_private { class ExecutionContextScope; @@ -214,7 +214,7 @@ bool ValueObject::UpdateValueIfNeeded(bool update_format) { if (first_update) SetValueDidChange(false); - else if (!m_value_did_change && success == false) { + else if (!m_value_did_change && !success) { // The value wasn't gotten successfully, so we mark this as changed if // the value used to be valid and now isn't SetValueDidChange(value_was_valid); @@ -442,10 +442,7 @@ bool ValueObject::IsLogicalTrue(Status &error) { } bool ret; - if (scalar_value.ULongLong(1) == 0) - ret = false; - else - ret = true; + ret = scalar_value.ULongLong(1) != 0; error.Clear(); return ret; } @@ -639,7 +636,7 @@ ValueObject *ValueObject::CreateChildAtIndex(size_t idx, bool child_is_deref_of_parent = false; uint64_t language_flags = 0; - const bool transparent_pointers = synthetic_array_member == false; + const bool transparent_pointers = !synthetic_array_member; CompilerType child_compiler_type; ExecutionContext exe_ctx(GetExecutionContextRef()); @@ -662,8 +659,6 @@ ValueObject *ValueObject::CreateChildAtIndex(size_t idx, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, eAddressTypeInvalid, language_flags); - // if (valobj) - // valobj->SetAddressTypeOfChildren(eAddressTypeInvalid); } return valobj; @@ -761,10 +756,13 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx, ExecutionContext exe_ctx(GetExecutionContextRef()); - const uint64_t item_type_size = pointee_or_element_compiler_type.GetByteSize( - exe_ctx.GetBestExecutionContextScope()); - const uint64_t bytes = item_count * item_type_size; - const uint64_t offset = item_idx * item_type_size; + llvm::Optional item_type_size = + pointee_or_element_compiler_type.GetByteSize( + exe_ctx.GetBestExecutionContextScope()); + if (!item_type_size) + return 0; + const uint64_t bytes = item_count * *item_type_size; + const uint64_t offset = item_idx * *item_type_size; if (item_idx == 0 && item_count == 1) // simply a deref { @@ -827,10 +825,10 @@ size_t ValueObject::GetPointeeData(DataExtractor &data, uint32_t item_idx, } } break; case eAddressTypeHost: { - const uint64_t max_bytes = + auto max_bytes = GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope()); - if (max_bytes > offset) { - size_t bytes_read = std::min(max_bytes - offset, bytes); + if (max_bytes && *max_bytes > offset) { + size_t bytes_read = std::min(*max_bytes - offset, bytes); addr = m_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); if (addr == 0 || addr == LLDB_INVALID_ADDRESS) break; @@ -1823,14 +1821,16 @@ ValueObjectSP ValueObject::GetSyntheticChildAtOffset( return synthetic_child_sp; if (!can_create) - return ValueObjectSP(); + return {}; ExecutionContext exe_ctx(GetExecutionContextRef()); - - ValueObjectChild *synthetic_child = new ValueObjectChild( - *this, type, name_const_str, - type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0, - false, false, eAddressTypeInvalid, 0); + llvm::Optional size = + type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); + if (!size) + return {}; + ValueObjectChild *synthetic_child = + new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0, + false, false, eAddressTypeInvalid, 0); if (synthetic_child) { AddSyntheticChild(name_const_str, synthetic_child); synthetic_child_sp = synthetic_child->GetSP(); @@ -1861,16 +1861,18 @@ ValueObjectSP ValueObject::GetSyntheticBase(uint32_t offset, return synthetic_child_sp; if (!can_create) - return ValueObjectSP(); + return {}; const bool is_base_class = true; ExecutionContext exe_ctx(GetExecutionContextRef()); - - ValueObjectChild *synthetic_child = new ValueObjectChild( - *this, type, name_const_str, - type.GetByteSize(exe_ctx.GetBestExecutionContextScope()), offset, 0, 0, - is_base_class, false, eAddressTypeInvalid, 0); + llvm::Optional size = + type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); + if (!size) + return {}; + ValueObjectChild *synthetic_child = + new ValueObjectChild(*this, type, name_const_str, *size, offset, 0, 0, + is_base_class, false, eAddressTypeInvalid, 0); if (synthetic_child) { AddSyntheticChild(name_const_str, synthetic_child); synthetic_child_sp = synthetic_child->GetSP(); @@ -1923,11 +1925,11 @@ ValueObject::GetSyntheticExpressionPathChild(const char *expression, } void ValueObject::CalculateSyntheticValue(bool use_synthetic) { - if (use_synthetic == false) + if (!use_synthetic) return; TargetSP target_sp(GetTargetSP()); - if (target_sp && target_sp->GetEnableSyntheticValue() == false) { + if (target_sp && !target_sp->GetEnableSyntheticValue()) { m_synthetic_value = NULL; return; } @@ -1978,7 +1980,7 @@ ValueObjectSP ValueObject::GetStaticValue() { return GetSP(); } lldb::ValueObjectSP ValueObject::GetNonSyntheticValue() { return GetSP(); } ValueObjectSP ValueObject::GetSyntheticValue(bool use_synthetic) { - if (use_synthetic == false) + if (!use_synthetic) return ValueObjectSP(); CalculateSyntheticValue(use_synthetic); @@ -1997,10 +1999,7 @@ bool ValueObject::HasSyntheticValue() { CalculateSyntheticValue(true); - if (m_synthetic_value) - return true; - else - return false; + return m_synthetic_value != nullptr; } bool ValueObject::GetBaseClassPath(Stream &s) { @@ -2806,31 +2805,6 @@ ValueObjectSP ValueObject::GetQualifiedRepresentationIfAvailable( return result_sp; } -lldb::addr_t ValueObject::GetCPPVTableAddress(AddressType &address_type) { - CompilerType pointee_type; - CompilerType this_type(GetCompilerType()); - uint32_t type_info = this_type.GetTypeInfo(&pointee_type); - if (type_info) { - bool ptr_or_ref = false; - if (type_info & (eTypeIsPointer | eTypeIsReference)) { - ptr_or_ref = true; - type_info = pointee_type.GetTypeInfo(); - } - - const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus; - if ((type_info & cpp_class) == cpp_class) { - if (ptr_or_ref) { - address_type = GetAddressTypeOfChildren(); - return GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - } else - return GetAddressOf(false, &address_type); - } - } - - address_type = eAddressTypeInvalid; - return LLDB_INVALID_ADDRESS; -} - ValueObjectSP ValueObject::Dereference(Status &error) { if (m_deref_valobj) return m_deref_valobj->GetSP(); @@ -3222,7 +3196,7 @@ ValueObject * ValueObject::FollowParentChain(std::function f) { ValueObject *vo = this; while (vo) { - if (f(vo) == false) + if (!f(vo)) break; vo = vo->m_parent; } @@ -3291,8 +3265,7 @@ bool ValueObject::CanProvideValue() { // board debugging scenarios have no notion of types, but still manage to // have raw numeric values for things like registers. sigh. const CompilerType &type(GetCompilerType()); - return (false == type.IsValid()) || - (0 != (type.GetTypeInfo() & eTypeHasValue)); + return (!type.IsValid()) || (0 != (type.GetTypeInfo() & eTypeHasValue)); } bool ValueObject::IsChecksumEmpty() { return m_value_checksum.empty(); } diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectCast.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectCast.cpp index e0978f692bc5..fb0b55b6efdf 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectCast.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectCast.cpp @@ -9,12 +9,12 @@ #include "lldb/Core/ValueObjectCast.h" -#include "lldb/Core/Scalar.h" // for operator!=, Scalar #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Utility/Status.h" // for Status +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/Status.h" namespace lldb_private { class ConstString; @@ -44,7 +44,9 @@ ValueObjectCast::~ValueObjectCast() {} CompilerType ValueObjectCast::GetCompilerTypeImpl() { return m_cast_type; } size_t ValueObjectCast::CalculateNumChildren(uint32_t max) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren( + true, &exe_ctx); return children_count <= max ? children_count : max; } diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectChild.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectChild.cpp index 019daa2fd3d2..0f7be8317dec 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectChild.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectChild.cpp @@ -9,21 +9,21 @@ #include "lldb/Core/ValueObjectChild.h" -#include "lldb/Core/Scalar.h" // for Scalar -#include "lldb/Core/Value.h" // for Value, Value::ValueType::e... +#include "lldb/Core/Value.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" -#include "lldb/Utility/Flags.h" // for Flags -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-forward.h" // for ProcessSP, ModuleSP +#include "lldb/Utility/Flags.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-forward.h" -#include // for _Func_impl<>::_Mybase -#include // for shared_ptr -#include // for vector +#include +#include +#include -#include // for snprintf, size_t -#include // for strlen +#include +#include using namespace lldb_private; @@ -51,7 +51,8 @@ lldb::ValueType ValueObjectChild::GetValueType() const { } size_t ValueObjectChild::CalculateNumChildren(uint32_t max) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); return children_count <= max ? children_count : max; } @@ -123,7 +124,7 @@ bool ValueObjectChild::UpdateValue() { Flags parent_type_flags(parent_type.GetTypeInfo()); const bool is_instance_ptr_base = - ((m_is_base_class == true) && + ((m_is_base_class) && (parent_type_flags.AnySet(lldb::eTypeInstanceIsPointer))); if (parent->GetCompilerType().ShouldTreatScalarValueAsAddress()) { @@ -141,7 +142,7 @@ bool ValueObjectChild::UpdateValue() { switch (addr_type) { case eAddressTypeFile: { lldb::ProcessSP process_sp(GetProcessSP()); - if (process_sp && process_sp->IsAlive() == true) + if (process_sp && process_sp->IsAlive()) m_value.SetValueType(Value::eValueTypeLoadAddress); else m_value.SetValueType(Value::eValueTypeFileAddress); @@ -201,12 +202,9 @@ bool ValueObjectChild::UpdateValue() { ExecutionContext exe_ctx( GetExecutionContextRef().Lock(thread_and_frame_only_if_stopped)); if (GetCompilerType().GetTypeInfo() & lldb::eTypeHasValue) { - if (!is_instance_ptr_base) - m_error = - m_value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); - else - m_error = m_parent->GetValue().GetValueAsData(&exe_ctx, m_data, 0, - GetModule().get()); + Value &value = is_instance_ptr_base ? m_parent->GetValue() : m_value; + m_error = + value.GetValueAsData(&exe_ctx, m_data, 0, GetModule().get()); } else { m_error.Clear(); // No value so nothing to read... } diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResult.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResult.cpp index 1023696c35a7..f6e32c03b0eb 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResult.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResult.cpp @@ -9,15 +9,15 @@ #include "lldb/Core/ValueObjectConstResult.h" -#include "lldb/Core/Scalar.h" // for Scalar #include "lldb/Core/ValueObjectDynamicValue.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/ExecutionContextScope.h" // for ExecutionContextScope +#include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Process.h" -#include "lldb/Utility/DataBuffer.h" // for DataBuffer -#include "lldb/Utility/DataBufferHeap.h" // for DataBufferHeap +#include "lldb/Utility/DataBuffer.h" +#include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" namespace lldb_private { class Module; @@ -198,17 +198,19 @@ lldb::ValueType ValueObjectConstResult::GetValueType() const { uint64_t ValueObjectConstResult::GetByteSize() { ExecutionContext exe_ctx(GetExecutionContextRef()); - - if (m_byte_size == 0) - SetByteSize( - GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope())); + if (m_byte_size == 0) { + if (auto size = + GetCompilerType().GetByteSize(exe_ctx.GetBestExecutionContextScope())) + SetByteSize(*size); + } return m_byte_size; } void ValueObjectConstResult::SetByteSize(size_t size) { m_byte_size = size; } size_t ValueObjectConstResult::CalculateNumChildren(uint32_t max) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); return children_count <= max ? children_count : max; } diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultChild.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultChild.cpp index 3e9f87684162..441c16479f2c 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultChild.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultChild.cpp @@ -9,7 +9,7 @@ #include "lldb/Core/ValueObjectConstResultChild.h" -#include "lldb/lldb-private-enumerations.h" // for AddressType::eAddressType +#include "lldb/lldb-private-enumerations.h" namespace lldb_private { class DataExtractor; } @@ -52,6 +52,11 @@ lldb::ValueObjectSP ValueObjectConstResultChild::AddressOf(Status &error) { return m_impl.AddressOf(error); } +lldb::addr_t ValueObjectConstResultChild::GetAddressOf( + bool scalar_is_load_address, AddressType* address_type) { + return m_impl.GetAddressOf(scalar_is_load_address, address_type); +} + ValueObject *ValueObjectConstResultChild::CreateChildAtIndex( size_t idx, bool synthetic_array_member, int32_t synthetic_index) { return m_impl.CreateChildAtIndex(idx, synthetic_array_member, diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultImpl.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultImpl.cpp index 714634ed56e3..6bf8e62db067 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultImpl.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectConstResultImpl.cpp @@ -9,19 +9,19 @@ #include "lldb/Core/ValueObjectConstResultImpl.h" -#include "lldb/Core/Scalar.h" // for Scalar -#include "lldb/Core/Value.h" // for Value, Value::Val... -#include "lldb/Core/ValueObject.h" // for ValueObject +#include "lldb/Core/Value.h" +#include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectConstResultCast.h" #include "lldb/Core/ValueObjectConstResultChild.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Target/ExecutionContext.h" -#include "lldb/Utility/DataBufferHeap.h" // for DataBufferHeap -#include "lldb/Utility/Endian.h" // for InlHostByteOrder -#include "lldb/Utility/SharingPtr.h" // for SharingPtr +#include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/Endian.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/SharingPtr.h" -#include // for string +#include namespace lldb_private { class DataExtractor; @@ -66,7 +66,7 @@ ValueObject *ValueObjectConstResultImpl::CreateChildAtIndex( bool child_is_deref_of_parent = false; uint64_t language_flags; - const bool transparent_pointers = synthetic_array_member == false; + const bool transparent_pointers = !synthetic_array_member; CompilerType compiler_type = m_impl_backend->GetCompilerType(); CompilerType child_compiler_type; @@ -77,7 +77,13 @@ ValueObject *ValueObjectConstResultImpl::CreateChildAtIndex( ignore_array_bounds, child_name_str, child_byte_size, child_byte_offset, child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, child_is_deref_of_parent, m_impl_backend, language_flags); - if (child_compiler_type && child_byte_size) { + + // One might think we should check that the size of the children + // is always strictly positive, hence we could avoid creating a + // ValueObject if that's not the case, but it turns out there + // are languages out there which allow zero-size types with + // children (e.g. Swift). + if (child_compiler_type) { if (synthetic_index) child_byte_offset += child_byte_size * synthetic_index; diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectDynamicValue.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectDynamicValue.cpp index e9b48310b0c6..161b6e49e0dd 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectDynamicValue.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectDynamicValue.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ValueObjectDynamicValue.h" -#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/CompilerType.h" @@ -17,13 +16,14 @@ #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/DataExtractor.h" // for DataExtractor +#include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-types.h" // for addr_t, offset_t +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-types.h" -#include // for strcmp, size_t +#include namespace lldb_private { class Declaration; } @@ -92,7 +92,8 @@ ConstString ValueObjectDynamicValue::GetDisplayTypeName() { size_t ValueObjectDynamicValue::CalculateNumChildren(uint32_t max) { const bool success = UpdateValueIfNeeded(false); if (success && m_dynamic_type_info.HasType()) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); return children_count <= max ? children_count : max; } else return m_parent->GetNumChildren(max); diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectList.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectList.cpp index 0dd07252888f..7a7e0d8417b7 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectList.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectList.cpp @@ -9,11 +9,11 @@ #include "lldb/Core/ValueObjectList.h" -#include "lldb/Core/ValueObject.h" // for ValueObject -#include "lldb/Utility/ConstString.h" // for ConstString -#include "lldb/Utility/SharingPtr.h" // for SharingPtr +#include "lldb/Core/ValueObject.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/SharingPtr.h" -#include // for back_insert_iterator, back_ins... +#include using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectMemory.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectMemory.cpp index 3e71fea6bb35..24103204ee47 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectMemory.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectMemory.cpp @@ -8,19 +8,19 @@ //===----------------------------------------------------------------------===// #include "lldb/Core/ValueObjectMemory.h" -#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/Symbol/Type.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/DataExtractor.h" // for DataExtractor -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-types.h" // for addr_t -#include "llvm/Support/ErrorHandling.h" // for llvm_unreachable +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-types.h" +#include "llvm/Support/ErrorHandling.h" -#include // for assert -#include // for shared_ptr +#include +#include namespace lldb_private { class ExecutionContextScope; @@ -128,15 +128,19 @@ size_t ValueObjectMemory::CalculateNumChildren(uint32_t max) { return child_count <= max ? child_count : max; } + ExecutionContext exe_ctx(GetExecutionContextRef()); const bool omit_empty_base_classes = true; - auto child_count = m_compiler_type.GetNumChildren(omit_empty_base_classes); + auto child_count = + m_compiler_type.GetNumChildren(omit_empty_base_classes, &exe_ctx); return child_count <= max ? child_count : max; } uint64_t ValueObjectMemory::GetByteSize() { if (m_type_sp) return m_type_sp->GetByteSize(); - return m_compiler_type.GetByteSize(nullptr); + if (llvm::Optional size = m_compiler_type.GetByteSize(nullptr)) + return *size; + return 0; } lldb::ValueType ValueObjectMemory::GetValueType() const { diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectRegister.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectRegister.cpp index 05022d3ed10a..41d1c27f7361 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectRegister.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectRegister.cpp @@ -10,23 +10,23 @@ #include "lldb/Core/ValueObjectRegister.h" #include "lldb/Core/Module.h" -#include "lldb/Core/Scalar.h" // for Scalar -#include "lldb/Core/Value.h" // for Value, Value::ContextType:... +#include "lldb/Core/Value.h" #include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/TypeSystem.h" // for TypeSystem +#include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" -#include "lldb/Target/StackFrame.h" // for StackFrame +#include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/DataExtractor.h" // for DataExtractor -#include "lldb/Utility/Status.h" // for Status -#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/Stream.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" -#include // for assert -#include // for shared_ptr +#include +#include namespace lldb_private { class ExecutionContextScope; @@ -279,7 +279,8 @@ ConstString ValueObjectRegister::GetTypeName() { } size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) { - auto children_count = GetCompilerType().GetNumChildren(true); + ExecutionContext exe_ctx(GetExecutionContextRef()); + auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx); return children_count <= max ? children_count : max; } diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectSyntheticFilter.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectSyntheticFilter.cpp index 044387a4ae12..d22b1dc1c57d 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectSyntheticFilter.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectSyntheticFilter.cpp @@ -9,14 +9,14 @@ #include "lldb/Core/ValueObjectSyntheticFilter.h" -#include "lldb/Core/Value.h" // for Value +#include "lldb/Core/Value.h" #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/TypeSynthetic.h" -#include "lldb/Target/ExecutionContext.h" // for ExecutionContext +#include "lldb/Target/ExecutionContext.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for GetLogIfAllCategoriesSet -#include "lldb/Utility/SharingPtr.h" // for SharingPtr -#include "lldb/Utility/Status.h" // for Status +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/SharingPtr.h" +#include "lldb/Utility/Status.h" #include "llvm/ADT/STLExtras.h" @@ -119,7 +119,7 @@ bool ValueObjectSynthetic::MightHaveChildren() { if (m_might_have_children == eLazyBoolCalculate) m_might_have_children = (m_synth_filter_ap->MightHaveChildren() ? eLazyBoolYes : eLazyBoolNo); - return (m_might_have_children == eLazyBoolNo ? false : true); + return (m_might_have_children != eLazyBoolNo); } uint64_t ValueObjectSynthetic::GetByteSize() { return m_parent->GetByteSize(); } @@ -174,7 +174,7 @@ bool ValueObjectSynthetic::UpdateValue() { } // let our backend do its update - if (m_synth_filter_ap->Update() == false) { + if (!m_synth_filter_ap->Update()) { if (log) log->Printf("[ValueObjectSynthetic::UpdateValue] name=%s, synthetic " "filter said caches are stale - clearing", @@ -235,7 +235,7 @@ lldb::ValueObjectSP ValueObjectSynthetic::GetChildAtIndex(size_t idx, UpdateValueIfNeeded(); ValueObject *valobj; - if (m_children_byindex.GetValueForKey(idx, valobj) == false) { + if (!m_children_byindex.GetValueForKey(idx, valobj)) { if (can_create && m_synth_filter_ap.get() != nullptr) { if (log) log->Printf("[ValueObjectSynthetic::GetChildAtIndex] name=%s, child at " diff --git a/contrib/llvm/tools/lldb/source/Core/ValueObjectVariable.cpp b/contrib/llvm/tools/lldb/source/Core/ValueObjectVariable.cpp index bfe5c3de7fbf..4d401c56249c 100644 --- a/contrib/llvm/tools/lldb/source/Core/ValueObjectVariable.cpp +++ b/contrib/llvm/tools/lldb/source/Core/ValueObjectVariable.cpp @@ -9,14 +9,12 @@ #include "lldb/Core/ValueObjectVariable.h" -#include "lldb/Core/Address.h" // for Address -#include "lldb/Core/AddressRange.h" // for AddressRange +#include "lldb/Core/Address.h" +#include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" // for Scalar, operator!= #include "lldb/Core/Value.h" -#include "lldb/Expression/DWARFExpression.h" // for DWARFExpression -#include "lldb/Symbol/Declaration.h" // for Declaration +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/Function.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" @@ -27,15 +25,17 @@ #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" -#include "lldb/Utility/DataExtractor.h" // for DataExtractor -#include "lldb/Utility/Status.h" // for Status -#include "lldb/lldb-private-enumerations.h" // for AddressType::eAddressTy... -#include "lldb/lldb-types.h" // for addr_t +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" +#include "lldb/Utility/Status.h" +#include "lldb/lldb-private-enumerations.h" +#include "lldb/lldb-types.h" -#include "llvm/ADT/StringRef.h" // for StringRef +#include "llvm/ADT/StringRef.h" -#include // for assert -#include // for shared_ptr +#include +#include namespace lldb_private { class ExecutionContextScope; @@ -98,8 +98,9 @@ size_t ValueObjectVariable::CalculateNumChildren(uint32_t max) { if (!type.IsValid()) return 0; + ExecutionContext exe_ctx(GetExecutionContextRef()); const bool omit_empty_base_classes = true; - auto child_count = type.GetNumChildren(omit_empty_base_classes); + auto child_count = type.GetNumChildren(omit_empty_base_classes, &exe_ctx); return child_count <= max ? child_count : max; } @@ -111,7 +112,7 @@ uint64_t ValueObjectVariable::GetByteSize() { if (!type.IsValid()) return 0; - return type.GetByteSize(exe_ctx.GetBestExecutionContextScope()); + return type.GetByteSize(exe_ctx.GetBestExecutionContextScope()).getValueOr(0); } lldb::ValueType ValueObjectVariable::GetValueType() const { diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/CXXFunctionPointer.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/CXXFunctionPointer.cpp index fad67a9d5b7a..9059891e5e9b 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/CXXFunctionPointer.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/CXXFunctionPointer.cpp @@ -38,7 +38,7 @@ bool lldb_private::formatters::CXXFunctionPointerSummaryProvider( Address so_addr; Target *target = exe_ctx.GetTargetPtr(); - if (target && target->GetSectionLoadList().IsEmpty() == false) { + if (target && !target->GetSectionLoadList().IsEmpty()) { if (target->GetSectionLoadList().ResolveLoadAddress(func_ptr_address, so_addr)) { so_addr.Dump(&sstr, exe_ctx.GetBestExecutionContextScope(), diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/DataVisualization.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/DataVisualization.cpp index 2a2d4b8b553e..23b8b6e128c8 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/DataVisualization.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/DataVisualization.cpp @@ -10,10 +10,6 @@ #include "lldb/DataFormatters/DataVisualization.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb; using namespace lldb_private; @@ -149,7 +145,7 @@ void DataVisualization::Categories::Enable(lldb::LanguageType lang_type) { } void DataVisualization::Categories::Disable(const ConstString &category) { - if (GetFormatManager().GetCategory(category)->IsEnabled() == true) + if (GetFormatManager().GetCategory(category)->IsEnabled()) GetFormatManager().DisableCategory(category); } @@ -170,7 +166,7 @@ void DataVisualization::Categories::Enable( void DataVisualization::Categories::Disable( const lldb::TypeCategoryImplSP &category) { - if (category.get() && category->IsEnabled() == true) + if (category.get() && category->IsEnabled()) GetFormatManager().DisableCategory(category); } diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/DumpValueObjectOptions.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/DumpValueObjectOptions.cpp index 7c9d5eb77a01..17f8d00ff493 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/DumpValueObjectOptions.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/DumpValueObjectOptions.cpp @@ -10,10 +10,6 @@ #include "lldb/DataFormatters/DumpValueObjectOptions.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/ValueObject.h" using namespace lldb; @@ -71,7 +67,7 @@ DumpValueObjectOptions &DumpValueObjectOptions::SetUseObjectiveC(bool use) { } DumpValueObjectOptions &DumpValueObjectOptions::SetShowSummary(bool show) { - if (show == false) + if (!show) SetOmitSummaryDepth(UINT32_MAX); else SetOmitSummaryDepth(0); diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/FormatCache.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/FormatCache.cpp index 0f1b29f1b476..bb5f379d3c73 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/FormatCache.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/FormatCache.cpp @@ -8,13 +8,9 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/FormatCache.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/FormatClasses.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/FormatClasses.cpp index f657361d3d5d..1c595c3c04e5 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/FormatClasses.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/FormatClasses.cpp @@ -12,13 +12,9 @@ #include "lldb/DataFormatters/FormatManager.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/FormatManager.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/FormatManager.cpp index bafee1799b80..da03c64b0f8c 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/FormatManager.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/FormatManager.cpp @@ -11,10 +11,6 @@ #include "llvm/ADT/STLExtras.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Debugger.h" #include "lldb/DataFormatters/FormattersHelpers.h" @@ -297,7 +293,7 @@ FormatManager::GetFormatForType(lldb::TypeNameSpecifierImplSP type_sp) { uint32_t prio_category = UINT32_MAX; for (uint32_t category_id = 0; category_id < num_categories; category_id++) { category_sp = GetCategoryAtIndex(category_id); - if (category_sp->IsEnabled() == false) + if (!category_sp->IsEnabled()) continue; lldb::TypeFormatImplSP format_current_sp = category_sp->GetFormatForType(type_sp); @@ -321,7 +317,7 @@ FormatManager::GetSummaryForType(lldb::TypeNameSpecifierImplSP type_sp) { uint32_t prio_category = UINT32_MAX; for (uint32_t category_id = 0; category_id < num_categories; category_id++) { category_sp = GetCategoryAtIndex(category_id); - if (category_sp->IsEnabled() == false) + if (!category_sp->IsEnabled()) continue; lldb::TypeSummaryImplSP summary_current_sp = category_sp->GetSummaryForType(type_sp); @@ -345,7 +341,7 @@ FormatManager::GetFilterForType(lldb::TypeNameSpecifierImplSP type_sp) { uint32_t prio_category = UINT32_MAX; for (uint32_t category_id = 0; category_id < num_categories; category_id++) { category_sp = GetCategoryAtIndex(category_id); - if (category_sp->IsEnabled() == false) + if (!category_sp->IsEnabled()) continue; lldb::TypeFilterImplSP filter_current_sp( (TypeFilterImpl *)category_sp->GetFilterForType(type_sp).get()); @@ -370,7 +366,7 @@ FormatManager::GetSyntheticForType(lldb::TypeNameSpecifierImplSP type_sp) { uint32_t prio_category = UINT32_MAX; for (uint32_t category_id = 0; category_id < num_categories; category_id++) { category_sp = GetCategoryAtIndex(category_id); - if (category_sp->IsEnabled() == false) + if (!category_sp->IsEnabled()) continue; lldb::ScriptedSyntheticChildrenSP synth_current_sp( (ScriptedSyntheticChildren *)category_sp->GetSyntheticForType(type_sp) @@ -410,7 +406,7 @@ FormatManager::GetValidatorForType(lldb::TypeNameSpecifierImplSP type_sp) { uint32_t prio_category = UINT32_MAX; for (uint32_t category_id = 0; category_id < num_categories; category_id++) { category_sp = GetCategoryAtIndex(category_id); - if (category_sp->IsEnabled() == false) + if (!category_sp->IsEnabled()) continue; lldb::TypeValidatorImplSP validator_current_sp( category_sp->GetValidatorForType(type_sp).get()); @@ -483,7 +479,7 @@ lldb::Format FormatManager::GetSingleItemFormat(lldb::Format vector_format) { bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) { // if settings say no oneline whatsoever if (valobj.GetTargetSP().get() && - valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries() == false) + !valobj.GetTargetSP()->GetDebugger().GetAutoOneLineSummaries()) return false; // then don't oneline // if this object has a summary, then ask the summary @@ -539,7 +535,7 @@ bool FormatManager::ShouldPrintAsOneLiner(ValueObject &valobj) { if (!synth_sp) return false; // but if we only have them to provide a value, keep going - if (synth_sp->MightHaveChildren() == false && + if (!synth_sp->MightHaveChildren() && synth_sp->DoesProvideSyntheticValue()) is_synth_val = true; else diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/FormattersHelpers.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/FormattersHelpers.cpp index 460a49690d3d..1a1321598966 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/FormattersHelpers.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/FormattersHelpers.cpp @@ -8,13 +8,9 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Target/StackFrame.h" diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/LanguageCategory.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/LanguageCategory.cpp index 251f0c368e08..4a4b7c544f09 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/LanguageCategory.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/LanguageCategory.cpp @@ -10,10 +10,6 @@ #include "lldb/DataFormatters/LanguageCategory.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/FormatManager.h" #include "lldb/DataFormatters/TypeCategory.h" #include "lldb/DataFormatters/TypeFormat.h" diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/StringPrinter.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/StringPrinter.cpp index 89d7a95069ca..6a000f0f6431 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/StringPrinter.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/StringPrinter.cpp @@ -312,7 +312,7 @@ static bool DumpUTFBufferToStream( utf8_data_end_ptr = utf8_data_ptr + utf8_data_buffer_sp->GetByteSize(); ConvertFunction(&data_ptr, data_end_ptr, &utf8_data_ptr, utf8_data_end_ptr, llvm::lenientConversion); - if (false == zero_is_terminator) + if (!zero_is_terminator) utf8_data_end_ptr = utf8_data_ptr; // needed because the ConvertFunction will change the value of the // data_ptr. diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/TypeCategory.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/TypeCategory.cpp index 184a8c98de62..5740a095f8bd 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/TypeCategory.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/TypeCategory.cpp @@ -10,10 +10,6 @@ #include "lldb/DataFormatters/TypeCategory.h" #include "lldb/Target/Language.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb; using namespace lldb_private; @@ -161,10 +157,7 @@ bool TypeCategoryImpl::Get(ValueObject &valobj, else /*if (filter_sp.get() && synth.get())*/ { - if (filter_sp->GetRevision() > synth->GetRevision()) - pick_synth = false; - else - pick_synth = true; + pick_synth = filter_sp->GetRevision() <= synth->GetRevision(); } if (pick_synth) { if (regex_synth && reason) diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/TypeCategoryMap.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/TypeCategoryMap.cpp index d2da672f13dc..3193f2703efa 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/TypeCategoryMap.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/TypeCategoryMap.cpp @@ -13,10 +13,6 @@ #include "lldb/DataFormatters/FormatClasses.h" #include "lldb/Utility/Log.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb; using namespace lldb_private; @@ -122,8 +118,7 @@ void TypeCategoryMap::EnableAllCategories() { void TypeCategoryMap::DisableAllCategories() { std::lock_guard guard(m_map_mutex); - Position p = First; - for (; false == m_active_categories.empty(); p++) { + for (Position p = First; !m_active_categories.empty(); p++) { m_active_categories.front()->SetEnabledPosition(p); Disable(m_active_categories.front()); } diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/TypeFormat.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/TypeFormat.cpp index 7902ccb47771..f00a679cecfd 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/TypeFormat.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/TypeFormat.cpp @@ -9,13 +9,9 @@ #include "lldb/DataFormatters/TypeFormat.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" @@ -98,16 +94,18 @@ bool TypeFormatImpl_Format::FormatObject(ValueObject *valobj, return false; } + ExecutionContextScope *exe_scope = + exe_ctx.GetBestExecutionContextScope(); + llvm::Optional size = compiler_type.GetByteSize(exe_scope); + if (!size) + return false; StreamString sstr; - ExecutionContextScope *exe_scope( - exe_ctx.GetBestExecutionContextScope()); compiler_type.DumpTypeValue( - &sstr, // The stream to use for display - GetFormat(), // Format to display this type with - data, // Data to extract from - 0, // Byte offset into "m_data" - compiler_type.GetByteSize( - exe_scope), // Byte size of item in "m_data" + &sstr, // The stream to use for display + GetFormat(), // Format to display this type with + data, // Data to extract from + 0, // Byte offset into "m_data" + *size, // Byte size of item in "m_data" valobj->GetBitfieldBitSize(), // Bitfield bit size valobj->GetBitfieldBitOffset(), // Bitfield bit offset exe_scope); @@ -163,11 +161,10 @@ bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj, if (!target_sp) return false; const ModuleList &images(target_sp->GetImages()); - SymbolContext sc; TypeList types; llvm::DenseSet searched_symbol_files; - images.FindTypes(sc, m_enum_type, false, UINT32_MAX, searched_symbol_files, - types); + images.FindTypes(nullptr, m_enum_type, false, UINT32_MAX, + searched_symbol_files, types); if (types.GetSize() == 0) return false; for (lldb::TypeSP type_sp : types.Types()) { @@ -182,7 +179,7 @@ bool TypeFormatImpl_EnumType::FormatObject(ValueObject *valobj, } } else valobj_enum_type = iter->second; - if (valobj_enum_type.IsValid() == false) + if (!valobj_enum_type.IsValid()) return false; DataExtractor data; Status error; diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/TypeSummary.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/TypeSummary.cpp index 09a7ff8d7d36..492d3efc7f4c 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/TypeSummary.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/TypeSummary.cpp @@ -9,13 +9,9 @@ #include "lldb/DataFormatters/TypeSummary.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" @@ -139,7 +135,7 @@ bool CXXFunctionSummaryFormat::FormatObject(ValueObject *valobj, const TypeSummaryOptions &options) { dest.clear(); StreamString stream; - if (!m_impl || m_impl(*valobj, stream, options) == false) + if (!m_impl || !m_impl(*valobj, stream, options)) return false; dest = stream.GetString(); return true; diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/TypeSynthetic.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/TypeSynthetic.cpp index 28a51dae6b20..de46d505349b 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/TypeSynthetic.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/TypeSynthetic.cpp @@ -8,13 +8,9 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-enumerations.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/TypeValidator.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/TypeValidator.cpp index 7a5b8d565292..6769a5a99856 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/TypeValidator.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/TypeValidator.cpp @@ -7,13 +7,9 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/TypeValidator.h" #include "lldb/Utility/StreamString.h" diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/ValueObjectPrinter.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/ValueObjectPrinter.cpp index 43e91a2b6c92..082158822dff 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/ValueObjectPrinter.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/ValueObjectPrinter.cpp @@ -9,10 +9,6 @@ #include "lldb/DataFormatters/ValueObjectPrinter.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/ValueObject.h" #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -133,13 +129,13 @@ bool ValueObjectPrinter::GetMostSpecializedValue() { } if (m_valobj->IsSynthetic()) { - if (m_options.m_use_synthetic == false) { + if (!m_options.m_use_synthetic) { ValueObject *non_synthetic = m_valobj->GetNonSyntheticValue().get(); if (non_synthetic) m_valobj = non_synthetic; } } else { - if (m_options.m_use_synthetic == true) { + if (m_options.m_use_synthetic) { ValueObject *synthetic = m_valobj->GetSyntheticValue().get(); if (synthetic) m_valobj = synthetic; @@ -170,7 +166,7 @@ const char *ValueObjectPrinter::GetRootNameForDisplay(const char *if_fail) { bool ValueObjectPrinter::ShouldPrintValueObject() { if (m_should_print == eLazyBoolCalculate) m_should_print = - (m_options.m_flat_output == false || m_type_flags.Test(eTypeHasValue)) + (!m_options.m_flat_output || m_type_flags.Test(eTypeHasValue)) ? eLazyBoolYes : eLazyBoolNo; return m_should_print == eLazyBoolYes; @@ -330,7 +326,7 @@ bool ValueObjectPrinter::CheckScopeIfNeeded() { } TypeSummaryImpl *ValueObjectPrinter::GetSummaryFormatter(bool null_if_omitted) { - if (m_summary_formatter.second == false) { + if (!m_summary_formatter.second) { TypeSummaryImpl *entry = m_options.m_summary_sp ? m_options.m_summary_sp.get() : m_valobj->GetSummaryFormat().get(); @@ -462,7 +458,7 @@ bool ValueObjectPrinter::PrintObjectDescriptionIfNeeded(bool value_printed, else m_stream->Printf("%s\n", object_desc); return true; - } else if (value_printed == false && summary_printed == false) + } else if (!value_printed && !summary_printed) return true; else return false; @@ -629,7 +625,7 @@ bool ValueObjectPrinter::ShouldPrintEmptyBrackets(bool value_printed, if (!IsAggregate()) return false; - if (m_options.m_reveal_empty_aggregates == false) { + if (!m_options.m_reveal_empty_aggregates) { if (value_printed || summary_printed) return false; } diff --git a/contrib/llvm/tools/lldb/source/DataFormatters/VectorType.cpp b/contrib/llvm/tools/lldb/source/DataFormatters/VectorType.cpp index d85a7e674177..b11fb1456afa 100644 --- a/contrib/llvm/tools/lldb/source/DataFormatters/VectorType.cpp +++ b/contrib/llvm/tools/lldb/source/DataFormatters/VectorType.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/VectorType.h" #include "lldb/Core/ValueObject.h" @@ -175,13 +171,14 @@ static size_t CalculateNumChildren( lldb_private::ExecutionContextScope *exe_scope = nullptr // does not matter here because all we trade in are basic types ) { - auto container_size = container_type.GetByteSize(exe_scope); - auto element_size = element_type.GetByteSize(exe_scope); + llvm::Optional container_size = + container_type.GetByteSize(exe_scope); + llvm::Optional element_size = element_type.GetByteSize(exe_scope); - if (element_size) { - if (container_size % element_size) + if (container_size && element_size && *element_size) { + if (*container_size % *element_size) return 0; - return container_size / element_size; + return *container_size / *element_size; } return 0; } @@ -201,8 +198,11 @@ public: lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { if (idx >= CalculateNumChildren()) - return lldb::ValueObjectSP(); - auto offset = idx * m_child_type.GetByteSize(nullptr); + return {}; + llvm::Optional size = m_child_type.GetByteSize(nullptr); + if (!size) + return {}; + auto offset = idx * *size; StreamString idx_name; idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); ValueObjectSP child_sp(m_backend.GetSyntheticChildAtOffset( diff --git a/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp b/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp index 55eb65f32b5a..a6249b3a2864 100644 --- a/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/DWARFExpression.cpp @@ -9,19 +9,17 @@ #include "lldb/Expression/DWARFExpression.h" -// C Includes #include -// C++ Includes #include #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/dwarf.h" #include "lldb/Utility/DataEncoder.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/VMRange.h" @@ -1841,7 +1839,7 @@ bool DWARFExpression::Evaluate( error_ptr->SetErrorString( "Expression stack needs at least 1 item for DW_OP_abs."); return false; - } else if (stack.back().ResolveValue(exe_ctx).AbsoluteValue() == false) { + } else if (!stack.back().ResolveValue(exe_ctx).AbsoluteValue()) { if (error_ptr) error_ptr->SetErrorString( "Failed to take the absolute value of the first stack item."); @@ -1974,7 +1972,7 @@ bool DWARFExpression::Evaluate( "Expression stack needs at least 1 item for DW_OP_neg."); return false; } else { - if (stack.back().ResolveValue(exe_ctx).UnaryNegate() == false) { + if (!stack.back().ResolveValue(exe_ctx).UnaryNegate()) { if (error_ptr) error_ptr->SetErrorString("Unary negate failed."); return false; @@ -1995,7 +1993,7 @@ bool DWARFExpression::Evaluate( "Expression stack needs at least 1 item for DW_OP_not."); return false; } else { - if (stack.back().ResolveValue(exe_ctx).OnesComplement() == false) { + if (!stack.back().ResolveValue(exe_ctx).OnesComplement()) { if (error_ptr) error_ptr->SetErrorString("Logical NOT failed."); return false; @@ -2102,8 +2100,8 @@ bool DWARFExpression::Evaluate( } else { tmp = stack.back(); stack.pop_back(); - if (stack.back().ResolveValue(exe_ctx).ShiftRightLogical( - tmp.ResolveValue(exe_ctx)) == false) { + if (!stack.back().ResolveValue(exe_ctx).ShiftRightLogical( + tmp.ResolveValue(exe_ctx))) { if (error_ptr) error_ptr->SetErrorString("DW_OP_shr failed."); return false; @@ -2382,7 +2380,7 @@ bool DWARFExpression::Evaluate( case DW_OP_lit29: case DW_OP_lit30: case DW_OP_lit31: - stack.push_back(Scalar(op - DW_OP_lit0)); + stack.push_back(Scalar((uint64_t)(op - DW_OP_lit0))); break; //---------------------------------------------------------------------- @@ -3029,7 +3027,9 @@ bool DWARFExpression::AddressRangeForLocationListEntry( if (!debug_loc_data.ValidOffset(*offset_ptr)) return false; - switch (dwarf_cu->GetSymbolFileDWARF()->GetLocationListFormat()) { + DWARFExpression::LocationListFormat format = + dwarf_cu->GetSymbolFileDWARF()->GetLocationListFormat(); + switch (format) { case NonLocationList: return false; case RegularLocationList: @@ -3037,6 +3037,7 @@ bool DWARFExpression::AddressRangeForLocationListEntry( high_pc = debug_loc_data.GetAddress(offset_ptr); return true; case SplitDwarfLocationList: + case LocLists: switch (debug_loc_data.GetU8(offset_ptr)) { case DW_LLE_end_of_list: return false; @@ -3050,12 +3051,25 @@ bool DWARFExpression::AddressRangeForLocationListEntry( case DW_LLE_startx_length: { uint64_t index = debug_loc_data.GetULEB128(offset_ptr); low_pc = ReadAddressFromDebugAddrSection(dwarf_cu, index); - uint32_t length = debug_loc_data.GetU32(offset_ptr); + uint64_t length = (format == LocLists) + ? debug_loc_data.GetULEB128(offset_ptr) + : debug_loc_data.GetU32(offset_ptr); high_pc = low_pc + length; return true; } + case DW_LLE_start_length: { + low_pc = debug_loc_data.GetAddress(offset_ptr); + high_pc = low_pc + debug_loc_data.GetULEB128(offset_ptr); + return true; + } + case DW_LLE_start_end: { + low_pc = debug_loc_data.GetAddress(offset_ptr); + high_pc = debug_loc_data.GetAddress(offset_ptr); + return true; + } default: // Not supported entry type + lldbassert(false && "Not supported location list type"); return false; } } diff --git a/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp b/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp index abbb332fac48..03b2d26a256d 100644 --- a/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/ExpressionSourceCode.cpp @@ -105,10 +105,7 @@ public: if (m_file_stack.back() != m_current_file) return true; - if (line >= m_current_file_line) - return false; - else - return true; + return line < m_current_file_line; default: return false; } @@ -378,7 +375,5 @@ bool ExpressionSourceCode::GetOriginalBodyBounds( return false; start_loc += strlen(start_marker); end_loc = transformed_text.find(end_marker); - if (end_loc == std::string::npos) - return false; - return true; + return end_loc != std::string::npos; } diff --git a/contrib/llvm/tools/lldb/source/Expression/FunctionCaller.cpp b/contrib/llvm/tools/lldb/source/Expression/FunctionCaller.cpp index 9742ed0b270e..97f4f51e1ff6 100644 --- a/contrib/llvm/tools/lldb/source/Expression/FunctionCaller.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/FunctionCaller.cpp @@ -7,14 +7,9 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Expression/FunctionCaller.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Expression/DiagnosticManager.h" @@ -31,6 +26,7 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp b/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp index e0a7dca4113d..20431d5f93c5 100644 --- a/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/IRDynamicChecks.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Function.h" @@ -18,7 +15,6 @@ #include "llvm/IR/Value.h" #include "llvm/Support/raw_ostream.h" -// Project includes #include "lldb/Expression/IRDynamicChecks.h" #include "lldb/Expression/UtilityFunction.h" diff --git a/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp b/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp index e34a4c7fac52..ec6ceeac1813 100644 --- a/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/IRExecutionUnit.cpp @@ -553,6 +553,8 @@ lldb::SectionType IRExecutionUnit::GetSectionTypeFromSectionName( sect_type = lldb::eSectionTypeDWARFDebugLine; else if (dwarf_name.equals("loc")) sect_type = lldb::eSectionTypeDWARFDebugLoc; + else if (dwarf_name.equals("loclists")) + sect_type = lldb::eSectionTypeDWARFDebugLocLists; break; case 'm': @@ -707,9 +709,10 @@ FindBestAlternateMangledName(const ConstString &demangled, struct IRExecutionUnit::SearchSpec { ConstString name; - uint32_t mask; + lldb::FunctionNameType mask; - SearchSpec(ConstString n, uint32_t m = lldb::eFunctionNameTypeFull) + SearchSpec(ConstString n, + lldb::FunctionNameType m = lldb::eFunctionNameTypeFull) : name(n), mask(m) {} }; @@ -1010,7 +1013,7 @@ IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name) { Name.c_str()); m_parent.ReportSymbolLookupError(name_cs); - return 0xbad0bad0; + return 0; } else { if (log) log->Printf("IRExecutionUnit::getSymbolAddress(Name=\"%s\") = %" PRIx64, @@ -1088,6 +1091,7 @@ bool IRExecutionUnit::CommitOneAllocation(lldb::ProcessSP &process_sp, case lldb::eSectionTypeDWARFDebugInfo: case lldb::eSectionTypeDWARFDebugLine: case lldb::eSectionTypeDWARFDebugLoc: + case lldb::eSectionTypeDWARFDebugLocLists: case lldb::eSectionTypeDWARFDebugMacInfo: case lldb::eSectionTypeDWARFDebugPubNames: case lldb::eSectionTypeDWARFDebugPubTypes: @@ -1213,14 +1217,11 @@ void IRExecutionUnit::PopulateSectionList( } } -bool IRExecutionUnit::GetArchitecture(lldb_private::ArchSpec &arch) { +ArchSpec IRExecutionUnit::GetArchitecture() { ExecutionContext exe_ctx(GetBestExecutionContextScope()); - Target *target = exe_ctx.GetTargetPtr(); - if (target) - arch = target->GetArchitecture(); - else - arch.Clear(); - return arch.IsValid(); + if(Target *target = exe_ctx.GetTargetPtr()) + return target->GetArchitecture(); + return ArchSpec(); } lldb::ModuleSP IRExecutionUnit::GetJITModule() { diff --git a/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp b/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp index abf86b739f07..457eaef46dd3 100644 --- a/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/IRInterpreter.cpp @@ -10,7 +10,6 @@ #include "lldb/Expression/IRInterpreter.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/IRExecutionUnit.h" @@ -19,6 +18,7 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" @@ -152,17 +152,13 @@ public: Type *type) { size_t type_size = m_target_data.getTypeStoreSize(type); - switch (type_size) { - case 1: - case 2: - case 4: - case 8: - scalar = llvm::APInt(type_size*8, u64value); - break; - default: + if (type_size > 8) return false; - } + if (type_size != 1) + type_size = PowerOf2Ceil(type_size); + + scalar = llvm::APInt(type_size*8, u64value); return true; } @@ -192,8 +188,7 @@ public: return false; lldb::offset_t offset = 0; - if (value_size == 1 || value_size == 2 || value_size == 4 || - value_size == 8) { + if (value_size <= 8) { uint64_t u64value = value_extractor.GetMaxU64(&offset, value_size); return AssignToMatchType(scalar, u64value, value->getType()); } @@ -618,6 +613,18 @@ bool IRInterpreter::CanInterpret(llvm::Module &module, llvm::Function &function, } } + // The IR interpreter currently doesn't know about + // 128-bit integers. As they're not that frequent, + // we can just fall back to the JIT rather than + // choking. + if (operand_type->getPrimitiveSizeInBits() > 64) { + if (log) + log->Printf("Unsupported operand type: %s", + PrintType(operand_type).c_str()); + error.SetErrorString(unsupported_operand_error); + return false; + } + if (Constant *constant = llvm::dyn_cast(operand)) { if (!CanResolveConstant(constant)) { if (log) @@ -1585,9 +1592,6 @@ bool IRInterpreter::Interpret(llvm::Module &module, llvm::Function &function, // Check if this is a string literal or constant string pointer if (arg_ty->isPointerTy()) { - // Pointer to just one type - assert(arg_ty->getNumContainedTypes() == 1); - lldb::addr_t addr = tmp_op.ULongLong(); size_t dataSize = 0; diff --git a/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp b/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp index 1953e80852ff..e4c85d6ce727 100644 --- a/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/IRMemoryMap.cpp @@ -8,7 +8,6 @@ //===----------------------------------------------------------------------===// #include "lldb/Expression/IRMemoryMap.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" @@ -16,6 +15,7 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" using namespace lldb_private; @@ -272,20 +272,16 @@ IRMemoryMap::Allocation::Allocation(lldb::addr_t process_alloc, uint32_t permissions, uint8_t alignment, AllocationPolicy policy) : m_process_alloc(process_alloc), m_process_start(process_start), - m_size(size), m_permissions(permissions), m_alignment(alignment), - m_policy(policy), m_leak(false) { + m_size(size), m_policy(policy), m_leak(false), m_permissions(permissions), + m_alignment(alignment) { switch (policy) { default: assert(0 && "We cannot reach this!"); case eAllocationPolicyHostOnly: - m_data.SetByteSize(size); - memset(m_data.GetBytes(), 0, size); - break; - case eAllocationPolicyProcessOnly: - break; case eAllocationPolicyMirror: m_data.SetByteSize(size); - memset(m_data.GetBytes(), 0, size); + break; + case eAllocationPolicyProcessOnly: break; } } @@ -393,9 +389,10 @@ lldb::addr_t IRMemoryMap::Malloc(size_t size, uint8_t alignment, lldb::addr_t mask = alignment - 1; aligned_address = (allocation_address + mask) & (~mask); - m_allocations[aligned_address] = - Allocation(allocation_address, aligned_address, allocation_size, - permissions, alignment, policy); + m_allocations.emplace( + std::piecewise_construct, std::forward_as_tuple(aligned_address), + std::forward_as_tuple(allocation_address, aligned_address, + allocation_size, permissions, alignment, policy)); if (zero_memory) { Status write_error; diff --git a/contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp b/contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp index fc32bfbd37a2..edf1e69c30d8 100644 --- a/contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/LLVMUserExpression.cpp @@ -7,10 +7,7 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Project includes #include "lldb/Expression/LLVMUserExpression.h" #include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" diff --git a/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp b/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp index 74a965e015ce..4d4e5e21092c 100644 --- a/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/Materializer.cpp @@ -7,13 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Expression/Materializer.h" #include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/ExpressionVariable.h" @@ -27,6 +22,7 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; @@ -50,7 +46,8 @@ uint32_t Materializer::AddStructMember(Entity &entity) { } void Materializer::Entity::SetSizeAndAlignmentFromType(CompilerType &type) { - m_size = type.GetByteSize(nullptr); + if (llvm::Optional size = type.GetByteSize(nullptr)) + m_size = *size; uint32_t bit_alignment = type.GetTypeBitAlign(); @@ -532,7 +529,7 @@ public: if (data.GetByteSize() < m_variable_sp->GetType()->GetByteSize()) { if (data.GetByteSize() == 0 && - m_variable_sp->LocationExpression().IsValid() == false) { + !m_variable_sp->LocationExpression().IsValid()) { err.SetErrorStringWithFormat("the variable '%s' has no location, " "it may have been optimized out", m_variable_sp->GetName().AsCString()); @@ -798,7 +795,11 @@ public: ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope(); - size_t byte_size = m_type.GetByteSize(exe_scope); + llvm::Optional byte_size = m_type.GetByteSize(exe_scope); + if (!byte_size) { + err.SetErrorString("can't get size of type"); + return; + } size_t bit_align = m_type.GetTypeBitAlign(); size_t byte_align = (bit_align + 7) / 8; @@ -809,10 +810,10 @@ public: const bool zero_memory = true; m_temporary_allocation = map.Malloc( - byte_size, byte_align, + *byte_size, byte_align, lldb::ePermissionsReadable | lldb::ePermissionsWritable, IRMemoryMap::eAllocationPolicyMirror, zero_memory, alloc_error); - m_temporary_allocation_size = byte_size; + m_temporary_allocation_size = *byte_size; if (!alloc_error.Success()) { err.SetErrorStringWithFormat( diff --git a/contrib/llvm/tools/lldb/source/Expression/REPL.cpp b/contrib/llvm/tools/lldb/source/Expression/REPL.cpp index a441e381985c..943385bb3aac 100644 --- a/contrib/llvm/tools/lldb/source/Expression/REPL.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/REPL.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Expression/REPL.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" @@ -66,7 +62,7 @@ std::string REPL::GetSourcePath() { tmpdir_file_spec.GetFilename().SetCString(file_basename.AsCString()); m_repl_source_path = tmpdir_file_spec.GetPath(); } else { - tmpdir_file_spec = FileSpec("/tmp", false); + tmpdir_file_spec = FileSpec("/tmp"); tmpdir_file_spec.AppendPathComponent(file_basename.AsCString()); } @@ -416,11 +412,12 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { // Update our code on disk if (!m_repl_source_path.empty()) { - lldb_private::File file(m_repl_source_path.c_str(), - File::eOpenOptionWrite | - File::eOpenOptionTruncate | - File::eOpenOptionCanCreate, - lldb::eFilePermissionsFileDefault); + lldb_private::File file; + FileSystem::Instance().Open(file, FileSpec(m_repl_source_path), + File::eOpenOptionWrite | + File::eOpenOptionTruncate | + File::eOpenOptionCanCreate, + lldb::eFilePermissionsFileDefault); std::string code(m_code.CopyList()); code.append(1, '\n'); size_t bytes_written = code.size(); @@ -429,7 +426,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { // Now set the default file and line to the REPL source file m_target.GetSourceManager().SetDefaultFileAndLine( - FileSpec(m_repl_source_path, false), new_default_line); + FileSpec(m_repl_source_path), new_default_line); } static_cast(io_handler) .SetBaseLineNumber(m_code.GetSize() + 1); @@ -453,7 +450,7 @@ void REPL::IOHandlerInputComplete(IOHandler &io_handler, std::string &code) { int REPL::IOHandlerComplete(IOHandler &io_handler, const char *current_line, const char *cursor, const char *last_char, int skip_first_n_matches, int max_matches, - StringList &matches) { + StringList &matches, StringList &descriptions) { matches.Clear(); llvm::StringRef line(current_line, cursor - current_line); @@ -466,7 +463,7 @@ int REPL::IOHandlerComplete(IOHandler &io_handler, const char *current_line, const char *lldb_current_line = line.substr(1).data(); return debugger.GetCommandInterpreter().HandleCompletion( lldb_current_line, cursor, last_char, skip_first_n_matches, max_matches, - matches); + matches, descriptions); } // Strip spaces from the line and see if we had only spaces diff --git a/contrib/llvm/tools/lldb/source/Expression/UtilityFunction.cpp b/contrib/llvm/tools/lldb/source/Expression/UtilityFunction.cpp index 52f3bfc4d128..a0a1e4edfb0b 100644 --- a/contrib/llvm/tools/lldb/source/Expression/UtilityFunction.cpp +++ b/contrib/llvm/tools/lldb/source/Expression/UtilityFunction.cpp @@ -7,13 +7,11 @@ // //===----------------------------------------------------------------------===// -// C Includes #include #if HAVE_SYS_TYPES_H #include #endif -// C++ Includes #include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" diff --git a/contrib/llvm/tools/lldb/source/Host/common/Editline.cpp b/contrib/llvm/tools/lldb/source/Host/common/Editline.cpp index 329c0c1f3b70..f7ba4b5822ff 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/Editline.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/Editline.cpp @@ -13,6 +13,7 @@ #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Editline.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" @@ -172,7 +173,8 @@ private: const char *GetHistoryFilePath() { if (m_path.empty() && m_history && !m_prefix.empty()) { - FileSpec parent_path{"~/.lldb", true}; + FileSpec parent_path("~/.lldb"); + FileSystem::Instance().Resolve(parent_path); char history_path[PATH_MAX]; if (!llvm::sys::fs::create_directory(parent_path.GetPath())) { snprintf(history_path, sizeof(history_path), "~/.lldb/%s-history", @@ -181,7 +183,9 @@ private: snprintf(history_path, sizeof(history_path), "~/%s-widehistory", m_prefix.c_str()); } - m_path = FileSpec(history_path, true).GetPath(); + auto file_spec = FileSpec(history_path); + FileSystem::Instance().Resolve(file_spec); + m_path = file_spec.GetPath(); } if (m_path.empty()) return NULL; @@ -426,7 +430,7 @@ unsigned char Editline::RecallHistory(bool earlier) { // Treat moving from the "live" entry differently if (!m_in_history) { - if (earlier == false) + if (!earlier) return CC_ERROR; // Can't go newer than the "live" entry if (history_w(pHistory, &history_event, H_FIRST) == -1) return CC_ERROR; @@ -439,7 +443,7 @@ unsigned char Editline::RecallHistory(bool earlier) { m_live_history_lines = m_input_lines; m_in_history = true; } else { - if (history_w(pHistory, &history_event, earlier ? H_NEXT : H_PREV) == -1) { + if (history_w(pHistory, &history_event, earlier ? H_PREV : H_NEXT) == -1) { // Can't move earlier than the earliest entry if (earlier) return CC_ERROR; @@ -526,7 +530,7 @@ int Editline::GetCharacter(EditLineGetCharType *c) { break; case lldb::eConnectionStatusInterrupted: - lldbassert(0 && "Interrupts should have been handled above."); + llvm_unreachable("Interrupts should have been handled above."); case lldb::eConnectionStatusError: // Check GetError() for details case lldb::eConnectionStatusTimedOut: // Request timed out @@ -853,19 +857,45 @@ unsigned char Editline::BufferEndCommand(int ch) { return CC_NEWLINE; } +//------------------------------------------------------------------------------ +/// Prints completions and their descriptions to the given file. Only the +/// completions in the interval [start, end) are printed. +//------------------------------------------------------------------------------ +static void PrintCompletion(FILE *output_file, size_t start, size_t end, + StringList &completions, StringList &descriptions) { + // This is an 'int' because of printf. + int max_len = 0; + + for (size_t i = start; i < end; i++) { + const char *completion_str = completions.GetStringAtIndex(i); + max_len = std::max((int)strlen(completion_str), max_len); + } + + for (size_t i = start; i < end; i++) { + const char *completion_str = completions.GetStringAtIndex(i); + const char *description_str = descriptions.GetStringAtIndex(i); + + fprintf(output_file, "\n\t%-*s", max_len, completion_str); + + // Print the description if we got one. + if (strlen(description_str)) + fprintf(output_file, " -- %s", description_str); + } +} + unsigned char Editline::TabCommand(int ch) { if (m_completion_callback == nullptr) return CC_ERROR; const LineInfo *line_info = el_line(m_editline); - StringList completions; + StringList completions, descriptions; int page_size = 40; const int num_completions = m_completion_callback( line_info->buffer, line_info->cursor, line_info->lastchar, 0, // Don't skip any matches (start at match zero) -1, // Get all the matches - completions, m_completion_callback_baton); + completions, descriptions, m_completion_callback_baton); if (num_completions == 0) return CC_ERROR; @@ -893,10 +923,8 @@ unsigned char Editline::TabCommand(int ch) { int num_elements = num_completions + 1; fprintf(m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:"); if (num_completions < page_size) { - for (int i = 1; i < num_elements; i++) { - completion_str = completions.GetStringAtIndex(i); - fprintf(m_output_file, "\n\t%s", completion_str); - } + PrintCompletion(m_output_file, 1, num_elements, completions, + descriptions); fprintf(m_output_file, "\n"); } else { int cur_pos = 1; @@ -906,10 +934,10 @@ unsigned char Editline::TabCommand(int ch) { int endpoint = cur_pos + page_size; if (endpoint > num_elements) endpoint = num_elements; - for (; cur_pos < endpoint; cur_pos++) { - completion_str = completions.GetStringAtIndex(cur_pos); - fprintf(m_output_file, "\n\t%s", completion_str); - } + + PrintCompletion(m_output_file, cur_pos, endpoint, completions, + descriptions); + cur_pos = endpoint; if (cur_pos >= num_elements) { fprintf(m_output_file, "\n"); diff --git a/contrib/llvm/tools/lldb/source/Host/common/File.cpp b/contrib/llvm/tools/lldb/source/Host/common/File.cpp index 3c3d55df2207..810c15588402 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/File.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/File.cpp @@ -27,9 +27,10 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" -#include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors() +#include "llvm/Support/Process.h" #include "lldb/Host/Config.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" @@ -71,26 +72,6 @@ static const char *GetStreamOpenModeFromOptions(uint32_t options) { int File::kInvalidDescriptor = -1; FILE *File::kInvalidStream = NULL; -File::File(const char *path, uint32_t options, uint32_t permissions) - : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor), - m_stream(kInvalidStream), m_options(), m_own_stream(false), - m_is_interactive(eLazyBoolCalculate), - m_is_real_terminal(eLazyBoolCalculate) { - Open(path, options, permissions); -} - -File::File(const FileSpec &filespec, uint32_t options, uint32_t permissions) - : IOObject(eFDTypeFile, false), m_descriptor(kInvalidDescriptor), - m_stream(kInvalidStream), m_options(0), m_own_stream(false), - m_is_interactive(eLazyBoolCalculate), - m_is_real_terminal(eLazyBoolCalculate) - -{ - if (filespec) { - Open(filespec.GetPath().c_str(), options, permissions); - } -} - File::~File() { Close(); } int File::GetDescriptor() const { @@ -159,108 +140,6 @@ void File::SetStream(FILE *fh, bool transfer_ownership) { m_own_stream = transfer_ownership; } -static int DoOpen(const char *path, int flags, int mode) { -#ifdef _MSC_VER - std::wstring wpath; - if (!llvm::ConvertUTF8toWide(path, wpath)) - return -1; - int result; - ::_wsopen_s(&result, wpath.c_str(), flags, _SH_DENYNO, mode); - return result; -#else - return ::open(path, flags, mode); -#endif -} - -Status File::Open(const char *path, uint32_t options, uint32_t permissions) { - Status error; - if (IsValid()) - Close(); - - int oflag = 0; - const bool read = options & eOpenOptionRead; - const bool write = options & eOpenOptionWrite; - if (write) { - if (read) - oflag |= O_RDWR; - else - oflag |= O_WRONLY; - - if (options & eOpenOptionAppend) - oflag |= O_APPEND; - - if (options & eOpenOptionTruncate) - oflag |= O_TRUNC; - - if (options & eOpenOptionCanCreate) - oflag |= O_CREAT; - - if (options & eOpenOptionCanCreateNewOnly) - oflag |= O_CREAT | O_EXCL; - } else if (read) { - oflag |= O_RDONLY; - -#ifndef _WIN32 - if (options & eOpenOptionDontFollowSymlinks) - oflag |= O_NOFOLLOW; -#endif - } - -#ifndef _WIN32 - if (options & eOpenOptionNonBlocking) - oflag |= O_NONBLOCK; - if (options & eOpenOptionCloseOnExec) - oflag |= O_CLOEXEC; -#else - oflag |= O_BINARY; -#endif - - mode_t mode = 0; - if (oflag & O_CREAT) { - if (permissions & lldb::eFilePermissionsUserRead) - mode |= S_IRUSR; - if (permissions & lldb::eFilePermissionsUserWrite) - mode |= S_IWUSR; - if (permissions & lldb::eFilePermissionsUserExecute) - mode |= S_IXUSR; - if (permissions & lldb::eFilePermissionsGroupRead) - mode |= S_IRGRP; - if (permissions & lldb::eFilePermissionsGroupWrite) - mode |= S_IWGRP; - if (permissions & lldb::eFilePermissionsGroupExecute) - mode |= S_IXGRP; - if (permissions & lldb::eFilePermissionsWorldRead) - mode |= S_IROTH; - if (permissions & lldb::eFilePermissionsWorldWrite) - mode |= S_IWOTH; - if (permissions & lldb::eFilePermissionsWorldExecute) - mode |= S_IXOTH; - } - - m_descriptor = llvm::sys::RetryAfterSignal(-1, DoOpen, path, oflag, mode); - if (!DescriptorIsValid()) - error.SetErrorToErrno(); - else { - m_should_close_fd = true; - m_options = options; - } - - return error; -} - -uint32_t File::GetPermissions(const FileSpec &file_spec, Status &error) { - if (file_spec) { - error.Clear(); - auto Perms = llvm::sys::fs::getPermissions(file_spec.GetPath()); - if (Perms) - return *Perms; - error = Status(Perms.getError()); - return 0; - } else - error.SetErrorString("empty file spec"); - return 0; -} - uint32_t File::GetPermissions(Status &error) const { int fd = GetDescriptor(); if (fd != kInvalidDescriptor) { @@ -315,7 +194,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const { if (::fcntl(GetDescriptor(), F_GETPATH, path) == -1) error.SetErrorToErrno(); else - file_spec.SetFile(path, false, FileSpec::Style::native); + file_spec.SetFile(path, FileSpec::Style::native); } else { error.SetErrorString("invalid file handle"); } @@ -330,7 +209,7 @@ Status File::GetFileSpec(FileSpec &file_spec) const { error.SetErrorToErrno(); else { path[len] = '\0'; - file_spec.SetFile(path, false, FileSpec::Style::native); + file_spec.SetFile(path, FileSpec::Style::native); } } #else @@ -806,6 +685,9 @@ void File::CalculateInteractiveAndTerminal() { if (_isatty(fd)) { m_is_interactive = eLazyBoolYes; m_is_real_terminal = eLazyBoolYes; +#if defined(ENABLE_VIRTUAL_TERMINAL_PROCESSING) + m_supports_colors = eLazyBoolYes; +#endif } #else if (isatty(fd)) { diff --git a/contrib/llvm/tools/lldb/source/Host/common/FileCache.cpp b/contrib/llvm/tools/lldb/source/Host/common/FileCache.cpp index b4629255c852..17833ef2cbb3 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/FileCache.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/FileCache.cpp @@ -10,6 +10,7 @@ #include "lldb/Host/FileCache.h" #include "lldb/Host/File.h" +#include "lldb/Host/FileSystem.h" using namespace lldb; using namespace lldb_private; @@ -25,14 +26,13 @@ FileCache &FileCache::GetInstance() { lldb::user_id_t FileCache::OpenFile(const FileSpec &file_spec, uint32_t flags, uint32_t mode, Status &error) { - std::string path(file_spec.GetPath()); - if (path.empty()) { + if (!file_spec) { error.SetErrorString("empty path"); return UINT64_MAX; } FileSP file_sp(new File()); - error = file_sp->Open(path.c_str(), flags, mode); - if (file_sp->IsValid() == false) + error = FileSystem::Instance().Open(*file_sp, file_spec, flags, mode); + if (!file_sp->IsValid()) return UINT64_MAX; lldb::user_id_t fd = file_sp->GetDescriptor(); m_cache[fd] = file_sp; diff --git a/contrib/llvm/tools/lldb/source/Host/common/FileSystem.cpp b/contrib/llvm/tools/lldb/source/Host/common/FileSystem.cpp index 4472aece1daa..7191c9db9b2e 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/FileSystem.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/FileSystem.cpp @@ -9,7 +9,29 @@ #include "lldb/Host/FileSystem.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/TildeExpressionResolver.h" + +#include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/Threading.h" + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include "lldb/Host/windows/windows.h" +#else +#include +#include +#include +#include +#endif #include #include @@ -17,12 +39,366 @@ using namespace lldb; using namespace lldb_private; +using namespace llvm; -llvm::sys::TimePoint<> -FileSystem::GetModificationTime(const FileSpec &file_spec) { - llvm::sys::fs::file_status status; - std::error_code ec = llvm::sys::fs::status(file_spec.GetPath(), status); - if (ec) - return llvm::sys::TimePoint<>(); - return status.getLastModificationTime(); +FileSystem &FileSystem::Instance() { return *InstanceImpl(); } + +void FileSystem::Initialize() { + lldbassert(!InstanceImpl() && "Already initialized."); + InstanceImpl().emplace(); +} + +void FileSystem::Initialize(IntrusiveRefCntPtr fs) { + lldbassert(!InstanceImpl() && "Already initialized."); + InstanceImpl().emplace(fs); +} + +void FileSystem::Terminate() { + lldbassert(InstanceImpl() && "Already terminated."); + InstanceImpl().reset(); +} + +Optional &FileSystem::InstanceImpl() { + static Optional g_fs; + return g_fs; +} + +vfs::directory_iterator FileSystem::DirBegin(const FileSpec &file_spec, + std::error_code &ec) { + return DirBegin(file_spec.GetPath(), ec); +} + +vfs::directory_iterator FileSystem::DirBegin(const Twine &dir, + std::error_code &ec) { + return m_fs->dir_begin(dir, ec); +} + +llvm::ErrorOr +FileSystem::GetStatus(const FileSpec &file_spec) const { + return GetStatus(file_spec.GetPath()); +} + +llvm::ErrorOr FileSystem::GetStatus(const Twine &path) const { + return m_fs->status(path); +} + +sys::TimePoint<> +FileSystem::GetModificationTime(const FileSpec &file_spec) const { + return GetModificationTime(file_spec.GetPath()); +} + +sys::TimePoint<> FileSystem::GetModificationTime(const Twine &path) const { + ErrorOr status = m_fs->status(path); + if (!status) + return sys::TimePoint<>(); + return status->getLastModificationTime(); +} + +uint64_t FileSystem::GetByteSize(const FileSpec &file_spec) const { + return GetByteSize(file_spec.GetPath()); +} + +uint64_t FileSystem::GetByteSize(const Twine &path) const { + ErrorOr status = m_fs->status(path); + if (!status) + return 0; + return status->getSize(); +} + +uint32_t FileSystem::GetPermissions(const FileSpec &file_spec) const { + return GetPermissions(file_spec.GetPath()); +} + +uint32_t FileSystem::GetPermissions(const FileSpec &file_spec, + std::error_code &ec) const { + return GetPermissions(file_spec.GetPath(), ec); +} + +uint32_t FileSystem::GetPermissions(const Twine &path) const { + std::error_code ec; + return GetPermissions(path, ec); +} + +uint32_t FileSystem::GetPermissions(const Twine &path, + std::error_code &ec) const { + ErrorOr status = m_fs->status(path); + if (!status) { + ec = status.getError(); + return sys::fs::perms::perms_not_known; + } + return status->getPermissions(); +} + +bool FileSystem::Exists(const Twine &path) const { return m_fs->exists(path); } + +bool FileSystem::Exists(const FileSpec &file_spec) const { + return Exists(file_spec.GetPath()); +} + +bool FileSystem::Readable(const Twine &path) const { + return GetPermissions(path) & sys::fs::perms::all_read; +} + +bool FileSystem::Readable(const FileSpec &file_spec) const { + return Readable(file_spec.GetPath()); +} + +bool FileSystem::IsDirectory(const Twine &path) const { + ErrorOr status = m_fs->status(path); + if (!status) + return false; + return status->isDirectory(); +} + +bool FileSystem::IsDirectory(const FileSpec &file_spec) const { + return IsDirectory(file_spec.GetPath()); +} + +bool FileSystem::IsLocal(const Twine &path) const { + bool b = false; + m_fs->isLocal(path, b); + return b; +} + +bool FileSystem::IsLocal(const FileSpec &file_spec) const { + return IsLocal(file_spec.GetPath()); +} + +void FileSystem::EnumerateDirectory(Twine path, bool find_directories, + bool find_files, bool find_other, + EnumerateDirectoryCallbackType callback, + void *callback_baton) { + std::error_code EC; + vfs::recursive_directory_iterator Iter(*m_fs, path, EC); + vfs::recursive_directory_iterator End; + for (; Iter != End && !EC; Iter.increment(EC)) { + const auto &Item = *Iter; + ErrorOr Status = m_fs->status(Item.path()); + if (!Status) + break; + if (!find_files && Status->isRegularFile()) + continue; + if (!find_directories && Status->isDirectory()) + continue; + if (!find_other && Status->isOther()) + continue; + + auto Result = callback(callback_baton, Status->getType(), Item.path()); + if (Result == eEnumerateDirectoryResultQuit) + return; + if (Result == eEnumerateDirectoryResultNext) { + // Default behavior is to recurse. Opt out if the callback doesn't want + // this behavior. + Iter.no_push(); + } + } +} + +std::error_code FileSystem::MakeAbsolute(SmallVectorImpl &path) const { + return m_fs->makeAbsolute(path); +} + +std::error_code FileSystem::MakeAbsolute(FileSpec &file_spec) const { + SmallString<128> path; + file_spec.GetPath(path, false); + + auto EC = MakeAbsolute(path); + if (EC) + return EC; + + FileSpec new_file_spec(path, file_spec.GetPathStyle()); + file_spec = new_file_spec; + return {}; +} + +std::error_code FileSystem::GetRealPath(const Twine &path, + SmallVectorImpl &output) const { + return m_fs->getRealPath(path, output); +} + +void FileSystem::Resolve(SmallVectorImpl &path) { + if (path.empty()) + return; + + // Resolve tilde. + SmallString<128> original_path(path.begin(), path.end()); + StandardTildeExpressionResolver Resolver; + Resolver.ResolveFullPath(original_path, path); + + // Try making the path absolute if it exists. + SmallString<128> absolute_path(path.begin(), path.end()); + MakeAbsolute(path); + if (!Exists(path)) { + path.clear(); + path.append(original_path.begin(), original_path.end()); + } +} + +void FileSystem::Resolve(FileSpec &file_spec) { + // Extract path from the FileSpec. + SmallString<128> path; + file_spec.GetPath(path); + + // Resolve the path. + Resolve(path); + + // Update the FileSpec with the resolved path. + file_spec.SetPath(path); + file_spec.SetIsResolved(true); +} + +std::shared_ptr +FileSystem::CreateDataBuffer(const llvm::Twine &path, uint64_t size, + uint64_t offset) { + const bool is_volatile = !IsLocal(path); + + std::unique_ptr buffer; + if (size == 0) { + auto buffer_or_error = + llvm::WritableMemoryBuffer::getFile(path, -1, is_volatile); + if (!buffer_or_error) + return nullptr; + buffer = std::move(*buffer_or_error); + } else { + auto buffer_or_error = llvm::WritableMemoryBuffer::getFileSlice( + path, size, offset, is_volatile); + if (!buffer_or_error) + return nullptr; + buffer = std::move(*buffer_or_error); + } + return std::shared_ptr(new DataBufferLLVM(std::move(buffer))); +} + +std::shared_ptr +FileSystem::CreateDataBuffer(const FileSpec &file_spec, uint64_t size, + uint64_t offset) { + return CreateDataBuffer(file_spec.GetPath(), size, offset); +} + +bool FileSystem::ResolveExecutableLocation(FileSpec &file_spec) { + // If the directory is set there's nothing to do. + const ConstString &directory = file_spec.GetDirectory(); + if (directory) + return false; + + // We cannot look for a file if there's no file name. + const ConstString &filename = file_spec.GetFilename(); + if (!filename) + return false; + + // Search for the file on the host. + const std::string filename_str(filename.GetCString()); + llvm::ErrorOr error_or_path = + llvm::sys::findProgramByName(filename_str); + if (!error_or_path) + return false; + + // findProgramByName returns "." if it can't find the file. + llvm::StringRef path = *error_or_path; + llvm::StringRef parent = llvm::sys::path::parent_path(path); + if (parent.empty() || parent == ".") + return false; + + // Make sure that the result exists. + FileSpec result(*error_or_path); + if (!Exists(result)) + return false; + + file_spec = result; + return true; +} + +static int OpenWithFS(const FileSystem &fs, const char *path, int flags, + int mode) { + return const_cast(fs).Open(path, flags, mode); +} + +static int GetOpenFlags(uint32_t options) { + const bool read = options & File::eOpenOptionRead; + const bool write = options & File::eOpenOptionWrite; + + int open_flags = 0; + if (write) { + if (read) + open_flags |= O_RDWR; + else + open_flags |= O_WRONLY; + + if (options & File::eOpenOptionAppend) + open_flags |= O_APPEND; + + if (options & File::eOpenOptionTruncate) + open_flags |= O_TRUNC; + + if (options & File::eOpenOptionCanCreate) + open_flags |= O_CREAT; + + if (options & File::eOpenOptionCanCreateNewOnly) + open_flags |= O_CREAT | O_EXCL; + } else if (read) { + open_flags |= O_RDONLY; + +#ifndef _WIN32 + if (options & File::eOpenOptionDontFollowSymlinks) + open_flags |= O_NOFOLLOW; +#endif + } + +#ifndef _WIN32 + if (options & File::eOpenOptionNonBlocking) + open_flags |= O_NONBLOCK; + if (options & File::eOpenOptionCloseOnExec) + open_flags |= O_CLOEXEC; +#else + open_flags |= O_BINARY; +#endif + + return open_flags; +} + +static mode_t GetOpenMode(uint32_t permissions) { + mode_t mode = 0; + if (permissions & lldb::eFilePermissionsUserRead) + mode |= S_IRUSR; + if (permissions & lldb::eFilePermissionsUserWrite) + mode |= S_IWUSR; + if (permissions & lldb::eFilePermissionsUserExecute) + mode |= S_IXUSR; + if (permissions & lldb::eFilePermissionsGroupRead) + mode |= S_IRGRP; + if (permissions & lldb::eFilePermissionsGroupWrite) + mode |= S_IWGRP; + if (permissions & lldb::eFilePermissionsGroupExecute) + mode |= S_IXGRP; + if (permissions & lldb::eFilePermissionsWorldRead) + mode |= S_IROTH; + if (permissions & lldb::eFilePermissionsWorldWrite) + mode |= S_IWOTH; + if (permissions & lldb::eFilePermissionsWorldExecute) + mode |= S_IXOTH; + return mode; +} + +Status FileSystem::Open(File &File, const FileSpec &file_spec, uint32_t options, + uint32_t permissions) { + if (File.IsValid()) + File.Close(); + + const int open_flags = GetOpenFlags(options); + const mode_t open_mode = + (open_flags & O_CREAT) ? GetOpenMode(permissions) : 0; + const std::string path = file_spec.GetPath(); + + int descriptor = llvm::sys::RetryAfterSignal( + -1, OpenWithFS, *this, path.c_str(), open_flags, open_mode); + + Status error; + if (!File::DescriptorIsValid(descriptor)) { + File.SetDescriptor(descriptor, false); + error.SetErrorToErrno(); + } else { + File.SetDescriptor(descriptor, true); + File.SetOptions(options); + } + return error; } diff --git a/contrib/llvm/tools/lldb/source/Host/common/Host.cpp b/contrib/llvm/tools/lldb/source/Host/common/Host.cpp index d2848254779e..62b936aadef1 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/Host.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/Host.cpp @@ -45,14 +45,13 @@ #include #endif -// C++ Includes #include +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostProcess.h" #include "lldb/Host/MonitoringProcessLauncher.h" -#include "lldb/Host/Predicate.h" #include "lldb/Host/ProcessLauncher.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" @@ -62,6 +61,7 @@ #include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Predicate.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private-forward.h" #include "llvm/ADT/SmallString.h" @@ -419,8 +419,10 @@ FileSpec Host::GetModuleFileSpecForHostAddress(const void *host_addr) { #if !defined(__ANDROID__) Dl_info info; if (::dladdr(host_addr, &info)) { - if (info.dli_fname) - module_filespec.SetFile(info.dli_fname, true, FileSpec::Style::native); + if (info.dli_fname) { + module_filespec.SetFile(info.dli_fname, FileSpec::Style::native); + FileSystem::Instance().Resolve(module_filespec); + } } #endif return module_filespec; @@ -494,7 +496,7 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir, if (working_dir) launch_info.SetWorkingDirectory(working_dir); - llvm::SmallString output_file_path; + llvm::SmallString<64> output_file_path; if (command_output_ptr) { // Create a temporary file to get the stdout/stderr and redirect the output @@ -510,7 +512,7 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir, } } - FileSpec output_file_spec{output_file_path.c_str(), false}; + FileSpec output_file_spec(output_file_path.c_str()); launch_info.AppendSuppressFileAction(STDIN_FILENO, true, false); if (output_file_spec) { @@ -554,14 +556,15 @@ Status Host::RunShellCommand(const Args &args, const FileSpec &working_dir, if (command_output_ptr) { command_output_ptr->clear(); - uint64_t file_size = output_file_spec.GetByteSize(); + uint64_t file_size = + FileSystem::Instance().GetByteSize(output_file_spec); if (file_size > 0) { if (file_size > command_output_ptr->max_size()) { error.SetErrorStringWithFormat( "shell command output is too large to fit into a std::string"); } else { auto Buffer = - DataBufferLLVM::CreateFromPath(output_file_spec.GetPath()); + FileSystem::Instance().CreateDataBuffer(output_file_spec); if (error.Success()) command_output_ptr->assign(Buffer->GetChars(), Buffer->GetByteSize()); diff --git a/contrib/llvm/tools/lldb/source/Host/common/HostInfoBase.cpp b/contrib/llvm/tools/lldb/source/Host/common/HostInfoBase.cpp index 4de6953a91e3..34c362efc9e0 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/HostInfoBase.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/HostInfoBase.cpp @@ -42,7 +42,7 @@ namespace { struct HostInfoBaseFields { ~HostInfoBaseFields() { - if (m_lldb_process_tmp_dir.Exists()) { + if (FileSystem::Instance().Exists(m_lldb_process_tmp_dir)) { // Remove the LLDB temporary directory if we have one. Set "recurse" to // true to all files that were created for the LLDB process can be // cleaned up. @@ -226,7 +226,7 @@ bool HostInfoBase::ComputeSharedLibraryDirectory(FileSpec &file_spec) { // This is necessary because when running the testsuite the shlib might be a // symbolic link inside the Python resource dir. - FileSystem::ResolveSymbolicLink(lldb_file_spec, lldb_file_spec); + FileSystem::Instance().ResolveSymbolicLink(lldb_file_spec, lldb_file_spec); // Remove the filename so that this FileSpec only represents the directory. file_spec.GetDirectory() = lldb_file_spec.GetDirectory(); @@ -256,7 +256,8 @@ bool HostInfoBase::ComputeProcessTempFileDirectory(FileSpec &file_spec) { bool HostInfoBase::ComputeTempFileBaseDirectory(FileSpec &file_spec) { llvm::SmallVector tmpdir; llvm::sys::path::system_temp_directory(/*ErasedOnReboot*/ true, tmpdir); - file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size()), true); + file_spec = FileSpec(std::string(tmpdir.data(), tmpdir.size())); + FileSystem::Instance().Resolve(file_spec); return true; } diff --git a/contrib/llvm/tools/lldb/source/Host/common/HostNativeThreadBase.cpp b/contrib/llvm/tools/lldb/source/Host/common/HostNativeThreadBase.cpp index 402d3caacfcb..25c8066bb1a3 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/HostNativeThreadBase.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/HostNativeThreadBase.cpp @@ -41,6 +41,10 @@ void HostNativeThreadBase::Reset() { m_result = 0; } +bool HostNativeThreadBase::EqualsThread(lldb::thread_t thread) const { + return m_thread == thread; +} + lldb::thread_t HostNativeThreadBase::Release() { lldb::thread_t result = m_thread; m_thread = LLDB_INVALID_HOST_THREAD; diff --git a/contrib/llvm/tools/lldb/source/Host/common/HostThread.cpp b/contrib/llvm/tools/lldb/source/Host/common/HostThread.cpp index 02882c523908..2bf6f0a933d8 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/HostThread.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/HostThread.cpp @@ -43,5 +43,5 @@ lldb::thread_result_t HostThread::GetResult() const { } bool HostThread::EqualsThread(lldb::thread_t thread) const { - return m_native_thread->GetSystemHandle() == thread; + return m_native_thread->EqualsThread(thread); } diff --git a/contrib/llvm/tools/lldb/source/Host/common/MainLoop.cpp b/contrib/llvm/tools/lldb/source/Host/common/MainLoop.cpp index 65158c942934..39c353e6717e 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/MainLoop.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/MainLoop.cpp @@ -309,7 +309,7 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) { g_signal_flags[signo] = 0; // Even if using kqueue, the signal handler will still be invoked, so it's - // important to replace it with our "bening" handler. + // important to replace it with our "benign" handler. int ret = sigaction(signo, &new_action, &info.old_action); assert(ret == 0 && "sigaction failed"); @@ -321,7 +321,7 @@ MainLoop::RegisterSignal(int signo, const Callback &callback, Status &error) { #endif // If we're using kqueue, the signal needs to be unblocked in order to - // recieve it. If using pselect/ppoll, we need to block it, and later unblock + // receive it. If using pselect/ppoll, we need to block it, and later unblock // it as a part of the system call. ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK, &new_action.sa_mask, &old_set); diff --git a/contrib/llvm/tools/lldb/source/Host/common/MonitoringProcessLauncher.cpp b/contrib/llvm/tools/lldb/source/Host/common/MonitoringProcessLauncher.cpp index 76c11454f573..f6f772cb3679 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/MonitoringProcessLauncher.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/MonitoringProcessLauncher.cpp @@ -8,10 +8,10 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/MonitoringProcessLauncher.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostProcess.h" #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Status.h" #include "llvm/Support/FileSystem.h" @@ -29,20 +29,16 @@ MonitoringProcessLauncher::LaunchProcess(const ProcessLaunchInfo &launch_info, error.Clear(); + FileSystem &fs = FileSystem::Instance(); FileSpec exe_spec(resolved_info.GetExecutableFile()); - llvm::sys::fs::file_status stats; - status(exe_spec.GetPath(), stats); - if (!exists(stats)) { - exe_spec.ResolvePath(); - status(exe_spec.GetPath(), stats); - } - if (!exists(stats)) { - exe_spec.ResolveExecutableLocation(); - status(exe_spec.GetPath(), stats); - } + if (!fs.Exists(exe_spec)) + FileSystem::Instance().Resolve(exe_spec); - if (!exists(stats)) { + if (!fs.Exists(exe_spec)) + FileSystem::Instance().ResolveExecutableLocation(exe_spec); + + if (!fs.Exists(exe_spec)) { error.SetErrorStringWithFormatv("executable doesn't exist: '{0}'", exe_spec); return HostProcess(); diff --git a/contrib/llvm/tools/lldb/source/Host/common/NativeBreakpoint.cpp b/contrib/llvm/tools/lldb/source/Host/common/NativeBreakpoint.cpp deleted file mode 100644 index 5eee3de482c1..000000000000 --- a/contrib/llvm/tools/lldb/source/Host/common/NativeBreakpoint.cpp +++ /dev/null @@ -1,109 +0,0 @@ -//===-- NativeBreakpoint.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Host/common/NativeBreakpoint.h" - -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Status.h" -#include "lldb/lldb-defines.h" - -using namespace lldb_private; - -NativeBreakpoint::NativeBreakpoint(lldb::addr_t addr) - : m_addr(addr), m_ref_count(1), m_enabled(true) { - assert(addr != LLDB_INVALID_ADDRESS && "breakpoint set for invalid address"); -} - -NativeBreakpoint::~NativeBreakpoint() {} - -void NativeBreakpoint::AddRef() { - ++m_ref_count; - - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 - " bumped up, new ref count %" PRIu32, - __FUNCTION__, m_addr, m_ref_count); -} - -int32_t NativeBreakpoint::DecRef() { - --m_ref_count; - - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 - " ref count decremented, new ref count %" PRIu32, - __FUNCTION__, m_addr, m_ref_count); - - return m_ref_count; -} - -Status NativeBreakpoint::Enable() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - - if (m_enabled) { - // We're already enabled. Just log and exit. - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 - " already enabled, ignoring.", - __FUNCTION__, m_addr); - return Status(); - } - - // Log and enable. - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " enabling...", - __FUNCTION__, m_addr); - - Status error = DoEnable(); - if (error.Success()) { - m_enabled = true; - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " enable SUCCESS.", - __FUNCTION__, m_addr); - } else { - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " enable FAIL: %s", - __FUNCTION__, m_addr, error.AsCString()); - } - - return error; -} - -Status NativeBreakpoint::Disable() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - - if (!m_enabled) { - // We're already disabled. Just log and exit. - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 - " already disabled, ignoring.", - __FUNCTION__, m_addr); - return Status(); - } - - // Log and disable. - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " disabling...", - __FUNCTION__, m_addr); - - Status error = DoDisable(); - if (error.Success()) { - m_enabled = false; - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " disable SUCCESS.", - __FUNCTION__, m_addr); - } else { - if (log) - log->Printf("NativeBreakpoint::%s addr = 0x%" PRIx64 " disable FAIL: %s", - __FUNCTION__, m_addr, error.AsCString()); - } - - return error; -} diff --git a/contrib/llvm/tools/lldb/source/Host/common/NativeBreakpointList.cpp b/contrib/llvm/tools/lldb/source/Host/common/NativeBreakpointList.cpp deleted file mode 100644 index cfcbe0831064..000000000000 --- a/contrib/llvm/tools/lldb/source/Host/common/NativeBreakpointList.cpp +++ /dev/null @@ -1,229 +0,0 @@ -//===-- NativeBreakpointList.cpp --------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Host/common/NativeBreakpointList.h" - -#include "lldb/Utility/Log.h" - -#include "lldb/Host/common/NativeBreakpoint.h" -#include "lldb/Host/common/SoftwareBreakpoint.h" - -using namespace lldb; -using namespace lldb_private; - -NativeBreakpointList::NativeBreakpointList() : m_mutex() {} - -Status NativeBreakpointList::AddRef(lldb::addr_t addr, size_t size_hint, - bool hardware, - CreateBreakpointFunc create_func) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 - ", size_hint = %zu, hardware = %s", - __FUNCTION__, addr, size_hint, hardware ? "true" : "false"); - - std::lock_guard guard(m_mutex); - - // Check if the breakpoint is already set. - auto iter = m_breakpoints.find(addr); - if (iter != m_breakpoints.end()) { - // Yes - bump up ref count. - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 - " -- already enabled, upping ref count", - __FUNCTION__, addr); - - iter->second->AddRef(); - return Status(); - } - - // Create a new breakpoint using the given create func. - if (log) - log->Printf( - "NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 - ", size_hint = %zu, hardware = %s", - __FUNCTION__, addr, size_hint, hardware ? "true" : "false"); - - NativeBreakpointSP breakpoint_sp; - Status error = create_func(addr, size_hint, hardware, breakpoint_sp); - if (error.Fail()) { - if (log) - log->Printf( - "NativeBreakpointList::%s creating breakpoint for addr = 0x%" PRIx64 - ", size_hint = %zu, hardware = %s -- FAILED: %s", - __FUNCTION__, addr, size_hint, hardware ? "true" : "false", - error.AsCString()); - return error; - } - - // Remember the breakpoint. - assert(breakpoint_sp && "NativeBreakpoint create function succeeded but " - "returned NULL breakpoint"); - m_breakpoints.insert(BreakpointMap::value_type(addr, breakpoint_sp)); - - return error; -} - -Status NativeBreakpointList::DecRef(lldb::addr_t addr) { - Status error; - - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, - addr); - - std::lock_guard guard(m_mutex); - - // Check if the breakpoint is already set. - auto iter = m_breakpoints.find(addr); - if (iter == m_breakpoints.end()) { - // Not found! - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", - __FUNCTION__, addr); - error.SetErrorString("breakpoint not found"); - return error; - } - - // Decrement ref count. - const int32_t new_ref_count = iter->second->DecRef(); - assert(new_ref_count >= 0 && "NativeBreakpoint ref count went negative"); - - if (new_ref_count > 0) { - // Still references to this breakpoint. Leave it alone. - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 - " -- new breakpoint ref count %" PRIu32, - __FUNCTION__, addr, new_ref_count); - return error; - } - - // Breakpoint has no more references. Disable it if it's not already - // disabled. - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 - " -- removing due to no remaining references", - __FUNCTION__, addr); - - // If it's enabled, we need to disable it. - if (iter->second->IsEnabled()) { - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 - " -- currently enabled, now disabling", - __FUNCTION__, addr); - error = iter->second->Disable(); - if (error.Fail()) { - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 - " -- removal FAILED: %s", - __FUNCTION__, addr, error.AsCString()); - // Continue since we still want to take it out of the breakpoint list. - } - } else { - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 - " -- already disabled, nothing to do", - __FUNCTION__, addr); - } - - // Take the breakpoint out of the list. - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 - " -- removed from breakpoint map", - __FUNCTION__, addr); - - m_breakpoints.erase(iter); - return error; -} - -Status NativeBreakpointList::EnableBreakpoint(lldb::addr_t addr) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, - addr); - - std::lock_guard guard(m_mutex); - - // Ensure we have said breakpoint. - auto iter = m_breakpoints.find(addr); - if (iter == m_breakpoints.end()) { - // Not found! - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", - __FUNCTION__, addr); - return Status("breakpoint not found"); - } - - // Enable it. - return iter->second->Enable(); -} - -Status NativeBreakpointList::DisableBreakpoint(lldb::addr_t addr) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, - addr); - - std::lock_guard guard(m_mutex); - - // Ensure we have said breakpoint. - auto iter = m_breakpoints.find(addr); - if (iter == m_breakpoints.end()) { - // Not found! - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64 " -- NOT FOUND", - __FUNCTION__, addr); - return Status("breakpoint not found"); - } - - // Disable it. - return iter->second->Disable(); -} - -Status NativeBreakpointList::GetBreakpoint(lldb::addr_t addr, - NativeBreakpointSP &breakpoint_sp) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("NativeBreakpointList::%s addr = 0x%" PRIx64, __FUNCTION__, - addr); - - std::lock_guard guard(m_mutex); - - // Ensure we have said breakpoint. - auto iter = m_breakpoints.find(addr); - if (iter == m_breakpoints.end()) { - // Not found! - breakpoint_sp.reset(); - return Status("breakpoint not found"); - } - - // Disable it. - breakpoint_sp = iter->second; - return Status(); -} - -Status NativeBreakpointList::RemoveTrapsFromBuffer(lldb::addr_t addr, void *buf, - size_t size) const { - for (const auto &map : m_breakpoints) { - lldb::addr_t bp_addr = map.first; - // Breapoint not in range, ignore - if (bp_addr < addr || addr + size <= bp_addr) - continue; - const auto &bp_sp = map.second; - // Not software breakpoint, ignore - if (!bp_sp->IsSoftwareBreakpoint()) - continue; - auto software_bp_sp = std::static_pointer_cast(bp_sp); - auto opcode_addr = static_cast(buf) + bp_addr - addr; - auto saved_opcodes = software_bp_sp->m_saved_opcodes; - auto opcode_size = software_bp_sp->m_opcode_size; - ::memcpy(opcode_addr, saved_opcodes, opcode_size); - } - return Status(); -} diff --git a/contrib/llvm/tools/lldb/source/Host/common/NativeProcessProtocol.cpp b/contrib/llvm/tools/lldb/source/Host/common/NativeProcessProtocol.cpp index 3e8648f81473..e3c81f6c147b 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/NativeProcessProtocol.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/NativeProcessProtocol.cpp @@ -8,13 +8,13 @@ //===----------------------------------------------------------------------===// #include "lldb/Host/common/NativeProcessProtocol.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" +#include "lldb/Host/common/NativeBreakpointList.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/common/NativeThreadProtocol.h" -#include "lldb/Host/common/SoftwareBreakpoint.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/lldb-enumerations.h" using namespace lldb; @@ -359,17 +359,271 @@ void NativeProcessProtocol::NotifyDidExec() { Status NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint) { Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("NativeProcessProtocol::%s addr = 0x%" PRIx64, __FUNCTION__, - addr); + LLDB_LOG(log, "addr = {0:x}, size_hint = {1}", addr, size_hint); - return m_breakpoint_list.AddRef( - addr, size_hint, false, - [this](lldb::addr_t addr, size_t size_hint, bool /* hardware */, - NativeBreakpointSP &breakpoint_sp) -> Status { - return SoftwareBreakpoint::CreateSoftwareBreakpoint( - *this, addr, size_hint, breakpoint_sp); - }); + auto it = m_software_breakpoints.find(addr); + if (it != m_software_breakpoints.end()) { + ++it->second.ref_count; + return Status(); + } + auto expected_bkpt = EnableSoftwareBreakpoint(addr, size_hint); + if (!expected_bkpt) + return Status(expected_bkpt.takeError()); + + m_software_breakpoints.emplace(addr, std::move(*expected_bkpt)); + return Status(); +} + +Status NativeProcessProtocol::RemoveSoftwareBreakpoint(lldb::addr_t addr) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + LLDB_LOG(log, "addr = {0:x}", addr); + auto it = m_software_breakpoints.find(addr); + if (it == m_software_breakpoints.end()) + return Status("Breakpoint not found."); + assert(it->second.ref_count > 0); + if (--it->second.ref_count > 0) + return Status(); + + // This is the last reference. Let's remove the breakpoint. + Status error; + + // Clear a software breakpoint instruction + llvm::SmallVector curr_break_op( + it->second.breakpoint_opcodes.size(), 0); + + // Read the breakpoint opcode + size_t bytes_read = 0; + error = + ReadMemory(addr, curr_break_op.data(), curr_break_op.size(), bytes_read); + if (error.Fail() || bytes_read < curr_break_op.size()) { + return Status("addr=0x%" PRIx64 + ": tried to read %zu bytes but only read %zu", + addr, curr_break_op.size(), bytes_read); + } + const auto &saved = it->second.saved_opcodes; + // Make sure the breakpoint opcode exists at this address + if (makeArrayRef(curr_break_op) != it->second.breakpoint_opcodes) { + if (curr_break_op != it->second.saved_opcodes) + return Status("Original breakpoint trap is no longer in memory."); + LLDB_LOG(log, + "Saved opcodes ({0:@[x]}) have already been restored at {1:x}.", + llvm::make_range(saved.begin(), saved.end()), addr); + } else { + // We found a valid breakpoint opcode at this address, now restore the + // saved opcode. + size_t bytes_written = 0; + error = WriteMemory(addr, saved.data(), saved.size(), bytes_written); + if (error.Fail() || bytes_written < saved.size()) { + return Status("addr=0x%" PRIx64 + ": tried to write %zu bytes but only wrote %zu", + addr, saved.size(), bytes_written); + } + + // Verify that our original opcode made it back to the inferior + llvm::SmallVector verify_opcode(saved.size(), 0); + size_t verify_bytes_read = 0; + error = ReadMemory(addr, verify_opcode.data(), verify_opcode.size(), + verify_bytes_read); + if (error.Fail() || verify_bytes_read < verify_opcode.size()) { + return Status("addr=0x%" PRIx64 + ": tried to read %zu verification bytes but only read %zu", + addr, verify_opcode.size(), verify_bytes_read); + } + if (verify_opcode != saved) + LLDB_LOG(log, "Restoring bytes at {0:x}: {1:@[x]}", addr, + llvm::make_range(saved.begin(), saved.end())); + } + + m_software_breakpoints.erase(it); + return Status(); +} + +llvm::Expected +NativeProcessProtocol::EnableSoftwareBreakpoint(lldb::addr_t addr, + uint32_t size_hint) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + + auto expected_trap = GetSoftwareBreakpointTrapOpcode(size_hint); + if (!expected_trap) + return expected_trap.takeError(); + + llvm::SmallVector saved_opcode_bytes(expected_trap->size(), 0); + // Save the original opcodes by reading them so we can restore later. + size_t bytes_read = 0; + Status error = ReadMemory(addr, saved_opcode_bytes.data(), + saved_opcode_bytes.size(), bytes_read); + if (error.Fail()) + return error.ToError(); + + // Ensure we read as many bytes as we expected. + if (bytes_read != saved_opcode_bytes.size()) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Failed to read memory while attempting to set breakpoint: attempted " + "to read {0} bytes but only read {1}.", + saved_opcode_bytes.size(), bytes_read); + } + + LLDB_LOG( + log, "Overwriting bytes at {0:x}: {1:@[x]}", addr, + llvm::make_range(saved_opcode_bytes.begin(), saved_opcode_bytes.end())); + + // Write a software breakpoint in place of the original opcode. + size_t bytes_written = 0; + error = WriteMemory(addr, expected_trap->data(), expected_trap->size(), + bytes_written); + if (error.Fail()) + return error.ToError(); + + // Ensure we wrote as many bytes as we expected. + if (bytes_written != expected_trap->size()) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Failed write memory while attempting to set " + "breakpoint: attempted to write {0} bytes but only wrote {1}", + expected_trap->size(), bytes_written); + } + + llvm::SmallVector verify_bp_opcode_bytes(expected_trap->size(), + 0); + size_t verify_bytes_read = 0; + error = ReadMemory(addr, verify_bp_opcode_bytes.data(), + verify_bp_opcode_bytes.size(), verify_bytes_read); + if (error.Fail()) + return error.ToError(); + + // Ensure we read as many verification bytes as we expected. + if (verify_bytes_read != verify_bp_opcode_bytes.size()) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Failed to read memory while " + "attempting to verify breakpoint: attempted to read {0} bytes " + "but only read {1}", + verify_bp_opcode_bytes.size(), verify_bytes_read); + } + + if (llvm::makeArrayRef(verify_bp_opcode_bytes.data(), verify_bytes_read) != + *expected_trap) { + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Verification of software breakpoint " + "writing failed - trap opcodes not successfully read back " + "after writing when setting breakpoint at {0:x}", + addr); + } + + LLDB_LOG(log, "addr = {0:x}: SUCCESS", addr); + return SoftwareBreakpoint{1, saved_opcode_bytes, *expected_trap}; +} + +llvm::Expected> +NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { + static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4}; + static const uint8_t g_i386_opcode[] = {0xCC}; + static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d}; + static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00}; + static const uint8_t g_s390x_opcode[] = {0x00, 0x01}; + static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap + + switch (GetArchitecture().GetMachine()) { + case llvm::Triple::aarch64: + return llvm::makeArrayRef(g_aarch64_opcode); + + case llvm::Triple::x86: + case llvm::Triple::x86_64: + return llvm::makeArrayRef(g_i386_opcode); + + case llvm::Triple::mips: + case llvm::Triple::mips64: + return llvm::makeArrayRef(g_mips64_opcode); + + case llvm::Triple::mipsel: + case llvm::Triple::mips64el: + return llvm::makeArrayRef(g_mips64el_opcode); + + case llvm::Triple::systemz: + return llvm::makeArrayRef(g_s390x_opcode); + + case llvm::Triple::ppc64le: + return llvm::makeArrayRef(g_ppc64le_opcode); + + default: + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "CPU type not supported!"); + } +} + +size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() { + switch (GetArchitecture().GetMachine()) { + case llvm::Triple::x86: + case llvm::Triple::x86_64: + case llvm::Triple::systemz: + // These architectures report increment the PC after breakpoint is hit. + return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size(); + + case llvm::Triple::arm: + case llvm::Triple::aarch64: + case llvm::Triple::mips64: + case llvm::Triple::mips64el: + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::ppc64le: + // On these architectures the PC doesn't get updated for breakpoint hits. + return 0; + + default: + llvm_unreachable("CPU type not supported!"); + } +} + +void NativeProcessProtocol::FixupBreakpointPCAsNeeded( + NativeThreadProtocol &thread) { + Log *log = GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS); + + Status error; + + // Find out the size of a breakpoint (might depend on where we are in the + // code). + NativeRegisterContext &context = thread.GetRegisterContext(); + + uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset(); + LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); + if (breakpoint_size == 0) + return; + + // First try probing for a breakpoint at a software breakpoint location: PC - + // breakpoint size. + const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation(); + lldb::addr_t breakpoint_addr = initial_pc_addr; + // Do not allow breakpoint probe to wrap around. + if (breakpoint_addr >= breakpoint_size) + breakpoint_addr -= breakpoint_size; + + if (m_software_breakpoints.count(breakpoint_addr) == 0) { + // We didn't find one at a software probe location. Nothing to do. + LLDB_LOG(log, + "pid {0} no lldb software breakpoint found at current pc with " + "adjustment: {1}", + GetID(), breakpoint_addr); + return; + } + + // + // We have a software breakpoint and need to adjust the PC. + // + + // Change the program counter. + LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(), + thread.GetID(), initial_pc_addr, breakpoint_addr); + + error = context.SetPC(breakpoint_addr); + if (error.Fail()) { + // This can happen in case the process was killed between the time we read + // the PC and when we are updating it. There's nothing better to do than to + // swallow the error. + LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(), + thread.GetID(), error); + } } Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr, @@ -377,15 +631,35 @@ Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr, if (hardware) return RemoveHardwareBreakpoint(addr); else - return m_breakpoint_list.DecRef(addr); + return RemoveSoftwareBreakpoint(addr); } -Status NativeProcessProtocol::EnableBreakpoint(lldb::addr_t addr) { - return m_breakpoint_list.EnableBreakpoint(addr); -} +Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr, + void *buf, size_t size, + size_t &bytes_read) { + Status error = ReadMemory(addr, buf, size, bytes_read); + if (error.Fail()) + return error; -Status NativeProcessProtocol::DisableBreakpoint(lldb::addr_t addr) { - return m_breakpoint_list.DisableBreakpoint(addr); + auto data = + llvm::makeMutableArrayRef(static_cast(buf), bytes_read); + for (const auto &pair : m_software_breakpoints) { + lldb::addr_t bp_addr = pair.first; + auto saved_opcodes = makeArrayRef(pair.second.saved_opcodes); + + if (bp_addr + saved_opcodes.size() < addr || addr + bytes_read <= bp_addr) + continue; // Breapoint not in range, ignore + + if (bp_addr < addr) { + saved_opcodes = saved_opcodes.drop_front(addr - bp_addr); + bp_addr = addr; + } + auto bp_data = data.drop_front(bp_addr - addr); + std::copy_n(saved_opcodes.begin(), + std::min(saved_opcodes.size(), bp_data.size()), + bp_data.begin()); + } + return Status(); } lldb::StateType NativeProcessProtocol::GetState() const { diff --git a/contrib/llvm/tools/lldb/source/Host/common/NativeRegisterContext.cpp b/contrib/llvm/tools/lldb/source/Host/common/NativeRegisterContext.cpp index 49b8284da970..6e6632aa710f 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/NativeRegisterContext.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/NativeRegisterContext.cpp @@ -9,8 +9,8 @@ #include "lldb/Host/common/NativeRegisterContext.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Host/PosixApi.h" #include "lldb/Host/common/NativeProcessProtocol.h" diff --git a/contrib/llvm/tools/lldb/source/Host/common/NativeThreadProtocol.cpp b/contrib/llvm/tools/lldb/source/Host/common/NativeThreadProtocol.cpp index 0c648e40eb5c..af43683295b0 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/NativeThreadProtocol.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/NativeThreadProtocol.cpp @@ -11,7 +11,6 @@ #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/Host/common/NativeRegisterContext.h" -#include "lldb/Host/common/SoftwareBreakpoint.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Host/common/ProcessRunLock.cpp b/contrib/llvm/tools/lldb/source/Host/common/ProcessRunLock.cpp index 48dcd62bb939..e0ba2ecfd3e9 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/ProcessRunLock.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/ProcessRunLock.cpp @@ -30,7 +30,7 @@ ProcessRunLock::~ProcessRunLock() { bool ProcessRunLock::ReadTryLock() { ::pthread_rwlock_rdlock(&m_rwlock); - if (m_running == false) { + if (!m_running) { return true; } ::pthread_rwlock_unlock(&m_rwlock); diff --git a/contrib/llvm/tools/lldb/source/Host/common/PseudoTerminal.cpp b/contrib/llvm/tools/lldb/source/Host/common/PseudoTerminal.cpp index c9b290078e18..08d4fa218968 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/PseudoTerminal.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/PseudoTerminal.cpp @@ -10,7 +10,8 @@ #include "lldb/Host/PseudoTerminal.h" #include "lldb/Host/Config.h" -#include +#include "llvm/Support/Errno.h" + #include #include #include @@ -26,6 +27,14 @@ int posix_openpt(int flags); using namespace lldb_private; +//---------------------------------------------------------------------- +// Write string describing error number +//---------------------------------------------------------------------- +static void ErrnoToStr(char *error_str, size_t error_len) { + std::string strerror = llvm::sys::StrError(); + ::snprintf(error_str, error_len, "%s", strerror.c_str()); +} + //---------------------------------------------------------------------- // PseudoTerminal constructor //---------------------------------------------------------------------- @@ -88,14 +97,14 @@ bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str, m_master_fd = ::posix_openpt(oflag); if (m_master_fd < 0) { if (error_str) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); return false; } // Grant access to the slave pseudo terminal if (::grantpt(m_master_fd) < 0) { if (error_str) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); CloseMasterFileDescriptor(); return false; } @@ -103,7 +112,7 @@ bool PseudoTerminal::OpenFirstAvailableMaster(int oflag, char *error_str, // Clear the lock flag on the slave pseudo terminal if (::unlockpt(m_master_fd) < 0) { if (error_str) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); CloseMasterFileDescriptor(); return false; } @@ -143,7 +152,7 @@ bool PseudoTerminal::OpenSlave(int oflag, char *error_str, size_t error_len) { if (m_slave_fd < 0) { if (error_str) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); return false; } @@ -175,7 +184,7 @@ const char *PseudoTerminal::GetSlaveName(char *error_str, const char *slave_name = ::ptsname(m_master_fd); if (error_str && slave_name == nullptr) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); return slave_name; } @@ -213,7 +222,7 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) { if (pid < 0) { // Fork failed if (error_str) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); } else if (pid == 0) { // Child Process ::setsid(); @@ -229,23 +238,23 @@ lldb::pid_t PseudoTerminal::Fork(char *error_str, size_t error_len) { // Acquire the controlling terminal if (::ioctl(m_slave_fd, TIOCSCTTY, (char *)0) < 0) { if (error_str) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); } #endif // Duplicate all stdio file descriptors to the slave pseudo terminal if (::dup2(m_slave_fd, STDIN_FILENO) != STDIN_FILENO) { if (error_str && !error_str[0]) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); } if (::dup2(m_slave_fd, STDOUT_FILENO) != STDOUT_FILENO) { if (error_str && !error_str[0]) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); } if (::dup2(m_slave_fd, STDERR_FILENO) != STDERR_FILENO) { if (error_str && !error_str[0]) - ::strerror_r(errno, error_str, error_len); + ErrnoToStr(error_str, error_len); } } } else { diff --git a/contrib/llvm/tools/lldb/source/Host/common/SocketAddress.cpp b/contrib/llvm/tools/lldb/source/Host/common/SocketAddress.cpp index def3e0359f01..172cb06a5819 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/SocketAddress.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/SocketAddress.cpp @@ -21,7 +21,6 @@ #include #include -// C Includes #if !defined(_WIN32) #include #endif @@ -29,9 +28,6 @@ #include #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/PosixApi.h" // WindowsXP needs an inet_ntop implementation diff --git a/contrib/llvm/tools/lldb/source/Host/common/SoftwareBreakpoint.cpp b/contrib/llvm/tools/lldb/source/Host/common/SoftwareBreakpoint.cpp deleted file mode 100644 index 353dadf6ce6d..000000000000 --- a/contrib/llvm/tools/lldb/source/Host/common/SoftwareBreakpoint.cpp +++ /dev/null @@ -1,350 +0,0 @@ -//===-- SoftwareBreakpoint.cpp ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Host/common/SoftwareBreakpoint.h" - -#include "lldb/Host/Debug.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Status.h" - -#include "lldb/Host/common/NativeProcessProtocol.h" - -using namespace lldb_private; - -// ------------------------------------------------------------------- static -// members ------------------------------------------------------------------- - -Status SoftwareBreakpoint::CreateSoftwareBreakpoint( - NativeProcessProtocol &process, lldb::addr_t addr, size_t size_hint, - NativeBreakpointSP &breakpoint_sp) { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr); - - // Validate the address. - if (addr == LLDB_INVALID_ADDRESS) - return Status("SoftwareBreakpoint::%s invalid load address specified.", - __FUNCTION__); - - // Ask the NativeProcessProtocol subclass to fill in the correct software - // breakpoint trap for the breakpoint site. - size_t bp_opcode_size = 0; - const uint8_t *bp_opcode_bytes = NULL; - Status error = process.GetSoftwareBreakpointTrapOpcode( - size_hint, bp_opcode_size, bp_opcode_bytes); - - if (error.Fail()) { - if (log) - log->Printf("SoftwareBreakpoint::%s failed to retrieve software " - "breakpoint trap opcode: %s", - __FUNCTION__, error.AsCString()); - return error; - } - - // Validate size of trap opcode. - if (bp_opcode_size == 0) { - if (log) - log->Printf("SoftwareBreakpoint::%s failed to retrieve any trap opcodes", - __FUNCTION__); - return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() " - "returned zero, unable to get breakpoint trap for address " - "0x%" PRIx64, - addr); - } - - if (bp_opcode_size > MAX_TRAP_OPCODE_SIZE) { - if (log) - log->Printf("SoftwareBreakpoint::%s cannot support %zu trapcode bytes, " - "max size is %zu", - __FUNCTION__, bp_opcode_size, MAX_TRAP_OPCODE_SIZE); - return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() " - "returned too many trap opcode bytes: requires %zu but we " - "only support a max of %zu", - bp_opcode_size, MAX_TRAP_OPCODE_SIZE); - } - - // Validate that we received opcodes. - if (!bp_opcode_bytes) { - if (log) - log->Printf("SoftwareBreakpoint::%s failed to retrieve trap opcode bytes", - __FUNCTION__); - return Status("SoftwareBreakpoint::GetSoftwareBreakpointTrapOpcode() " - "returned NULL trap opcode bytes, unable to get breakpoint " - "trap for address 0x%" PRIx64, - addr); - } - - // Enable the breakpoint. - uint8_t saved_opcode_bytes[MAX_TRAP_OPCODE_SIZE]; - error = EnableSoftwareBreakpoint(process, addr, bp_opcode_size, - bp_opcode_bytes, saved_opcode_bytes); - if (error.Fail()) { - if (log) - log->Printf("SoftwareBreakpoint::%s: failed to enable new breakpoint at " - "0x%" PRIx64 ": %s", - __FUNCTION__, addr, error.AsCString()); - return error; - } - - if (log) - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS", - __FUNCTION__, addr); - - // Set the breakpoint and verified it was written properly. Now create a - // breakpoint remover that understands how to undo this breakpoint. - breakpoint_sp.reset(new SoftwareBreakpoint(process, addr, saved_opcode_bytes, - bp_opcode_bytes, bp_opcode_size)); - return Status(); -} - -Status SoftwareBreakpoint::EnableSoftwareBreakpoint( - NativeProcessProtocol &process, lldb::addr_t addr, size_t bp_opcode_size, - const uint8_t *bp_opcode_bytes, uint8_t *saved_opcode_bytes) { - assert(bp_opcode_size <= MAX_TRAP_OPCODE_SIZE && - "bp_opcode_size out of valid range"); - assert(bp_opcode_bytes && "bp_opcode_bytes is NULL"); - assert(saved_opcode_bytes && "saved_opcode_bytes is NULL"); - - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, addr); - - // Save the original opcodes by reading them so we can restore later. - size_t bytes_read = 0; - - Status error = - process.ReadMemory(addr, saved_opcode_bytes, bp_opcode_size, bytes_read); - if (error.Fail()) { - if (log) - log->Printf("SoftwareBreakpoint::%s failed to read memory while " - "attempting to set breakpoint: %s", - __FUNCTION__, error.AsCString()); - return error; - } - - // Ensure we read as many bytes as we expected. - if (bytes_read != bp_opcode_size) { - if (log) - log->Printf("SoftwareBreakpoint::%s failed to read memory while " - "attempting to set breakpoint: attempted to read %zu bytes " - "but only read %zu", - __FUNCTION__, bp_opcode_size, bytes_read); - return Status("SoftwareBreakpoint::%s failed to read memory while " - "attempting to set breakpoint: attempted to read %zu bytes " - "but only read %zu", - __FUNCTION__, bp_opcode_size, bytes_read); - } - - // Log what we read. - if (log) { - int i = 0; - for (const uint8_t *read_byte = saved_opcode_bytes; - read_byte < saved_opcode_bytes + bp_opcode_size; ++read_byte) { - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 - " ovewriting byte index %d (was 0x%hhx)", - __FUNCTION__, addr, i++, *read_byte); - } - } - - // Write a software breakpoint in place of the original opcode. - size_t bytes_written = 0; - error = - process.WriteMemory(addr, bp_opcode_bytes, bp_opcode_size, bytes_written); - if (error.Fail()) { - if (log) - log->Printf("SoftwareBreakpoint::%s failed to write memory while " - "attempting to set breakpoint: %s", - __FUNCTION__, error.AsCString()); - return error; - } - - // Ensure we wrote as many bytes as we expected. - if (bytes_written != bp_opcode_size) { - error.SetErrorStringWithFormat( - "SoftwareBreakpoint::%s failed write memory while attempting to set " - "breakpoint: attempted to write %zu bytes but only wrote %zu", - __FUNCTION__, bp_opcode_size, bytes_written); - if (log) - log->PutCString(error.AsCString()); - return error; - } - - uint8_t verify_bp_opcode_bytes[MAX_TRAP_OPCODE_SIZE]; - size_t verify_bytes_read = 0; - error = process.ReadMemory(addr, verify_bp_opcode_bytes, bp_opcode_size, - verify_bytes_read); - if (error.Fail()) { - if (log) - log->Printf("SoftwareBreakpoint::%s failed to read memory while " - "attempting to verify the breakpoint set: %s", - __FUNCTION__, error.AsCString()); - return error; - } - - // Ensure we read as many verification bytes as we expected. - if (verify_bytes_read != bp_opcode_size) { - if (log) - log->Printf("SoftwareBreakpoint::%s failed to read memory while " - "attempting to verify breakpoint: attempted to read %zu " - "bytes but only read %zu", - __FUNCTION__, bp_opcode_size, verify_bytes_read); - return Status( - "SoftwareBreakpoint::%s failed to read memory while " - "attempting to verify breakpoint: attempted to read %zu bytes " - "but only read %zu", - __FUNCTION__, bp_opcode_size, verify_bytes_read); - } - - if (::memcmp(bp_opcode_bytes, verify_bp_opcode_bytes, bp_opcode_size) != 0) { - if (log) - log->Printf("SoftwareBreakpoint::%s: verification of software breakpoint " - "writing failed - trap opcodes not successfully read back " - "after writing when setting breakpoint at 0x%" PRIx64, - __FUNCTION__, addr); - return Status("SoftwareBreakpoint::%s: verification of software breakpoint " - "writing failed - trap opcodes not successfully read back " - "after writing when setting breakpoint at 0x%" PRIx64, - __FUNCTION__, addr); - } - - if (log) - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- SUCCESS", - __FUNCTION__, addr); - - return Status(); -} - -// ------------------------------------------------------------------- -// instance-level members -// ------------------------------------------------------------------- - -SoftwareBreakpoint::SoftwareBreakpoint(NativeProcessProtocol &process, - lldb::addr_t addr, - const uint8_t *saved_opcodes, - const uint8_t *trap_opcodes, - size_t opcode_size) - : NativeBreakpoint(addr), m_process(process), m_saved_opcodes(), - m_trap_opcodes(), m_opcode_size(opcode_size) { - assert(opcode_size > 0 && "setting software breakpoint with no trap opcodes"); - assert(opcode_size <= MAX_TRAP_OPCODE_SIZE && "trap opcode size too large"); - - ::memcpy(m_saved_opcodes, saved_opcodes, opcode_size); - ::memcpy(m_trap_opcodes, trap_opcodes, opcode_size); -} - -Status SoftwareBreakpoint::DoEnable() { - return EnableSoftwareBreakpoint(m_process, m_addr, m_opcode_size, - m_trap_opcodes, m_saved_opcodes); -} - -Status SoftwareBreakpoint::DoDisable() { - Status error; - assert(m_addr && (m_addr != LLDB_INVALID_ADDRESS) && - "can't remove a software breakpoint for an invalid address"); - - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - if (log) - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64, __FUNCTION__, - m_addr); - - assert((m_opcode_size > 0) && - "cannot restore opcodes when there are no opcodes"); - - if (m_opcode_size > 0) { - // Clear a software breakpoint instruction - uint8_t curr_break_op[MAX_TRAP_OPCODE_SIZE]; - bool break_op_found = false; - assert(m_opcode_size <= sizeof(curr_break_op)); - - // Read the breakpoint opcode - size_t bytes_read = 0; - error = - m_process.ReadMemory(m_addr, curr_break_op, m_opcode_size, bytes_read); - if (error.Success() && bytes_read < m_opcode_size) { - error.SetErrorStringWithFormat( - "SoftwareBreakpointr::%s addr=0x%" PRIx64 - ": tried to read %zu bytes but only read %zu", - __FUNCTION__, m_addr, m_opcode_size, bytes_read); - } - if (error.Success()) { - bool verify = false; - // Make sure the breakpoint opcode exists at this address - if (::memcmp(curr_break_op, m_trap_opcodes, m_opcode_size) == 0) { - break_op_found = true; - // We found a valid breakpoint opcode at this address, now restore the - // saved opcode. - size_t bytes_written = 0; - error = m_process.WriteMemory(m_addr, m_saved_opcodes, m_opcode_size, - bytes_written); - if (error.Success() && bytes_written < m_opcode_size) { - error.SetErrorStringWithFormat( - "SoftwareBreakpoint::%s addr=0x%" PRIx64 - ": tried to write %zu bytes but only wrote %zu", - __FUNCTION__, m_addr, m_opcode_size, bytes_written); - } - if (error.Success()) { - verify = true; - } - } else { - error.SetErrorString( - "Original breakpoint trap is no longer in memory."); - // Set verify to true and so we can check if the original opcode has - // already been restored - verify = true; - } - - if (verify) { - uint8_t verify_opcode[MAX_TRAP_OPCODE_SIZE]; - assert(m_opcode_size <= sizeof(verify_opcode)); - // Verify that our original opcode made it back to the inferior - - size_t verify_bytes_read = 0; - error = m_process.ReadMemory(m_addr, verify_opcode, m_opcode_size, - verify_bytes_read); - if (error.Success() && verify_bytes_read < m_opcode_size) { - error.SetErrorStringWithFormat( - "SoftwareBreakpoint::%s addr=0x%" PRIx64 - ": tried to read %zu verification bytes but only read %zu", - __FUNCTION__, m_addr, m_opcode_size, verify_bytes_read); - } - if (error.Success()) { - // compare the memory we just read with the original opcode - if (::memcmp(m_saved_opcodes, verify_opcode, m_opcode_size) == 0) { - // SUCCESS - if (log) { - int i = 0; - for (const uint8_t *verify_byte = verify_opcode; - verify_byte < verify_opcode + m_opcode_size; ++verify_byte) { - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 - " replaced byte index %d with 0x%hhx", - __FUNCTION__, m_addr, i++, *verify_byte); - } - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 - " -- SUCCESS", - __FUNCTION__, m_addr); - } - return error; - } else { - if (break_op_found) - error.SetErrorString("Failed to restore original opcode."); - } - } else - error.SetErrorString("Failed to read memory to verify that " - "breakpoint trap was restored."); - } - } - } - - if (log && error.Fail()) - log->Printf("SoftwareBreakpoint::%s addr = 0x%" PRIx64 " -- FAILED: %s", - __FUNCTION__, m_addr, error.AsCString()); - return error; -} - -bool SoftwareBreakpoint::IsSoftwareBreakpoint() const { return true; } diff --git a/contrib/llvm/tools/lldb/source/Host/common/StringConvert.cpp b/contrib/llvm/tools/lldb/source/Host/common/StringConvert.cpp index b4171437b7e2..8f4e1956fc28 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/StringConvert.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/StringConvert.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/StringConvert.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Host/common/Symbols.cpp b/contrib/llvm/tools/lldb/source/Host/common/Symbols.cpp index d7e0c13112aa..ed1677cbcb58 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/Symbols.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/Symbols.cpp @@ -16,7 +16,6 @@ #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/SafeMachO.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" #include "lldb/Utility/UUID.h" @@ -29,7 +28,6 @@ typedef int cpu_subtype_t; using namespace lldb; using namespace lldb_private; -using namespace llvm::MachO; #if defined(__APPLE__) @@ -67,96 +65,133 @@ static bool FileAtPathContainsArchAndUUID(const FileSpec &file_fspec, return false; } +// Given a binary exec_fspec, and a ModuleSpec with an architecture/uuid, +// return true if there is a matching dSYM bundle next to the exec_fspec, +// and return that value in dsym_fspec. +// If there is a .dSYM.yaa compressed archive next to the exec_fspec, +// call through Symbols::DownloadObjectAndSymbolFile to download the +// expanded/uncompressed dSYM and return that filepath in dsym_fspec. + +static bool LookForDsymNextToExecutablePath(const ModuleSpec &mod_spec, + const FileSpec &exec_fspec, + FileSpec &dsym_fspec) { + ConstString filename = exec_fspec.GetFilename(); + FileSpec dsym_directory = exec_fspec; + dsym_directory.RemoveLastPathComponent(); + + std::string dsym_filename = filename.AsCString(); + dsym_filename += ".dSYM"; + dsym_directory.AppendPathComponent(dsym_filename); + dsym_directory.AppendPathComponent("Contents"); + dsym_directory.AppendPathComponent("Resources"); + dsym_directory.AppendPathComponent("DWARF"); + + if (FileSystem::Instance().Exists(dsym_directory)) { + + // See if the binary name exists in the dSYM DWARF + // subdir. + dsym_fspec = dsym_directory; + dsym_fspec.AppendPathComponent(filename.AsCString()); + if (FileSystem::Instance().Exists(dsym_fspec) && + FileAtPathContainsArchAndUUID(dsym_fspec, mod_spec.GetArchitecturePtr(), + mod_spec.GetUUIDPtr())) { + return true; + } + + // See if we have "../CF.framework" - so we'll look for + // CF.framework.dSYM/Contents/Resources/DWARF/CF + // We need to drop the last suffix after '.' to match + // 'CF' in the DWARF subdir. + std::string binary_name (filename.AsCString()); + auto last_dot = binary_name.find_last_of('.'); + if (last_dot != std::string::npos) { + binary_name.erase(last_dot); + dsym_fspec = dsym_directory; + dsym_fspec.AppendPathComponent(binary_name); + if (FileSystem::Instance().Exists(dsym_fspec) && + FileAtPathContainsArchAndUUID(dsym_fspec, + mod_spec.GetArchitecturePtr(), + mod_spec.GetUUIDPtr())) { + return true; + } + } + } + + // See if we have a .dSYM.yaa next to this executable path. + FileSpec dsym_yaa_fspec = exec_fspec; + dsym_yaa_fspec.RemoveLastPathComponent(); + std::string dsym_yaa_filename = filename.AsCString(); + dsym_yaa_filename += ".dSYM.yaa"; + dsym_yaa_fspec.AppendPathComponent(dsym_yaa_filename); + + if (FileSystem::Instance().Exists(dsym_yaa_fspec)) { + ModuleSpec mutable_mod_spec = mod_spec; + if (Symbols::DownloadObjectAndSymbolFile(mutable_mod_spec, true) && + FileSystem::Instance().Exists(mutable_mod_spec.GetSymbolFileSpec())) { + dsym_fspec = mutable_mod_spec.GetSymbolFileSpec(); + return true; + } + } + + return false; +} + +// Given a ModuleSpec with a FileSpec and optionally uuid/architecture +// filled in, look for a .dSYM bundle next to that binary. Returns true +// if a .dSYM bundle is found, and that path is returned in the dsym_fspec +// FileSpec. +// +// This routine looks a few directory layers above the given exec_path - +// exec_path might be /System/Library/Frameworks/CF.framework/CF and the +// dSYM might be /System/Library/Frameworks/CF.framework.dSYM. +// +// If there is a .dSYM.yaa compressed archive found next to the binary, +// we'll call DownloadObjectAndSymbolFile to expand it into a plain .dSYM + static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec, FileSpec &dsym_fspec) { Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); - const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); + const FileSpec &exec_fspec = module_spec.GetFileSpec(); if (exec_fspec) { - char path[PATH_MAX]; - if (exec_fspec->GetPath(path, sizeof(path))) { - // Make sure the module isn't already just a dSYM file... - if (strcasestr(path, ".dSYM/Contents/Resources/DWARF") == NULL) { + if (::LookForDsymNextToExecutablePath (module_spec, exec_fspec, dsym_fspec)) { if (log) { - if (module_spec.GetUUIDPtr() && module_spec.GetUUIDPtr()->IsValid()) { - log->Printf( - "Searching for dSYM bundle next to executable %s, UUID %s", - path, module_spec.GetUUIDPtr()->GetAsString().c_str()); - } else { - log->Printf("Searching for dSYM bundle next to executable %s", - path); - } + log->Printf("dSYM with matching UUID & arch found at %s", dsym_fspec.GetPath().c_str()); } - ::strncat(path, ".dSYM/Contents/Resources/DWARF/", - sizeof(path) - strlen(path) - 1); - ::strncat(path, exec_fspec->GetFilename().AsCString(), - sizeof(path) - strlen(path) - 1); + return true; + } else { + FileSpec parent_dirs = exec_fspec; - dsym_fspec.SetFile(path, false, FileSpec::Style::native); + // Remove the binary name from the FileSpec + parent_dirs.RemoveLastPathComponent(); - ModuleSpecList module_specs; - ModuleSpec matched_module_spec; - if (dsym_fspec.Exists() && - FileAtPathContainsArchAndUUID(dsym_fspec, - module_spec.GetArchitecturePtr(), - module_spec.GetUUIDPtr())) { - if (log) { - log->Printf("dSYM with matching UUID & arch found at %s", path); - } - return true; - } else { - FileSpec parent_dirs = exec_fspec; + // Add a ".dSYM" name to each directory component of the path, + // stripping off components. e.g. we may have a binary like + // /S/L/F/Foundation.framework/Versions/A/Foundation and + // /S/L/F/Foundation.framework.dSYM + // + // so we'll need to start with + // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the + // "A", and if that doesn't exist, strip off the "A" and try it again + // with "Versions", etc., until we find a dSYM bundle or we've + // stripped off enough path components that there's no need to + // continue. - // Remove the binary name from the FileSpec - parent_dirs.RemoveLastPathComponent(); - - // Add a ".dSYM" name to each directory component of the path, - // stripping off components. e.g. we may have a binary like - // /S/L/F/Foundation.framework/Versions/A/Foundation and - // /S/L/F/Foundation.framework.dSYM - // - // so we'll need to start with - // /S/L/F/Foundation.framework/Versions/A, add the .dSYM part to the - // "A", and if that doesn't exist, strip off the "A" and try it again - // with "Versions", etc., until we find a dSYM bundle or we've - // stripped off enough path components that there's no need to - // continue. - - for (int i = 0; i < 4; i++) { - // Does this part of the path have a "." character - could it be a - // bundle's top level directory? - const char *fn = parent_dirs.GetFilename().AsCString(); - if (fn == nullptr) - break; - if (::strchr(fn, '.') != nullptr) { - dsym_fspec = parent_dirs; - dsym_fspec.RemoveLastPathComponent(); - - // If the current directory name is "Foundation.framework", see - // if - // "Foundation.framework.dSYM/Contents/Resources/DWARF/Foundation" - // exists & has the right uuid. - std::string dsym_fn = fn; - dsym_fn += ".dSYM"; - dsym_fspec.AppendPathComponent(dsym_fn.c_str()); - dsym_fspec.AppendPathComponent("Contents"); - dsym_fspec.AppendPathComponent("Resources"); - dsym_fspec.AppendPathComponent("DWARF"); - dsym_fspec.AppendPathComponent( - exec_fspec->GetFilename().AsCString()); - if (dsym_fspec.Exists() && - FileAtPathContainsArchAndUUID( - dsym_fspec, module_spec.GetArchitecturePtr(), - module_spec.GetUUIDPtr())) { - if (log) { - log->Printf("dSYM with matching UUID & arch found at %s", - dsym_fspec.GetPath().c_str()); - } - return true; - } + for (int i = 0; i < 4; i++) { + // Does this part of the path have a "." character - could it be a + // bundle's top level directory? + const char *fn = parent_dirs.GetFilename().AsCString(); + if (fn == nullptr) + break; + if (::strchr(fn, '.') != nullptr) { + if (::LookForDsymNextToExecutablePath (module_spec, parent_dirs, dsym_fspec)) { + if (log) { + log->Printf("dSYM with matching UUID & arch found at %s", + dsym_fspec.GetPath().c_str()); } - parent_dirs.RemoveLastPathComponent(); + return true; } } + parent_dirs.RemoveLastPathComponent(); } } } @@ -164,7 +199,7 @@ static bool LocateDSYMInVincinityOfExecutable(const ModuleSpec &module_spec, return false; } -FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) { +static FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) { const FileSpec *exec_fspec = module_spec.GetFileSpecPtr(); const ArchSpec *arch = module_spec.GetArchitecturePtr(); const UUID *uuid = module_spec.GetUUIDPtr(); @@ -180,7 +215,7 @@ FileSpec LocateExecutableSymbolFileDsym(const ModuleSpec &module_spec) { ModuleSpec dsym_module_spec; // First try and find the dSYM in the same directory as the executable or in // an appropriate parent directory - if (LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec) == false) { + if (!LocateDSYMInVincinityOfExecutable(module_spec, symbol_fspec)) { // We failed to easily find the dSYM above, so use DebugSymbols LocateMacOSXFilesUsingDebugSymbols(module_spec, dsym_module_spec); } else { @@ -212,9 +247,12 @@ ModuleSpec Symbols::LocateExecutableObjectFile(const ModuleSpec &module_spec) { return result; } +// Keep "symbols.enable-external-lookup" description in sync with this function. + FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) { FileSpec symbol_file_spec = module_spec.GetSymbolFileSpec(); - if (symbol_file_spec.IsAbsolute() && symbol_file_spec.Exists()) + if (symbol_file_spec.IsAbsolute() && + FileSystem::Instance().Exists(symbol_file_spec)) return symbol_file_spec; const char *symbol_filename = symbol_file_spec.GetFilename().AsCString(); @@ -225,25 +263,42 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) { // Add module directory. FileSpec module_file_spec = module_spec.GetFileSpec(); // We keep the unresolved pathname if it fails. - FileSystem::ResolveSymbolicLink(module_file_spec, module_file_spec); + FileSystem::Instance().ResolveSymbolicLink(module_file_spec, module_file_spec); const ConstString &file_dir = module_file_spec.GetDirectory(); - debug_file_search_paths.AppendIfUnique( - FileSpec(file_dir.AsCString("."), true)); + { + FileSpec file_spec(file_dir.AsCString(".")); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } - // Add current working directory. - debug_file_search_paths.AppendIfUnique(FileSpec(".", true)); + if (ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup()) { + + // Add current working directory. + { + FileSpec file_spec("."); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } #ifndef _WIN32 #if defined(__NetBSD__) - // Add /usr/libdata/debug directory. - debug_file_search_paths.AppendIfUnique( - FileSpec("/usr/libdata/debug", true)); + // Add /usr/libdata/debug directory. + { + FileSpec file_spec("/usr/libdata/debug"); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } #else - // Add /usr/lib/debug directory. - debug_file_search_paths.AppendIfUnique(FileSpec("/usr/lib/debug", true)); + // Add /usr/lib/debug directory. + { + FileSpec file_spec("/usr/lib/debug"); + FileSystem::Instance().Resolve(file_spec); + debug_file_search_paths.AppendIfUnique(file_spec); + } #endif #endif // _WIN32 + } std::string uuid_str; const UUID &module_uuid = module_spec.GetUUID(); @@ -260,8 +315,8 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) { size_t num_directories = debug_file_search_paths.GetSize(); for (size_t idx = 0; idx < num_directories; ++idx) { FileSpec dirspec = debug_file_search_paths.GetFileSpecAtIndex(idx); - dirspec.ResolvePath(); - if (!llvm::sys::fs::is_directory(dirspec.GetPath())) + FileSystem::Instance().Resolve(dirspec); + if (!FileSystem::Instance().IsDirectory(dirspec)) continue; std::vector files; @@ -279,13 +334,14 @@ FileSpec Symbols::LocateExecutableSymbolFile(const ModuleSpec &module_spec) { const uint32_t num_files = files.size(); for (size_t idx_file = 0; idx_file < num_files; ++idx_file) { const std::string &filename = files[idx_file]; - FileSpec file_spec(filename, true); + FileSpec file_spec(filename); + FileSystem::Instance().Resolve(file_spec); if (llvm::sys::fs::equivalent(file_spec.GetPath(), module_file_spec.GetPath())) continue; - if (file_spec.Exists()) { + if (FileSystem::Instance().Exists(file_spec)) { lldb_private::ModuleSpecList specs; const size_t num_specs = ObjectFile::GetModuleSpecifications(file_spec, 0, 0, specs); diff --git a/contrib/llvm/tools/lldb/source/Host/common/TaskPool.cpp b/contrib/llvm/tools/lldb/source/Host/common/TaskPool.cpp index c54b9a8ae56b..ba1362a46f33 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/TaskPool.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/TaskPool.cpp @@ -10,9 +10,9 @@ #include "lldb/Host/TaskPool.h" #include "lldb/Host/ThreadLauncher.h" -#include // for uint32_t -#include // for queue -#include // for thread +#include +#include +#include namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Host/common/XML.cpp b/contrib/llvm/tools/lldb/source/Host/common/XML.cpp index 7468a3d7ac65..967a294cbf72 100644 --- a/contrib/llvm/tools/lldb/source/Host/common/XML.cpp +++ b/contrib/llvm/tools/lldb/source/Host/common/XML.cpp @@ -201,8 +201,7 @@ void XMLNode::ForEachAttribute(AttributeCallback const &callback) const { llvm::StringRef attr_value; if (child->content) attr_value = llvm::StringRef((const char *)child->content); - if (callback(llvm::StringRef((const char *)attr->name), attr_value) == - false) + if (!callback(llvm::StringRef((const char *)attr->name), attr_value)) return; } } @@ -217,7 +216,7 @@ void XMLNode::ForEachSiblingNode(NodeCallback const &callback) const { if (IsValid()) { // iterate through all siblings for (xmlNodePtr node = m_node; node; node = node->next) { - if (callback(XMLNode(node)) == false) + if (!callback(XMLNode(node))) return; } } @@ -234,7 +233,7 @@ void XMLNode::ForEachSiblingElement(NodeCallback const &callback) const { if (node->type != XML_ELEMENT_NODE) continue; - if (callback(XMLNode(node)) == false) + if (!callback(XMLNode(node))) return; } } @@ -263,7 +262,7 @@ void XMLNode::ForEachSiblingElementWithName( // ignore this one } - if (callback(XMLNode(node)) == false) + if (!callback(XMLNode(node))) return; } } @@ -439,7 +438,7 @@ XMLNode ApplePropertyList::GetValueNode(const char *key) const { "key", [key, &value_node](const XMLNode &key_node) -> bool { std::string key_name; if (key_node.GetElementText(key_name)) { - if (key_name.compare(key) == 0) { + if (key_name == key) { value_node = key_node.GetSibling(); while (value_node && !value_node.IsElement()) value_node = value_node.GetSibling(); diff --git a/contrib/llvm/tools/lldb/source/Host/freebsd/Host.cpp b/contrib/llvm/tools/lldb/source/Host/freebsd/Host.cpp index 87552bc2a27e..7bf959aee982 100644 --- a/contrib/llvm/tools/lldb/source/Host/freebsd/Host.cpp +++ b/contrib/llvm/tools/lldb/source/Host/freebsd/Host.cpp @@ -8,7 +8,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include #include @@ -23,9 +22,6 @@ #include #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" @@ -75,11 +71,9 @@ GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, size_t pathname_len = sizeof(pathname); mib[2] = KERN_PROC_PATHNAME; if (::sysctl(mib, 4, pathname, &pathname_len, NULL, 0) == 0) - process_info.GetExecutableFile().SetFile(pathname, false, - FileSpec::Style::native); + process_info.GetExecutableFile().SetFile(pathname, FileSpec::Style::native); else - process_info.GetExecutableFile().SetFile(cstr, false, - FileSpec::Style::native); + process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native); if (!(match_info_ptr == NULL || NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(), diff --git a/contrib/llvm/tools/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp b/contrib/llvm/tools/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp index 18eae3eb7606..d123936b3668 100644 --- a/contrib/llvm/tools/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Host/freebsd/HostInfoFreeBSD.cpp @@ -69,7 +69,7 @@ FileSpec HostInfoFreeBSD::GetProgramFileSpec() { if (sysctl(exe_path_mib, 4, NULL, &exe_path_size, NULL, 0) == 0) { char *exe_path = new char[exe_path_size]; if (sysctl(exe_path_mib, 4, exe_path, &exe_path_size, NULL, 0) == 0) - g_program_filespec.SetFile(exe_path, false, FileSpec::Style::native); + g_program_filespec.SetFile(exe_path, FileSpec::Style::native); delete[] exe_path; } } diff --git a/contrib/llvm/tools/lldb/source/Host/netbsd/Host.cpp b/contrib/llvm/tools/lldb/source/Host/netbsd/Host.cpp index bfd5a74ffcc2..4d50363c72e0 100644 --- a/contrib/llvm/tools/lldb/source/Host/netbsd/Host.cpp +++ b/contrib/llvm/tools/lldb/source/Host/netbsd/Host.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include #include #include @@ -22,9 +21,6 @@ #include #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" @@ -70,7 +66,7 @@ static bool GetNetBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr, if (!cstr) return false; - process_info.GetExecutableFile().SetFile(cstr, false, + process_info.GetExecutableFile().SetFile(cstr, FileSpec::Style::native); if (!(match_info_ptr == NULL || diff --git a/contrib/llvm/tools/lldb/source/Host/netbsd/HostInfoNetBSD.cpp b/contrib/llvm/tools/lldb/source/Host/netbsd/HostInfoNetBSD.cpp index dfbce310509d..a54483fcc55b 100644 --- a/contrib/llvm/tools/lldb/source/Host/netbsd/HostInfoNetBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Host/netbsd/HostInfoNetBSD.cpp @@ -85,7 +85,7 @@ FileSpec HostInfoNetBSD::GetProgramFileSpec() { len = sizeof(path); if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1) { - g_program_filespec.SetFile(path, false, FileSpec::Style::native); + g_program_filespec.SetFile(path, FileSpec::Style::native); } } return g_program_filespec; diff --git a/contrib/llvm/tools/lldb/source/Host/openbsd/Host.cpp b/contrib/llvm/tools/lldb/source/Host/openbsd/Host.cpp index 49e9c290a027..cba1f4ee6b7c 100644 --- a/contrib/llvm/tools/lldb/source/Host/openbsd/Host.cpp +++ b/contrib/llvm/tools/lldb/source/Host/openbsd/Host.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include #include @@ -19,9 +18,6 @@ #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" diff --git a/contrib/llvm/tools/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/contrib/llvm/tools/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp index c21bb786a896..deac3844d4a2 100644 --- a/contrib/llvm/tools/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp +++ b/contrib/llvm/tools/lldb/source/Host/posix/ConnectionFileDescriptorPosix.cpp @@ -21,7 +21,6 @@ #include "lldb/Utility/SelectHelper.h" #include "lldb/Utility/Timeout.h" -// C Includes #include #include #include @@ -33,16 +32,13 @@ #include #endif -// C++ Includes #include -// Other libraries and framework includes #include "llvm/Support/Errno.h" #include "llvm/Support/ErrorHandling.h" #if defined(__APPLE__) #include "llvm/ADT/SmallVector.h" #endif -// Project includes #include "lldb/Host/Host.h" #include "lldb/Host/Socket.h" #include "lldb/Host/common/TCPSocket.h" diff --git a/contrib/llvm/tools/lldb/source/Host/posix/FileSystem.cpp b/contrib/llvm/tools/lldb/source/Host/posix/FileSystem.cpp index 60be642df608..d7045ff99919 100644 --- a/contrib/llvm/tools/lldb/source/Host/posix/FileSystem.cpp +++ b/contrib/llvm/tools/lldb/source/Host/posix/FileSystem.cpp @@ -11,6 +11,7 @@ // C includes #include +#include #include #include #include @@ -47,7 +48,7 @@ Status FileSystem::Readlink(const FileSpec &src, FileSpec &dst) { error.SetErrorToErrno(); else { buf[count] = '\0'; // Success - dst.SetFile(buf, false, FileSpec::Style::native); + dst.SetFile(buf, FileSpec::Style::native); } return error; } @@ -65,7 +66,7 @@ Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) { return err; } - dst = FileSpec(real_path, false); + dst = FileSpec(real_path); return Status(); } @@ -73,3 +74,7 @@ Status FileSystem::ResolveSymbolicLink(const FileSpec &src, FileSpec &dst) { FILE *FileSystem::Fopen(const char *path, const char *mode) { return ::fopen(path, mode); } + +int FileSystem::Open(const char *path, int flags, int mode) { + return ::open(path, flags, mode); +} diff --git a/contrib/llvm/tools/lldb/source/Host/posix/HostInfoPosix.cpp b/contrib/llvm/tools/lldb/source/Host/posix/HostInfoPosix.cpp index 62c70fa3edc1..4763ebc9b9d4 100644 --- a/contrib/llvm/tools/lldb/source/Host/posix/HostInfoPosix.cpp +++ b/contrib/llvm/tools/lldb/source/Host/posix/HostInfoPosix.cpp @@ -119,7 +119,7 @@ uint32_t HostInfoPosix::GetEffectiveUserID() { return geteuid(); } uint32_t HostInfoPosix::GetEffectiveGroupID() { return getegid(); } -FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh", false); } +FileSpec HostInfoPosix::GetDefaultShell() { return FileSpec("/bin/sh"); } bool HostInfoPosix::ComputePathRelativeToLibrary(FileSpec &file_spec, llvm::StringRef dir) { @@ -163,7 +163,7 @@ bool HostInfoPosix::ComputeSupportExeDirectory(FileSpec &file_spec) { } bool HostInfoPosix::ComputeHeaderDirectory(FileSpec &file_spec) { - FileSpec temp_file("/opt/local/include/lldb", false); + FileSpec temp_file("/opt/local/include/lldb"); file_spec.GetDirectory().SetCString(temp_file.GetPath().c_str()); return true; } diff --git a/contrib/llvm/tools/lldb/source/Host/posix/HostProcessPosix.cpp b/contrib/llvm/tools/lldb/source/Host/posix/HostProcessPosix.cpp index 3c5273f4bd3f..f431e0c72de1 100644 --- a/contrib/llvm/tools/lldb/source/Host/posix/HostProcessPosix.cpp +++ b/contrib/llvm/tools/lldb/source/Host/posix/HostProcessPosix.cpp @@ -62,7 +62,7 @@ Status HostProcessPosix::GetMainModule(FileSpec &file_spec) const { return error; } - error = FileSystem::Readlink(FileSpec{link_path, false}, file_spec); + error = FileSystem::Instance().Readlink(FileSpec(link_path), file_spec); if (!error.Success()) return error; diff --git a/contrib/llvm/tools/lldb/source/Host/posix/PipePosix.cpp b/contrib/llvm/tools/lldb/source/Host/posix/PipePosix.cpp index b321cad64275..866a9897ee43 100644 --- a/contrib/llvm/tools/lldb/source/Host/posix/PipePosix.cpp +++ b/contrib/llvm/tools/lldb/source/Host/posix/PipePosix.cpp @@ -61,12 +61,13 @@ bool SetCloexecFlag(int fd) { std::chrono::time_point Now() { return std::chrono::steady_clock::now(); } -} +} // namespace PipePosix::PipePosix() : m_fds{PipePosix::kInvalidDescriptor, PipePosix::kInvalidDescriptor} {} -PipePosix::PipePosix(int read_fd, int write_fd) : m_fds{read_fd, write_fd} {} +PipePosix::PipePosix(lldb::pipe_t read, lldb::pipe_t write) + : m_fds{read, write} {} PipePosix::PipePosix(PipePosix &&pipe_posix) : PipeBase{std::move(pipe_posix)}, @@ -125,8 +126,8 @@ Status PipePosix::CreateNew(llvm::StringRef name, bool child_process_inherit) { Status PipePosix::CreateWithUniqueName(llvm::StringRef prefix, bool child_process_inherit, llvm::SmallVectorImpl &name) { - llvm::SmallString named_pipe_path; - llvm::SmallString pipe_spec((prefix + ".%%%%%%").str()); + llvm::SmallString<128> named_pipe_path; + llvm::SmallString<128> pipe_spec((prefix + ".%%%%%%").str()); FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir(); if (!tmpdir_file_spec) tmpdir_file_spec.AppendPathComponent("/tmp"); diff --git a/contrib/llvm/tools/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp b/contrib/llvm/tools/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp index 46ce3e3d224f..6bf78463d060 100644 --- a/contrib/llvm/tools/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp +++ b/contrib/llvm/tools/lldb/source/Host/posix/ProcessLauncherPosixFork.cpp @@ -157,7 +157,7 @@ static void LLVM_ATTRIBUTE_NORETURN ChildFunc(int error_fd, #if defined(__linux__) if (errno == ETXTBSY) { - // On android M and earlier we can get this error because the adb deamon + // On android M and earlier we can get this error because the adb daemon // can hold a write handle on the executable even after it has finished // uploading it. This state lasts only a short time and happens only when // there are many concurrent adb commands being issued, such as when diff --git a/contrib/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp b/contrib/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp index b52e8e6f25e6..346f1748f179 100644 --- a/contrib/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp +++ b/contrib/llvm/tools/lldb/source/Initialization/SystemInitializerCommon.cpp @@ -17,9 +17,11 @@ #include "Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h" #endif // LLDB_ENABLE_ALL #include "Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Reproducer.h" #include "lldb/Utility/Timer.h" #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) @@ -36,12 +38,14 @@ #include using namespace lldb_private; +using namespace lldb_private::repro; SystemInitializerCommon::SystemInitializerCommon() {} SystemInitializerCommon::~SystemInitializerCommon() {} -void SystemInitializerCommon::Initialize() { +llvm::Error +SystemInitializerCommon::Initialize(const InitializerOptions &options) { #if defined(_MSC_VER) const char *disable_crash_dialog_var = getenv("LLDB_DISABLE_CRASH_DIALOG"); if (disable_crash_dialog_var && @@ -64,6 +68,16 @@ void SystemInitializerCommon::Initialize() { } #endif + ReproducerMode mode = ReproducerMode::Off; + if (options.reproducer_capture) + mode = ReproducerMode::Capture; + if (options.reproducer_replay) + mode = ReproducerMode::Replay; + + if (auto e = Reproducer::Initialize(mode, FileSpec(options.reproducer_path))) + return e; + + FileSystem::Initialize(); Log::Initialize(); HostInfo::Initialize(); static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); @@ -91,6 +105,8 @@ void SystemInitializerCommon::Initialize() { #if defined(_MSC_VER) ProcessWindowsLog::Initialize(); #endif + + return llvm::Error::success(); } void SystemInitializerCommon::Terminate() { @@ -112,4 +128,6 @@ void SystemInitializerCommon::Terminate() { HostInfo::Terminate(); Log::DisableAllLogChannels(); + FileSystem::Terminate(); + Reproducer::Terminate(); } diff --git a/contrib/llvm/tools/lldb/source/Initialization/SystemLifetimeManager.cpp b/contrib/llvm/tools/lldb/source/Initialization/SystemLifetimeManager.cpp index 4d271787833d..65431bf6017d 100644 --- a/contrib/llvm/tools/lldb/source/Initialization/SystemLifetimeManager.cpp +++ b/contrib/llvm/tools/lldb/source/Initialization/SystemLifetimeManager.cpp @@ -24,9 +24,9 @@ SystemLifetimeManager::~SystemLifetimeManager() { "SystemLifetimeManager destroyed without calling Terminate!"); } -void SystemLifetimeManager::Initialize( +llvm::Error SystemLifetimeManager::Initialize( std::unique_ptr initializer, - LoadPluginCallbackType plugin_callback) { + const InitializerOptions &options, LoadPluginCallbackType plugin_callback) { std::lock_guard guard(m_mutex); if (!m_initialized) { assert(!m_initializer && "Attempting to call " @@ -35,9 +35,13 @@ void SystemLifetimeManager::Initialize( m_initialized = true; m_initializer = std::move(initializer); - m_initializer->Initialize(); + if (auto e = m_initializer->Initialize(options)) + return e; + Debugger::Initialize(plugin_callback); } + + return llvm::Error::success(); } void SystemLifetimeManager::Terminate() { diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandAlias.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandAlias.cpp index a4b0a0c55c0e..078eb73a7a87 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandAlias.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandAlias.cpp @@ -158,8 +158,7 @@ void CommandAlias::GetAliasExpansion(StreamString &help_string) const { help_string.Printf(" %s", value.c_str()); } else { help_string.Printf(" %s", opt.c_str()); - if ((value.compare("") != 0) && - (value.compare("SetPropertyAtIndexAsBoolean(nullptr, idx, b); } +bool CommandInterpreter::GetEchoCommands() const { + const uint32_t idx = eEchoCommands; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +void CommandInterpreter::SetEchoCommands(bool b) { + const uint32_t idx = eEchoCommands; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); +} + +bool CommandInterpreter::GetEchoCommentCommands() const { + const uint32_t idx = eEchoCommentCommands; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +void CommandInterpreter::SetEchoCommentCommands(bool b) { + const uint32_t idx = eEchoCommentCommands; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); +} + void CommandInterpreter::AllowExitCodeOnQuit(bool allow) { m_allow_exit_code = allow; if (!allow) @@ -386,6 +424,13 @@ void CommandInterpreter::Initialize() { if (cmd_obj_sp) { AddAlias("rbreak", cmd_obj_sp, "--func-regex %1"); } + + cmd_obj_sp = GetCommandSPExact("frame variable", false); + if (cmd_obj_sp) { + AddAlias("v", cmd_obj_sp); + AddAlias("var", cmd_obj_sp); + AddAlias("vo", cmd_obj_sp, "--object-description"); + } } void CommandInterpreter::Clear() { @@ -439,6 +484,8 @@ void CommandInterpreter::LoadCommandDictionary() { m_command_dict["quit"] = CommandObjectSP(new CommandObjectQuit(*this)); m_command_dict["register"] = CommandObjectSP(new CommandObjectRegister(*this)); + m_command_dict["reproducer"] = + CommandObjectSP(new CommandObjectReproducer(*this)); m_command_dict["script"] = CommandObjectSP(new CommandObjectScript(*this, script_language)); m_command_dict["settings"] = @@ -794,20 +841,23 @@ void CommandInterpreter::LoadCommandDictionary() { } int CommandInterpreter::GetCommandNamesMatchingPartialString( - const char *cmd_str, bool include_aliases, StringList &matches) { - AddNamesMatchingPartialString(m_command_dict, cmd_str, matches); + const char *cmd_str, bool include_aliases, StringList &matches, + StringList &descriptions) { + AddNamesMatchingPartialString(m_command_dict, cmd_str, matches, + &descriptions); if (include_aliases) { - AddNamesMatchingPartialString(m_alias_dict, cmd_str, matches); + AddNamesMatchingPartialString(m_alias_dict, cmd_str, matches, + &descriptions); } return matches.GetSize(); } -CommandObjectSP CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, - bool include_aliases, - bool exact, - StringList *matches) const { +CommandObjectSP +CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, bool include_aliases, + bool exact, StringList *matches, + StringList *descriptions) const { CommandObjectSP command_sp; std::string cmd = cmd_str; @@ -848,8 +898,8 @@ CommandObjectSP CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, // empty CommandObjectSP and the list of matches. if (HasCommands()) { - num_cmd_matches = - AddNamesMatchingPartialString(m_command_dict, cmd_str, *matches); + num_cmd_matches = AddNamesMatchingPartialString(m_command_dict, cmd_str, + *matches, descriptions); } if (num_cmd_matches == 1) { @@ -860,8 +910,8 @@ CommandObjectSP CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, } if (include_aliases && HasAliases()) { - num_alias_matches = - AddNamesMatchingPartialString(m_alias_dict, cmd_str, *matches); + num_alias_matches = AddNamesMatchingPartialString(m_alias_dict, cmd_str, + *matches, descriptions); } if (num_alias_matches == 1) { @@ -872,8 +922,8 @@ CommandObjectSP CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, } if (HasUserCommands()) { - num_user_matches = - AddNamesMatchingPartialString(m_user_dict, cmd_str, *matches); + num_user_matches = AddNamesMatchingPartialString(m_user_dict, cmd_str, + *matches, descriptions); } if (num_user_matches == 1) { @@ -898,6 +948,8 @@ CommandObjectSP CommandInterpreter::GetCommandSP(llvm::StringRef cmd_str, } } else if (matches && command_sp) { matches->AppendString(cmd_str); + if (descriptions) + descriptions->AppendString(command_sp->GetHelp()); } return command_sp; @@ -935,16 +987,16 @@ bool CommandInterpreter::AddUserCommand(llvm::StringRef name, if (!name.empty()) { // do not allow replacement of internal commands if (CommandExists(name)) { - if (can_replace == false) + if (!can_replace) return false; - if (m_command_dict[name]->IsRemovable() == false) + if (!m_command_dict[name]->IsRemovable()) return false; } if (UserCommandExists(name)) { - if (can_replace == false) + if (!can_replace) return false; - if (m_user_dict[name]->IsRemovable() == false) + if (!m_user_dict[name]->IsRemovable()) return false; } @@ -997,10 +1049,12 @@ CommandObjectSP CommandInterpreter::GetCommandSPExact(llvm::StringRef cmd_str, return ret_val; } -CommandObject *CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str, - StringList *matches) const { +CommandObject * +CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str, + StringList *matches, + StringList *descriptions) const { CommandObject *command_obj = - GetCommandSP(cmd_str, false, true, matches).get(); + GetCommandSP(cmd_str, false, true, matches, descriptions).get(); // If we didn't find an exact match to the command string in the commands, // look in the aliases. @@ -1008,7 +1062,7 @@ CommandObject *CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str, if (command_obj) return command_obj; - command_obj = GetCommandSP(cmd_str, true, true, matches).get(); + command_obj = GetCommandSP(cmd_str, true, true, matches, descriptions).get(); if (command_obj) return command_obj; @@ -1023,10 +1077,12 @@ CommandObject *CommandInterpreter::GetCommandObject(llvm::StringRef cmd_str, if (command_obj) { if (matches) matches->AppendString(command_obj->GetCommandName()); + if (descriptions) + descriptions->AppendString(command_obj->GetHelp()); return command_obj; } - return GetCommandSP(cmd_str, true, false, matches).get(); + return GetCommandSP(cmd_str, true, false, matches, descriptions).get(); } bool CommandInterpreter::CommandExists(llvm::StringRef cmd) const { @@ -1337,7 +1393,7 @@ CommandObject *CommandInterpreter::BuildAliasResult( alias_cmd_obj = desugared.first.get(); std::string alias_name_str = alias_name; if ((cmd_args.GetArgumentCount() == 0) || - (alias_name_str.compare(cmd_args.GetArgumentAtIndex(0)) != 0)) + (alias_name_str != cmd_args.GetArgumentAtIndex(0))) cmd_args.Unshift(alias_name_str); result_str.Printf("%s", alias_cmd_obj->GetCommandName().str().c_str()); @@ -1399,130 +1455,140 @@ Status CommandInterpreter::PreprocessCommand(std::string &command) { size_t start_backtick; size_t pos = 0; while ((start_backtick = command.find('`', pos)) != std::string::npos) { + // Stop if an error was encountered during the previous iteration. + if (error.Fail()) + break; + if (start_backtick > 0 && command[start_backtick - 1] == '\\') { // The backtick was preceded by a '\' character, remove the slash and - // don't treat the backtick as the start of an expression + // don't treat the backtick as the start of an expression. command.erase(start_backtick - 1, 1); - // No need to add one to start_backtick since we just deleted a char + // No need to add one to start_backtick since we just deleted a char. pos = start_backtick; - } else { - const size_t expr_content_start = start_backtick + 1; - const size_t end_backtick = command.find('`', expr_content_start); - if (end_backtick == std::string::npos) - return error; - else if (end_backtick == expr_content_start) { - // Empty expression (two backticks in a row) - command.erase(start_backtick, 2); - } else { - std::string expr_str(command, expr_content_start, - end_backtick - expr_content_start); + continue; + } - ExecutionContext exe_ctx(GetExecutionContext()); - Target *target = exe_ctx.GetTargetPtr(); - // Get a dummy target to allow for calculator mode while processing - // backticks. This also helps break the infinite loop caused when - // target is null. - if (!target) - target = m_debugger.GetDummyTarget(); - if (target) { - ValueObjectSP expr_result_valobj_sp; + const size_t expr_content_start = start_backtick + 1; + const size_t end_backtick = command.find('`', expr_content_start); - EvaluateExpressionOptions options; - options.SetCoerceToId(false); - options.SetUnwindOnError(true); - options.SetIgnoreBreakpoints(true); - options.SetKeepInMemory(false); - options.SetTryAllThreads(true); - options.SetTimeout(llvm::None); + if (end_backtick == std::string::npos) { + // Stop if there's no end backtick. + break; + } - ExpressionResults expr_result = target->EvaluateExpression( - expr_str.c_str(), exe_ctx.GetFramePtr(), expr_result_valobj_sp, - options); + if (end_backtick == expr_content_start) { + // Skip over empty expression. (two backticks in a row) + command.erase(start_backtick, 2); + continue; + } - if (expr_result == eExpressionCompleted) { - Scalar scalar; - if (expr_result_valobj_sp) - expr_result_valobj_sp = - expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable( - expr_result_valobj_sp->GetDynamicValueType(), true); - if (expr_result_valobj_sp->ResolveValue(scalar)) { - command.erase(start_backtick, end_backtick - start_backtick + 1); - StreamString value_strm; - const bool show_type = false; - scalar.GetValue(&value_strm, show_type); - size_t value_string_size = value_strm.GetSize(); - if (value_string_size) { - command.insert(start_backtick, value_strm.GetString()); - pos = start_backtick + value_string_size; - continue; - } else { - error.SetErrorStringWithFormat("expression value didn't result " - "in a scalar value for the " - "expression '%s'", - expr_str.c_str()); - } - } else { - error.SetErrorStringWithFormat("expression value didn't result " - "in a scalar value for the " - "expression '%s'", - expr_str.c_str()); - } - } else { - if (expr_result_valobj_sp) - error = expr_result_valobj_sp->GetError(); - if (error.Success()) { + std::string expr_str(command, expr_content_start, + end_backtick - expr_content_start); - switch (expr_result) { - case eExpressionSetupError: - error.SetErrorStringWithFormat( - "expression setup error for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionParseError: - error.SetErrorStringWithFormat( - "expression parse error for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionResultUnavailable: - error.SetErrorStringWithFormat( - "expression error fetching result for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionCompleted: - break; - case eExpressionDiscarded: - error.SetErrorStringWithFormat( - "expression discarded for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionInterrupted: - error.SetErrorStringWithFormat( - "expression interrupted for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionHitBreakpoint: - error.SetErrorStringWithFormat( - "expression hit breakpoint for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionTimedOut: - error.SetErrorStringWithFormat( - "expression timed out for the expression '%s'", - expr_str.c_str()); - break; - case eExpressionStoppedForDebug: - error.SetErrorStringWithFormat("expression stop at entry point " - "for debugging for the " - "expression '%s'", - expr_str.c_str()); - break; - } - } - } + ExecutionContext exe_ctx(GetExecutionContext()); + Target *target = exe_ctx.GetTargetPtr(); + + // Get a dummy target to allow for calculator mode while processing + // backticks. This also helps break the infinite loop caused when target is + // null. + if (!target) + target = m_debugger.GetDummyTarget(); + + if (!target) + continue; + + ValueObjectSP expr_result_valobj_sp; + + EvaluateExpressionOptions options; + options.SetCoerceToId(false); + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetKeepInMemory(false); + options.SetTryAllThreads(true); + options.SetTimeout(llvm::None); + + ExpressionResults expr_result = + target->EvaluateExpression(expr_str.c_str(), exe_ctx.GetFramePtr(), + expr_result_valobj_sp, options); + + if (expr_result == eExpressionCompleted) { + Scalar scalar; + if (expr_result_valobj_sp) + expr_result_valobj_sp = + expr_result_valobj_sp->GetQualifiedRepresentationIfAvailable( + expr_result_valobj_sp->GetDynamicValueType(), true); + if (expr_result_valobj_sp->ResolveValue(scalar)) { + command.erase(start_backtick, end_backtick - start_backtick + 1); + StreamString value_strm; + const bool show_type = false; + scalar.GetValue(&value_strm, show_type); + size_t value_string_size = value_strm.GetSize(); + if (value_string_size) { + command.insert(start_backtick, value_strm.GetString()); + pos = start_backtick + value_string_size; + continue; + } else { + error.SetErrorStringWithFormat("expression value didn't result " + "in a scalar value for the " + "expression '%s'", + expr_str.c_str()); + break; } - } - if (error.Fail()) + } else { + error.SetErrorStringWithFormat("expression value didn't result " + "in a scalar value for the " + "expression '%s'", + expr_str.c_str()); break; + } + + continue; + } + + if (expr_result_valobj_sp) + error = expr_result_valobj_sp->GetError(); + + if (error.Success()) { + switch (expr_result) { + case eExpressionSetupError: + error.SetErrorStringWithFormat( + "expression setup error for the expression '%s'", expr_str.c_str()); + break; + case eExpressionParseError: + error.SetErrorStringWithFormat( + "expression parse error for the expression '%s'", expr_str.c_str()); + break; + case eExpressionResultUnavailable: + error.SetErrorStringWithFormat( + "expression error fetching result for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionCompleted: + break; + case eExpressionDiscarded: + error.SetErrorStringWithFormat( + "expression discarded for the expression '%s'", expr_str.c_str()); + break; + case eExpressionInterrupted: + error.SetErrorStringWithFormat( + "expression interrupted for the expression '%s'", expr_str.c_str()); + break; + case eExpressionHitBreakpoint: + error.SetErrorStringWithFormat( + "expression hit breakpoint for the expression '%s'", + expr_str.c_str()); + break; + case eExpressionTimedOut: + error.SetErrorStringWithFormat( + "expression timed out for the expression '%s'", expr_str.c_str()); + break; + case eExpressionStoppedForDebug: + error.SetErrorStringWithFormat("expression stop at entry point " + "for debugging for the " + "expression '%s'", + expr_str.c_str()); + break; + } } } return error; @@ -1712,16 +1778,17 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) { if (request.GetCursorIndex() == -1) { // We got nothing on the command line, so return the list of commands bool include_aliases = true; - StringList new_matches; - num_command_matches = - GetCommandNamesMatchingPartialString("", include_aliases, new_matches); - request.AddCompletions(new_matches); + StringList new_matches, descriptions; + num_command_matches = GetCommandNamesMatchingPartialString( + "", include_aliases, new_matches, descriptions); + request.AddCompletions(new_matches, descriptions); } else if (request.GetCursorIndex() == 0) { // The cursor is in the first argument, so just do a lookup in the // dictionary. - StringList new_matches; - CommandObject *cmd_obj = GetCommandObject( - request.GetParsedLine().GetArgumentAtIndex(0), &new_matches); + StringList new_matches, new_descriptions; + CommandObject *cmd_obj = + GetCommandObject(request.GetParsedLine().GetArgumentAtIndex(0), + &new_matches, &new_descriptions); if (num_command_matches == 1 && cmd_obj && cmd_obj->IsMultiwordObject() && new_matches.GetStringAtIndex(0) != nullptr && @@ -1733,12 +1800,13 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) { look_for_subcommand = true; num_command_matches = 0; new_matches.DeleteStringAtIndex(0); + new_descriptions.DeleteStringAtIndex(0); request.GetParsedLine().AppendArgument(llvm::StringRef()); request.SetCursorIndex(request.GetCursorIndex() + 1); request.SetCursorCharPosition(0); } } - request.AddCompletions(new_matches); + request.AddCompletions(new_matches, new_descriptions); num_command_matches = request.GetNumberOfMatches(); } @@ -1762,12 +1830,13 @@ int CommandInterpreter::HandleCompletionMatches(CompletionRequest &request) { int CommandInterpreter::HandleCompletion( const char *current_line, const char *cursor, const char *last_char, - int match_start_point, int max_return_elements, StringList &matches) { + int match_start_point, int max_return_elements, StringList &matches, + StringList &descriptions) { llvm::StringRef command_line(current_line, last_char - current_line); + CompletionResult result; CompletionRequest request(command_line, cursor - current_line, - match_start_point, max_return_elements, matches); - + match_start_point, max_return_elements, result); // Don't complete comments, and if the line we are completing is just the // history repeat character, substitute the appropriate history line. const char *first_arg = request.GetParsedLine().GetArgumentAtIndex(0); @@ -1777,6 +1846,7 @@ int CommandInterpreter::HandleCompletion( else if (first_arg[0] == CommandHistory::g_repeat_char) { if (auto hist_str = m_command_history.FindString(first_arg)) { matches.InsertStringAtIndex(0, *hist_str); + descriptions.InsertStringAtIndex(0, "Previous command history event"); return -2; } else return 0; @@ -1787,6 +1857,8 @@ int CommandInterpreter::HandleCompletion( lldbassert(max_return_elements == -1); int num_command_matches = HandleCompletionMatches(request); + result.GetMatches(matches); + result.GetDescriptions(descriptions); if (num_command_matches <= 0) return num_command_matches; @@ -1794,6 +1866,7 @@ int CommandInterpreter::HandleCompletion( if (request.GetParsedLine().GetArgumentCount() == 0) { // If we got an empty string, insert nothing. matches.InsertStringAtIndex(0, ""); + descriptions.InsertStringAtIndex(0, ""); } else { // Now figure out if there is a common substring, and if so put that in // element 0, otherwise put an empty string in element 0. @@ -1815,6 +1888,7 @@ int CommandInterpreter::HandleCompletion( common_prefix.push_back(' '); } matches.InsertStringAtIndex(0, common_prefix.c_str()); + descriptions.InsertStringAtIndex(0, ""); } return num_command_matches; } @@ -1873,7 +1947,7 @@ void CommandInterpreter::BuildAliasCommandArgs(CommandObject *alias_cmd_obj, // Make sure that the alias name is the 0th element in cmd_args std::string alias_name_str = alias_name; - if (alias_name_str.compare(cmd_args.GetArgumentAtIndex(0)) != 0) + if (alias_name_str != cmd_args.GetArgumentAtIndex(0)) cmd_args.Unshift(alias_name_str); Args new_args(alias_cmd_obj->GetCommandName()); @@ -2025,13 +2099,14 @@ void CommandInterpreter::SourceInitFile(bool in_cwd, LoadCWDlldbinitFile should_load = target->TargetProperties::GetLoadCWDlldbinitFile(); if (should_load == eLoadCWDlldbinitWarn) { - FileSpec dot_lldb(".lldbinit", true); + FileSpec dot_lldb(".lldbinit"); + FileSystem::Instance().Resolve(dot_lldb); llvm::SmallString<64> home_dir_path; llvm::sys::path::home_directory(home_dir_path); - FileSpec homedir_dot_lldb(home_dir_path.c_str(), false); + FileSpec homedir_dot_lldb(home_dir_path.c_str()); homedir_dot_lldb.AppendPathComponent(".lldbinit"); - homedir_dot_lldb.ResolvePath(); - if (dot_lldb.Exists() && + FileSystem::Instance().Resolve(homedir_dot_lldb); + if (FileSystem::Instance().Exists(dot_lldb) && dot_lldb.GetDirectory() != homedir_dot_lldb.GetDirectory()) { result.AppendErrorWithFormat( "There is a .lldbinit file in the current directory which is not " @@ -2049,7 +2124,8 @@ void CommandInterpreter::SourceInitFile(bool in_cwd, return; } } else if (should_load == eLoadCWDlldbinitTrue) { - init_file.SetFile("./.lldbinit", true, FileSpec::Style::native); + init_file.SetFile("./.lldbinit", FileSpec::Style::native); + FileSystem::Instance().Resolve(init_file); } } } else { @@ -2061,11 +2137,11 @@ void CommandInterpreter::SourceInitFile(bool in_cwd, // init files. llvm::SmallString<64> home_dir_path; llvm::sys::path::home_directory(home_dir_path); - FileSpec profilePath(home_dir_path.c_str(), false); + FileSpec profilePath(home_dir_path.c_str()); profilePath.AppendPathComponent(".lldbinit"); std::string init_file_path = profilePath.GetPath(); - if (m_skip_app_init_files == false) { + if (!m_skip_app_init_files) { FileSpec program_file_spec(HostInfo::GetProgramFileSpec()); const char *program_name = program_file_spec.GetFilename().AsCString(); @@ -2073,22 +2149,22 @@ void CommandInterpreter::SourceInitFile(bool in_cwd, char program_init_file_name[PATH_MAX]; ::snprintf(program_init_file_name, sizeof(program_init_file_name), "%s-%s", init_file_path.c_str(), program_name); - init_file.SetFile(program_init_file_name, true, - FileSpec::Style::native); - if (!init_file.Exists()) + init_file.SetFile(program_init_file_name, FileSpec::Style::native); + FileSystem::Instance().Resolve(init_file); + if (!FileSystem::Instance().Exists(init_file)) init_file.Clear(); } } if (!init_file && !m_skip_lldbinit_files) - init_file.SetFile(init_file_path, false, FileSpec::Style::native); + init_file.SetFile(init_file_path, FileSpec::Style::native); } // If the file exists, tell HandleCommand to 'source' it; this will do the // actual broadcasting of the commands back to any appropriate listener (see // CommandObjectSource::Execute for more details). - if (init_file.Exists()) { + if (FileSystem::Instance().Exists(init_file)) { const bool saved_batch = SetBatchCommandMode(true); CommandInterpreterRunOptions options; options.SetSilent(true); @@ -2281,20 +2357,20 @@ enum { eHandleCommandFlagStopOnContinue = (1u << 0), eHandleCommandFlagStopOnError = (1u << 1), eHandleCommandFlagEchoCommand = (1u << 2), - eHandleCommandFlagPrintResult = (1u << 3), - eHandleCommandFlagStopOnCrash = (1u << 4) + eHandleCommandFlagEchoCommentCommand = (1u << 3), + eHandleCommandFlagPrintResult = (1u << 4), + eHandleCommandFlagStopOnCrash = (1u << 5) }; void CommandInterpreter::HandleCommandsFromFile( FileSpec &cmd_file, ExecutionContext *context, CommandInterpreterRunOptions &options, CommandReturnObject &result) { - if (cmd_file.Exists()) { + if (FileSystem::Instance().Exists(cmd_file)) { StreamFileSP input_file_sp(new StreamFile()); std::string cmd_file_path = cmd_file.GetPath(); - Status error = input_file_sp->GetFile().Open(cmd_file_path.c_str(), - File::eOpenOptionRead); - + Status error = FileSystem::Instance().Open(input_file_sp->GetFile(), + cmd_file, File::eOpenOptionRead); if (error.Success()) { Debugger &debugger = GetDebugger(); @@ -2324,9 +2400,10 @@ void CommandInterpreter::HandleCommandsFromFile( flags |= eHandleCommandFlagStopOnError; } + // stop-on-crash can only be set, if it is present in all levels of + // pushed flag sets. if (options.GetStopOnCrash()) { if (m_command_source_flags.empty()) { - // Echo command by default flags |= eHandleCommandFlagStopOnCrash; } else if (m_command_source_flags.back() & eHandleCommandFlagStopOnCrash) { @@ -2346,6 +2423,19 @@ void CommandInterpreter::HandleCommandsFromFile( flags |= eHandleCommandFlagEchoCommand; } + // We will only ever ask for this flag, if we echo commands in general. + if (options.m_echo_comment_commands == eLazyBoolCalculate) { + if (m_command_source_flags.empty()) { + // Echo comments by default + flags |= eHandleCommandFlagEchoCommentCommand; + } else if (m_command_source_flags.back() & + eHandleCommandFlagEchoCommentCommand) { + flags |= eHandleCommandFlagEchoCommentCommand; + } + } else if (options.m_echo_comment_commands == eLazyBoolYes) { + flags |= eHandleCommandFlagEchoCommentCommand; + } + if (options.m_print_results == eLazyBoolCalculate) { if (m_command_source_flags.empty()) { // Print output by default @@ -2667,6 +2757,21 @@ void CommandInterpreter::PrintCommandOutput(Stream &stream, } } +bool CommandInterpreter::EchoCommandNonInteractive( + llvm::StringRef line, const Flags &io_handler_flags) const { + if (!io_handler_flags.Test(eHandleCommandFlagEchoCommand)) + return false; + + llvm::StringRef command = line.trim(); + if (command.empty()) + return true; + + if (command.front() == m_comment_char) + return io_handler_flags.Test(eHandleCommandFlagEchoCommentCommand); + + return true; +} + void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, std::string &line) { // If we were interrupted, bail out... @@ -2674,7 +2779,7 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, return; const bool is_interactive = io_handler.GetIsInteractive(); - if (is_interactive == false) { + if (!is_interactive) { // When we are not interactive, don't execute blank lines. This will happen // sourcing a commands file. We don't want blank lines to repeat the // previous command and cause any errors to occur (like redefining an @@ -2685,7 +2790,7 @@ void CommandInterpreter::IOHandlerInputComplete(IOHandler &io_handler, // When using a non-interactive file handle (like when sourcing commands // from a file) we need to echo the command out so we don't just see the // command output and no command... - if (io_handler.GetFlags().Test(eHandleCommandFlagEchoCommand)) + if (EchoCommandNonInteractive(line, io_handler.GetFlags())) io_handler.GetOutputStreamFile()->Printf("%s%s\n", io_handler.GetPrompt(), line.c_str()); } @@ -2859,6 +2964,8 @@ CommandInterpreter::GetIOHandler(bool force_create, flags |= eHandleCommandFlagStopOnCrash; if (options->m_echo_commands != eLazyBoolNo) flags |= eHandleCommandFlagEchoCommand; + if (options->m_echo_comment_commands != eLazyBoolNo) + flags |= eHandleCommandFlagEchoCommentCommand; if (options->m_print_results != eLazyBoolNo) flags |= eHandleCommandFlagPrintResult; } else { @@ -2921,8 +3028,7 @@ CommandInterpreter::ResolveCommandImpl(std::string &command_line, bool is_alias = GetAliasFullName(next_word, full_name); cmd_obj = GetCommandObject(next_word, &matches); bool is_real_command = - (is_alias == false) || - (cmd_obj != nullptr && cmd_obj->IsAlias() == false); + (!is_alias) || (cmd_obj != nullptr && !cmd_obj->IsAlias()); if (!is_real_command) { matches.Clear(); std::string alias_result; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp index 324b0b511220..05c540b37c62 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObject.cpp @@ -409,15 +409,12 @@ const char *CommandObject::GetArgumentName(CommandArgumentType arg_type) { } bool CommandObject::IsPairType(ArgumentRepetitionType arg_repeat_type) { - if ((arg_repeat_type == eArgRepeatPairPlain) || - (arg_repeat_type == eArgRepeatPairOptional) || - (arg_repeat_type == eArgRepeatPairPlus) || - (arg_repeat_type == eArgRepeatPairStar) || - (arg_repeat_type == eArgRepeatPairRange) || - (arg_repeat_type == eArgRepeatPairRangeOptional)) - return true; - - return false; + return (arg_repeat_type == eArgRepeatPairPlain) || + (arg_repeat_type == eArgRepeatPairOptional) || + (arg_repeat_type == eArgRepeatPairPlus) || + (arg_repeat_type == eArgRepeatPairStar) || + (arg_repeat_type == eArgRepeatPairRange) || + (arg_repeat_type == eArgRepeatPairRangeOptional); } static CommandObject::CommandArgumentEntry diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp index ec89ad8fb162..2944177b0dc3 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectRegexCommand.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/CommandObjectRegexCommand.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/CommandReturnObject.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.cpp index fa1516df60c9..ed434031ae4e 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.cpp @@ -9,10 +9,6 @@ #include "CommandObjectScript.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Debugger.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.h b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.h index 7a61b06e5b04..ca453a875494 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.h +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandObjectScript.h @@ -10,10 +10,6 @@ #ifndef liblldb_CommandObjectScript_h_ #define liblldb_CommandObjectScript_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/CommandObject.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Interpreter/CommandReturnObject.cpp b/contrib/llvm/tools/lldb/source/Interpreter/CommandReturnObject.cpp index 7c06e22c3909..cf397a47a3bf 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/CommandReturnObject.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/CommandReturnObject.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/CommandReturnObject.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionArgParser.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionArgParser.cpp index 3bd3af8fc50e..b0565b706c5b 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionArgParser.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionArgParser.cpp @@ -46,10 +46,10 @@ char OptionArgParser::ToChar(llvm::StringRef s, char fail_value, } int64_t OptionArgParser::ToOptionEnum(llvm::StringRef s, - OptionEnumValueElement *enum_values, + const OptionEnumValues &enum_values, int32_t fail_value, Status &error) { error.Clear(); - if (!enum_values) { + if (enum_values.empty()) { error.SetErrorString("invalid enumeration argument"); return fail_value; } @@ -59,16 +59,18 @@ int64_t OptionArgParser::ToOptionEnum(llvm::StringRef s, return fail_value; } - for (int i = 0; enum_values[i].string_value != nullptr; i++) { - llvm::StringRef this_enum(enum_values[i].string_value); + for (const auto &enum_value : enum_values) { + llvm::StringRef this_enum(enum_value.string_value); if (this_enum.startswith(s)) - return enum_values[i].value; + return enum_value.value; } StreamString strm; strm.PutCString("invalid enumeration value, valid values are: "); - for (int i = 0; enum_values[i].string_value != nullptr; i++) { - strm.Printf("%s\"%s\"", i > 0 ? ", " : "", enum_values[i].string_value); + bool is_first = true; + for (const auto &enum_value : enum_values) { + strm.Printf("%s\"%s\"", + is_first ? is_first = false,"" : ", ", enum_value.string_value); } error.SetErrorString(strm.GetString()); return fail_value; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupArchitecture.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupArchitecture.cpp index bbd69b8f13fc..42eafc9872db 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupArchitecture.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupArchitecture.cpp @@ -18,9 +18,9 @@ OptionGroupArchitecture::OptionGroupArchitecture() : m_arch_str() {} OptionGroupArchitecture::~OptionGroupArchitecture() {} -static OptionDefinition g_option_table[] = { +static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "arch", 'a', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeArchitecture, + nullptr, {}, 0, eArgTypeArchitecture, "Specify the architecture for the target."}, }; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupBoolean.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupBoolean.cpp index e3759f2e60a1..ca694ef5f488 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupBoolean.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupBoolean.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupBoolean.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" using namespace lldb; @@ -32,7 +28,7 @@ OptionGroupBoolean::OptionGroupBoolean(uint32_t usage_mask, bool required, m_option_definition.option_has_arg = no_argument_toggle_default ? OptionParser::eNoArgument : OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; + m_option_definition.enum_values = {}; m_option_definition.completion_type = 0; m_option_definition.argument_type = eArgTypeBoolean; m_option_definition.usage_text = usage_text; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFile.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFile.cpp index d45f00a66616..241bad022ba7 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFile.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFile.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupFile.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" using namespace lldb; @@ -30,7 +26,7 @@ OptionGroupFile::OptionGroupFile(uint32_t usage_mask, bool required, m_option_definition.short_option = short_option; m_option_definition.validator = nullptr; m_option_definition.option_has_arg = OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; + m_option_definition.enum_values = {}; m_option_definition.completion_type = completion_type; m_option_definition.argument_type = argument_type; m_option_definition.usage_text = usage_text; @@ -61,7 +57,7 @@ OptionGroupFileList::OptionGroupFileList( m_option_definition.short_option = short_option; m_option_definition.validator = nullptr; m_option_definition.option_has_arg = OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; + m_option_definition.enum_values = {}; m_option_definition.completion_type = completion_type; m_option_definition.argument_type = argument_type; m_option_definition.usage_text = usage_text; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFormat.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFormat.cpp index b64c19324810..6345a633635c 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFormat.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupFormat.cpp @@ -27,18 +27,18 @@ OptionGroupFormat::OptionGroupFormat(lldb::Format default_format, OptionGroupFormat::~OptionGroupFormat() {} -static OptionDefinition g_option_table[] = { +static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "format", 'f', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeFormat, + nullptr, {}, 0, eArgTypeFormat, "Specify a format to be used for display."}, {LLDB_OPT_SET_2, false, "gdb-format", 'G', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeGDBFormat, + nullptr, {}, 0, eArgTypeGDBFormat, "Specify a format using a GDB format specifier string."}, {LLDB_OPT_SET_3, false, "size", 's', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeByteSize, + nullptr, {}, 0, eArgTypeByteSize, "The size in bytes to use when displaying with the selected format."}, {LLDB_OPT_SET_4, false, "count", 'c', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeCount, + nullptr, {}, 0, eArgTypeCount, "The number of total items to display."}, }; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupOutputFile.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupOutputFile.cpp index fd406494ea97..aebbf05131a0 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupOutputFile.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupOutputFile.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupOutputFile.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" using namespace lldb; @@ -25,12 +21,12 @@ OptionGroupOutputFile::~OptionGroupOutputFile() {} static const uint32_t SHORT_OPTION_APND = 0x61706e64; // 'apnd' -static OptionDefinition g_option_table[] = { +static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "outfile", 'o', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeFilename, + nullptr, {}, 0, eArgTypeFilename, "Specify a path for capturing command output."}, {LLDB_OPT_SET_1, false, "append-outfile", SHORT_OPTION_APND, - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Append to the file specified with '--outfile '."}, }; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp index 47974276c8c0..5858fcc4aa48 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupPlatform.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupPlatform.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Target/Platform.h" @@ -65,21 +61,21 @@ void OptionGroupPlatform::OptionParsingStarting( m_os_version = llvm::VersionTuple(); } -static OptionDefinition g_option_table[] = { +static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_ALL, false, "platform", 'p', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypePlatform, "Specify name of the platform to " - "use for this target, creating the " - "platform if necessary."}, + nullptr, {}, 0, eArgTypePlatform, "Specify name of the platform to " + "use for this target, creating the " + "platform if necessary."}, {LLDB_OPT_SET_ALL, false, "version", 'v', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Specify the initial SDK version to use prior to connecting."}, {LLDB_OPT_SET_ALL, false, "build", 'b', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Specify the initial SDK build number."}, {LLDB_OPT_SET_ALL, false, "sysroot", 'S', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeFilename, "Specify the SDK root directory " - "that contains a root of all " - "remote system files."}}; + nullptr, {}, 0, eArgTypeFilename, "Specify the SDK root directory " + "that contains a root of all " + "remote system files."}}; llvm::ArrayRef OptionGroupPlatform::GetDefinitions() { llvm::ArrayRef result(g_option_table); diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupString.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupString.cpp index 1a161945a17f..1b1fbdf4f6ed 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupString.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupString.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupString.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" using namespace lldb; @@ -31,7 +27,7 @@ OptionGroupString::OptionGroupString(uint32_t usage_mask, bool required, m_option_definition.short_option = short_option; m_option_definition.validator = nullptr; m_option_definition.option_has_arg = OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; + m_option_definition.enum_values = {}; m_option_definition.completion_type = completion_type; m_option_definition.argument_type = argument_type; m_option_definition.usage_text = usage_text; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUInt64.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUInt64.cpp index ae4828c3e926..bb2dcbbd23f9 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUInt64.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUInt64.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupUInt64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" using namespace lldb; @@ -31,7 +27,7 @@ OptionGroupUInt64::OptionGroupUInt64(uint32_t usage_mask, bool required, m_option_definition.short_option = short_option; m_option_definition.validator = nullptr; m_option_definition.option_has_arg = OptionParser::eRequiredArgument; - m_option_definition.enum_values = nullptr; + m_option_definition.enum_values = {}; m_option_definition.completion_type = completion_type; m_option_definition.argument_type = argument_type; m_option_definition.usage_text = usage_text; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUUID.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUUID.cpp index bf02d1b660cf..0859877774cc 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUUID.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupUUID.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupUUID.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" using namespace lldb; @@ -22,9 +18,9 @@ OptionGroupUUID::OptionGroupUUID() : m_uuid() {} OptionGroupUUID::~OptionGroupUUID() {} -static OptionDefinition g_option_table[] = { +static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeNone, "A module UUID value."}, + nullptr, {}, 0, eArgTypeNone, "A module UUID value."}, }; llvm::ArrayRef OptionGroupUUID::GetDefinitions() { diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp index 54b45c29c70d..40f219c8ab86 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupValueObjectDisplay.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/ValueObjectPrinter.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -28,46 +24,44 @@ OptionGroupValueObjectDisplay::OptionGroupValueObjectDisplay() {} OptionGroupValueObjectDisplay::~OptionGroupValueObjectDisplay() {} -static OptionDefinition g_option_table[] = { +static const OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "dynamic-type", 'd', - OptionParser::eRequiredArgument, nullptr, g_dynamic_value_types, 0, + OptionParser::eRequiredArgument, nullptr, GetDynamicValueTypes(), 0, eArgTypeNone, "Show the object as its full dynamic type, not its static " "type, if available."}, {LLDB_OPT_SET_1, false, "synthetic-type", 'S', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Show the object obeying its synthetic provider, if available."}, {LLDB_OPT_SET_1, false, "depth", 'D', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeCount, "Set the max recurse depth when " - "dumping aggregate types (default is " - "infinity)."}, + nullptr, {}, 0, eArgTypeCount, "Set the max recurse depth when dumping " + "aggregate types (default is infinity)."}, {LLDB_OPT_SET_1, false, "flat", 'F', OptionParser::eNoArgument, nullptr, - nullptr, 0, eArgTypeNone, "Display results in a flat format that uses " - "expression paths for each variable or member."}, + {}, 0, eArgTypeNone, "Display results in a flat format that uses " + "expression paths for each variable or member."}, {LLDB_OPT_SET_1, false, "location", 'L', OptionParser::eNoArgument, nullptr, - nullptr, 0, eArgTypeNone, "Show variable location information."}, + {}, 0, eArgTypeNone, "Show variable location information."}, {LLDB_OPT_SET_1, false, "object-description", 'O', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print as an Objective-C object."}, {LLDB_OPT_SET_1, false, "ptr-depth", 'P', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeCount, "The number of pointers to be " - "traversed when dumping values " - "(default is zero)."}, + nullptr, {}, 0, eArgTypeCount, "The number of pointers to be traversed " + "when dumping values (default is zero)."}, {LLDB_OPT_SET_1, false, "show-types", 'T', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Show variable types when dumping values."}, {LLDB_OPT_SET_1, false, "no-summary-depth", 'Y', - OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeCount, + OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeCount, "Set the depth at which omitting summary information stops (default is " "1)."}, {LLDB_OPT_SET_1, false, "raw-output", 'R', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, "Don't use formatting options."}, + nullptr, {}, 0, eArgTypeNone, "Don't use formatting options."}, {LLDB_OPT_SET_1, false, "show-all-children", 'A', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Ignore the upper bound on the number of children to show."}, {LLDB_OPT_SET_1, false, "validate", 'V', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeBoolean, "Show results of type validators."}, + nullptr, {}, 0, eArgTypeBoolean, "Show results of type validators."}, {LLDB_OPT_SET_1, false, "element-count", 'Z', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCount, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount, "Treat the result of the expression as if its type is an array of this " "many values."}}; @@ -86,8 +80,8 @@ Status OptionGroupValueObjectDisplay::SetOptionValue( switch (short_option) { case 'd': { int32_t result; - result = OptionArgParser::ToOptionEnum(option_arg, g_dynamic_value_types, 2, - error); + result = OptionArgParser::ToOptionEnum(option_arg, GetDynamicValueTypes(), + 2, error); if (error.Success()) use_dynamic = (lldb::DynamicValueType)result; } break; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupVariable.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupVariable.cpp index 7b7a62be8743..f90212cfcb2f 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupVariable.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupVariable.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupVariable.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/DataVisualization.h" #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -24,31 +20,34 @@ using namespace lldb_private; // if you add any options here, remember to update the counters in // OptionGroupVariable::GetNumDefinitions() -static OptionDefinition g_variable_options[] = { +static constexpr OptionDefinition g_variable_options[] = { {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-args", 'a', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Omit function arguments."}, + {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-recognized-args", 't', + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, + "Omit recognized function arguments."}, {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "no-locals", 'l', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Omit local variables."}, {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-globals", 'g', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show the current frame source file global and static variables."}, {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "show-declaration", 'c', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show variable declaration information (source file and line where the " "variable was declared)."}, {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "regex", 'r', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeRegularExpression, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeRegularExpression, "The argument for name lookups are regular expressions."}, {LLDB_OPT_SET_1 | LLDB_OPT_SET_2, false, "scope", 's', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Show variable scope (argument, local, global, static)."}, {LLDB_OPT_SET_1, false, "summary", 'y', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeName, + nullptr, {}, 0, eArgTypeName, "Specify the summary that the variable output should use."}, {LLDB_OPT_SET_2, false, "summary-string", 'z', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Specify a summary string to use to format the variable output."}, }; @@ -56,8 +55,8 @@ static Status ValidateNamedSummary(const char *str, void *) { if (!str || !str[0]) return Status("must specify a valid named summary"); TypeSummaryImplSP summary_sp; - if (DataVisualization::NamedSummaryFormats::GetSummaryFormat( - ConstString(str), summary_sp) == false) + if (!DataVisualization::NamedSummaryFormats::GetSummaryFormat( + ConstString(str), summary_sp)) return Status("must specify a valid named summary"); return Status(); } @@ -101,6 +100,9 @@ OptionGroupVariable::SetOptionValue(uint32_t option_idx, case 's': show_scope = true; break; + case 't': + show_recognized_args = false; + break; case 'y': error = summary.SetCurrentValue(option_arg); break; @@ -119,6 +121,7 @@ OptionGroupVariable::SetOptionValue(uint32_t option_idx, void OptionGroupVariable::OptionParsingStarting( ExecutionContext *execution_context) { show_args = true; // Frame option only + show_recognized_args = true; // Frame option only show_locals = true; // Frame option only show_globals = false; // Frame option only show_decl = false; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupWatchpoint.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupWatchpoint.cpp index 0431fefaa7f9..36b4cc5ac4f6 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupWatchpoint.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionGroupWatchpoint.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionGroupWatchpoint.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/lldb-enumerations.h" @@ -20,33 +16,31 @@ using namespace lldb; using namespace lldb_private; -static OptionEnumValueElement g_watch_type[] = { +static constexpr OptionEnumValueElement g_watch_type[] = { {OptionGroupWatchpoint::eWatchRead, "read", "Watch for read"}, {OptionGroupWatchpoint::eWatchWrite, "write", "Watch for write"}, {OptionGroupWatchpoint::eWatchReadWrite, "read_write", - "Watch for read/write"}, - {0, nullptr, nullptr}}; + "Watch for read/write"} }; -static OptionEnumValueElement g_watch_size[] = { +static constexpr OptionEnumValueElement g_watch_size[] = { {1, "1", "Watch for byte size of 1"}, {2, "2", "Watch for byte size of 2"}, {4, "4", "Watch for byte size of 4"}, - {8, "8", "Watch for byte size of 8"}, - {0, nullptr, nullptr}}; + {8, "8", "Watch for byte size of 8"} }; -static OptionDefinition g_option_table[] = { +static constexpr OptionDefinition g_option_table[] = { {LLDB_OPT_SET_1, false, "watch", 'w', OptionParser::eRequiredArgument, - nullptr, g_watch_type, 0, eArgTypeWatchType, + nullptr, OptionEnumValues(g_watch_type), 0, eArgTypeWatchType, "Specify the type of watching to perform."}, {LLDB_OPT_SET_1, false, "size", 's', OptionParser::eRequiredArgument, - nullptr, g_watch_size, 0, eArgTypeByteSize, + nullptr, OptionEnumValues(g_watch_size), 0, eArgTypeByteSize, "Number of bytes to use to watch a region."}}; bool OptionGroupWatchpoint::IsWatchSizeSupported(uint32_t watch_size) { - for (uint32_t i = 0; i < llvm::array_lengthof(g_watch_size); ++i) { - if (g_watch_size[i].value == 0) + for (const auto& size : g_watch_size) { + if (0 == size.value) break; - if (watch_size == g_watch_size[i].value) + if (watch_size == size.value) return true; } return false; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp index c3f363b05988..4e480dd5784b 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValue.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValue.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionValues.h" #include "lldb/Utility/StringList.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp index d4f1fcb8a70a..e4f0b9dd0df0 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArch.cpp @@ -9,15 +9,11 @@ #include "lldb/Interpreter/OptionValueArch.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Core/State.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArgs.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArgs.cpp index 26e438548ea3..4fa9e187668d 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArgs.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArgs.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueArgs.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Args.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp index d3fd1cb5db48..d755fa2fddb9 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueArray.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueArray.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/StringConvert.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Stream.h" @@ -31,13 +27,17 @@ void OptionValueArray::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, strm.Printf("(%s)", GetTypeAsCString()); } if (dump_mask & eDumpOptionValue) { - if (dump_mask & eDumpOptionType) - strm.Printf(" =%s", (m_values.size() > 0) ? "\n" : ""); - strm.IndentMore(); + const bool one_line = dump_mask & eDumpOptionCommand; const uint32_t size = m_values.size(); + if (dump_mask & eDumpOptionType) + strm.Printf(" =%s", (m_values.size() > 0 && !one_line) ? "\n" : ""); + if (!one_line) + strm.IndentMore(); for (uint32_t i = 0; i < size; ++i) { - strm.Indent(); - strm.Printf("[%u]: ", i); + if (!one_line) { + strm.Indent(); + strm.Printf("[%u]: ", i); + } const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; switch (array_element_type) { default: @@ -63,10 +63,16 @@ void OptionValueArray::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, extra_dump_options); break; } - if (i < (size - 1)) - strm.EOL(); + + if (!one_line) { + if (i < (size - 1)) + strm.EOL(); + } else { + strm << ' '; + } } - strm.IndentLess(); + if (!one_line) + strm.IndentLess(); } } @@ -215,7 +221,7 @@ Status OptionValueArray::SetArgs(const Args &args, VarSetOperationType op) { if (num_remove_indexes) { // Sort and then erase in reverse so indexes are always valid if (num_remove_indexes > 1) { - std::sort(remove_indexes.begin(), remove_indexes.end()); + llvm::sort(remove_indexes.begin(), remove_indexes.end()); for (std::vector::const_reverse_iterator pos = remove_indexes.rbegin(), end = remove_indexes.rend(); diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp index 94c774d69111..a7fe10e79431 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueBoolean.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueBoolean.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/PosixApi.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Utility/Stream.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp index 21fe88014724..1307b47a7134 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueChar.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueChar.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StringList.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp index 2e8a8427237b..5058064f1ca2 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueDictionary.cpp @@ -9,15 +9,11 @@ #include "lldb/Interpreter/OptionValueDictionary.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/StringRef.h" -// Project includes -#include "lldb/Core/State.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Interpreter/OptionValueString.h" #include "lldb/Utility/Args.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; @@ -33,16 +29,23 @@ void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx, strm.Printf("(%s)", GetTypeAsCString()); } if (dump_mask & eDumpOptionValue) { + const bool one_line = dump_mask & eDumpOptionCommand; if (dump_mask & eDumpOptionType) strm.PutCString(" ="); collection::iterator pos, end = m_values.end(); - strm.IndentMore(); + if (!one_line) + strm.IndentMore(); for (pos = m_values.begin(); pos != end; ++pos) { OptionValue *option_value = pos->second.get(); - strm.EOL(); + + if (one_line) + strm << ' '; + else + strm.EOL(); + strm.Indent(pos->first.GetCString()); const uint32_t extra_dump_options = m_raw_value_dump ? eDumpOptionRaw : 0; @@ -74,7 +77,8 @@ void OptionValueDictionary::DumpValue(const ExecutionContext *exe_ctx, break; } } - strm.IndentLess(); + if (!one_line) + strm.IndentLess(); } } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp index c7cbcab7fcc8..e65dd2b67831 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueEnumeration.cpp @@ -9,17 +9,13 @@ #include "lldb/Interpreter/OptionValueEnumeration.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/StringList.h" using namespace lldb; using namespace lldb_private; OptionValueEnumeration::OptionValueEnumeration( - const OptionEnumValueElement *enumerators, enum_type value) + const OptionEnumValues &enumerators, enum_type value) : OptionValue(), m_current_value(value), m_default_value(value), m_enumerations() { SetEnumerations(enumerators); @@ -91,18 +87,16 @@ Status OptionValueEnumeration::SetValueFromString(llvm::StringRef value, } void OptionValueEnumeration::SetEnumerations( - const OptionEnumValueElement *enumerators) { + const OptionEnumValues &enumerators) { m_enumerations.Clear(); - if (enumerators) { - for (size_t i = 0; enumerators[i].string_value != nullptr; ++i) { - ConstString const_enumerator_name(enumerators[i].string_value); - EnumeratorInfo enumerator_info = {enumerators[i].value, - enumerators[i].usage}; - m_enumerations.Append(const_enumerator_name, - enumerator_info); - } - m_enumerations.Sort(); + + for (const auto &enumerator : enumerators) { + ConstString const_enumerator_name(enumerator.string_value); + EnumeratorInfo enumerator_info = {enumerator.value, enumerator.usage}; + m_enumerations.Append(const_enumerator_name, enumerator_info); } + + m_enumerations.Sort(); } lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const { diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp index 2b93628679ce..735a7d86334d 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpec.cpp @@ -9,13 +9,12 @@ #include "lldb/Interpreter/OptionValueFileSpec.h" -#include "lldb/Core/State.h" #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Host/FileSystem.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Utility/Args.h" -#include "lldb/Utility/DataBufferLLVM.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; @@ -75,7 +74,9 @@ Status OptionValueFileSpec::SetValueFromString(llvm::StringRef value, // or whitespace. value = value.trim("\"' \t"); m_value_was_set = true; - m_current_value.SetFile(value.str(), m_resolve, FileSpec::Style::native); + m_current_value.SetFile(value.str(), FileSpec::Style::native); + if (m_resolve) + FileSystem::Instance().Resolve(m_current_value); m_data_sp.reset(); m_data_mod_time = llvm::sys::TimePoint<>(); NotifyValueChanged(); @@ -109,10 +110,11 @@ size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter, const lldb::DataBufferSP &OptionValueFileSpec::GetFileContents() { if (m_current_value) { - const auto file_mod_time = FileSystem::GetModificationTime(m_current_value); + const auto file_mod_time = FileSystem::Instance().GetModificationTime(m_current_value); if (m_data_sp && m_data_mod_time == file_mod_time) return m_data_sp; - m_data_sp = DataBufferLLVM::CreateFromPath(m_current_value.GetPath()); + m_data_sp = + FileSystem::Instance().CreateDataBuffer(m_current_value.GetPath()); m_data_mod_time = file_mod_time; } return m_data_sp; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp index 7fdc3c780239..fd78bba94fef 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFileSpecLIst.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueFileSpecList.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/StringConvert.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Stream.h" @@ -25,16 +21,24 @@ void OptionValueFileSpecList::DumpValue(const ExecutionContext *exe_ctx, if (dump_mask & eDumpOptionType) strm.Printf("(%s)", GetTypeAsCString()); if (dump_mask & eDumpOptionValue) { - if (dump_mask & eDumpOptionType) - strm.Printf(" =%s", m_current_value.GetSize() > 0 ? "\n" : ""); - strm.IndentMore(); + const bool one_line = dump_mask & eDumpOptionCommand; const uint32_t size = m_current_value.GetSize(); + if (dump_mask & eDumpOptionType) + strm.Printf(" =%s", + (m_current_value.GetSize() > 0 && !one_line) ? "\n" : ""); + if (!one_line) + strm.IndentMore(); for (uint32_t i = 0; i < size; ++i) { - strm.Indent(); - strm.Printf("[%u]: ", i); + if (!one_line) { + strm.Indent(); + strm.Printf("[%u]: ", i); + } m_current_value.GetFileSpecAtIndex(i).Dump(&strm); + if (one_line) + strm << ' '; } - strm.IndentLess(); + if (!one_line) + strm.IndentLess(); } } @@ -61,7 +65,7 @@ Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, count); } else { for (size_t i = 1; i < argc; ++i, ++idx) { - FileSpec file(args.GetArgumentAtIndex(i), false); + FileSpec file(args.GetArgumentAtIndex(i)); if (idx < count) m_current_value.Replace(idx, file); else @@ -83,7 +87,7 @@ Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, if (argc > 0) { m_value_was_set = true; for (size_t i = 0; i < argc; ++i) { - FileSpec file(args.GetArgumentAtIndex(i), false); + FileSpec file(args.GetArgumentAtIndex(i)); m_current_value.Append(file); } NotifyValueChanged(); @@ -107,7 +111,7 @@ Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, if (op == eVarSetOperationInsertAfter) ++idx; for (size_t i = 1; i < argc; ++i, ++idx) { - FileSpec file(args.GetArgumentAtIndex(i), false); + FileSpec file(args.GetArgumentAtIndex(i)); m_current_value.Insert(idx, file); } NotifyValueChanged(); @@ -136,7 +140,7 @@ Status OptionValueFileSpecList::SetValueFromString(llvm::StringRef value, size_t num_remove_indexes = remove_indexes.size(); if (num_remove_indexes) { // Sort and then erase in reverse so indexes are always valid - std::sort(remove_indexes.begin(), remove_indexes.end()); + llvm::sort(remove_indexes.begin(), remove_indexes.end()); for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) { m_current_value.Remove(j); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp index 1837804a4622..945d8bd33615 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormat.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueFormat.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Utility/Stream.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormatEntity.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormatEntity.cpp index ce1a84e8dece..18783625b86f 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormatEntity.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueFormatEntity.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueFormatEntity.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Module.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Utility/Stream.h" @@ -41,14 +37,30 @@ bool OptionValueFormatEntity::Clear() { return true; } +static void EscapeBackticks(llvm::StringRef str, std::string &dst) { + dst.clear(); + dst.reserve(str.size()); + + for (size_t i = 0, e = str.size(); i != e; ++i) { + char c = str[i]; + if (c == '`') { + if (i == 0 || str[i - 1] != '\\') + dst += '\\'; + } + dst += c; + } +} + void OptionValueFormatEntity::DumpValue(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) { if (dump_mask & eDumpOptionType) strm.Printf("(%s)", GetTypeAsCString()); if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) - strm.PutCString(" = \""); - strm << m_current_format.c_str() << '"'; + strm.PutCString(" = "); + std::string escaped; + EscapeBackticks(m_current_format, escaped); + strm << '"' << escaped << '"'; } } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueLanguage.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueLanguage.cpp index 1a82329bf0f3..c6e168d66b4f 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueLanguage.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueLanguage.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueLanguage.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Target/Language.h" #include "lldb/Utility/Args.h" @@ -28,7 +24,8 @@ void OptionValueLanguage::DumpValue(const ExecutionContext *exe_ctx, if (dump_mask & eDumpOptionValue) { if (dump_mask & eDumpOptionType) strm.PutCString(" = "); - strm.PutCString(Language::GetNameForLanguageType(m_current_value)); + if (m_current_value != eLanguageTypeUnknown) + strm.PutCString(Language::GetNameForLanguageType(m_current_value)); } } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp index 8390a8cf5aba..11ec739c5bb9 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValuePathMappings.cpp @@ -9,10 +9,7 @@ #include "lldb/Interpreter/OptionValuePathMappings.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes +#include "lldb/Host/FileSystem.h" #include "lldb/Host/StringConvert.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/FileSpec.h" @@ -23,7 +20,7 @@ using namespace lldb_private; namespace { static bool VerifyPathExists(const char *path) { if (path && path[0]) - return FileSpec(path, false).Exists(); + return FileSystem::Instance().Exists(path); else return false; } @@ -180,7 +177,7 @@ Status OptionValuePathMappings::SetValueFromString(llvm::StringRef value, size_t num_remove_indexes = remove_indexes.size(); if (num_remove_indexes) { // Sort and then erase in reverse so indexes are always valid - std::sort(remove_indexes.begin(), remove_indexes.end()); + llvm::sort(remove_indexes.begin(), remove_indexes.end()); for (size_t j = num_remove_indexes - 1; j < num_remove_indexes; ++j) { m_path_mappings.Remove(j, m_notify_changes); } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp index c1887f34b712..327d26b09ebb 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueProperties.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueProperties.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Flags.h" #include "lldb/Core/UserSettingsController.h" @@ -42,7 +38,7 @@ OptionValueProperties::OptionValueProperties( for (size_t i = 0; i < num_properties; ++i) { // Duplicate any values that are not global when constructing properties // from a global copy - if (m_properties[i].IsGlobal() == false) { + if (!m_properties[i].IsGlobal()) { lldb::OptionValueSP new_value_sp(m_properties[i].GetValue()->DeepCopy()); m_properties[i].SetOptionValue(new_value_sp); } @@ -53,9 +49,9 @@ size_t OptionValueProperties::GetNumProperties() const { return m_properties.size(); } -void OptionValueProperties::Initialize(const PropertyDefinition *defs) { - for (size_t i = 0; defs[i].name; ++i) { - Property property(defs[i]); +void OptionValueProperties::Initialize(const PropertyDefinitions &defs) { + for (const auto &definition : defs) { + Property property(definition); assert(property.IsValid()); m_name_to_index.Append(ConstString(property.GetName()), m_properties.size()); property.GetValue()->SetParent(shared_from_this()); @@ -216,7 +212,7 @@ Status OptionValueProperties::SetSubValue(const ExecutionContext *exe_ctx, else { // Don't set an error if the path contained .experimental. - those are // allowed to be missing and should silently fail. - if (name_contains_experimental == false && error.AsCString() == nullptr) { + if (!name_contains_experimental && error.AsCString() == nullptr) { error.SetErrorStringWithFormat("invalid value path '%s'", name.str().c_str()); } } diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp index aee8f97db163..3c06ff3957b0 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueRegex.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueRegex.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Stream.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp index ddd1b9662ca3..c087c3ee24be 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueSInt64.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueSInt64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/StringConvert.h" #include "lldb/Utility/Stream.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp index 8383b531270b..c89a0c6bf404 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueString.cpp @@ -10,10 +10,6 @@ #include "lldb/Interpreter/OptionValueString.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Stream.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp index c8db1bd532c6..053b5798880e 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUInt64.cpp @@ -10,10 +10,6 @@ #include "lldb/Interpreter/OptionValueUInt64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Host/StringConvert.h" #include "lldb/Utility/Stream.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp index 355e07bb2b5f..5518a0574112 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/OptionValueUUID.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/OptionValueUUID.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Module.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Utility/Stream.h" diff --git a/contrib/llvm/tools/lldb/source/Interpreter/Options.cpp b/contrib/llvm/tools/lldb/source/Interpreter/Options.cpp index c9567e91f6b8..c6357399a7e2 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/Options.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/Options.cpp @@ -9,15 +9,11 @@ #include "lldb/Interpreter/Options.h" -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Host/OptionParser.h" #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -461,7 +457,7 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd, } } - if (options.empty() == false) { + if (!options.empty()) { // We have some required options with no arguments strm.PutCString(" -"); for (i = 0; i < 2; ++i) @@ -480,14 +476,14 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd, if (def.usage_mask & opt_set_mask && isprint8(def.short_option)) { // Add current option to the end of out_stream. - if (def.required == false && + if (!def.required && def.option_has_arg == OptionParser::eNoArgument) { options.insert(def.short_option); } } } - if (options.empty() == false) { + if (!options.empty()) { // We have some required options with no arguments strm.PutCString(" [-"); for (i = 0; i < 2; ++i) @@ -601,15 +597,17 @@ void Options::GenerateOptionUsage(Stream &strm, CommandObject *cmd, if (opt_defs[i].usage_text) OutputFormattedUsageText(strm, opt_defs[i], screen_width); - if (opt_defs[i].enum_values != nullptr) { + if (!opt_defs[i].enum_values.empty()) { strm.Indent(); strm.Printf("Values: "); - for (int k = 0; opt_defs[i].enum_values[k].string_value != nullptr; - k++) { - if (k == 0) - strm.Printf("%s", opt_defs[i].enum_values[k].string_value); + bool is_first = true; + for (const auto &enum_value : opt_defs[i].enum_values) { + if (is_first) { + strm.Printf("%s", enum_value.string_value); + is_first = false; + } else - strm.Printf(" | %s", opt_defs[i].enum_values[k].string_value); + strm.Printf(" | %s", enum_value.string_value); } strm.EOL(); } @@ -770,17 +768,18 @@ bool Options::HandleOptionArgumentCompletion( // See if this is an enumeration type option, and if so complete it here: - OptionEnumValueElement *enum_values = opt_defs[opt_defs_index].enum_values; - if (enum_values != nullptr) { + const auto &enum_values = opt_defs[opt_defs_index].enum_values; + if (!enum_values.empty()) { bool return_value = false; std::string match_string( request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos), request.GetParsedLine().GetArgumentAtIndex(opt_arg_pos) + request.GetCursorCharPosition()); - for (int i = 0; enum_values[i].string_value != nullptr; i++) { - if (strstr(enum_values[i].string_value, match_string.c_str()) == - enum_values[i].string_value) { - request.AddCompletion(enum_values[i].string_value); + + for (const auto &enum_value : enum_values) { + if (strstr(enum_value.string_value, match_string.c_str()) == + enum_value.string_value) { + request.AddCompletion(enum_value.string_value); return_value = true; } } @@ -828,7 +827,7 @@ bool Options::HandleOptionArgumentCompletion( const char *module_name = request.GetParsedLine().GetArgumentAtIndex(cur_arg_pos); if (module_name) { - FileSpec module_spec(module_name, false); + FileSpec module_spec(module_name); lldb::TargetSP target_sp = interpreter.GetDebugger().GetSelectedTarget(); // Search filters require a target... diff --git a/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp b/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp index 369029bc570d..5f1022347cf4 100644 --- a/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp +++ b/contrib/llvm/tools/lldb/source/Interpreter/Property.cpp @@ -9,10 +9,6 @@ #include "lldb/Interpreter/Property.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/UserSettingsController.h" #include "lldb/Host/StringConvert.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -102,8 +98,10 @@ Property::Property(const PropertyDefinition &definition) // "definition.default_uint_value" represents if the // "definition.default_cstr_value" should be resolved or not const bool resolve = definition.default_uint_value != 0; - m_value_sp.reset(new OptionValueFileSpec( - FileSpec(definition.default_cstr_value, resolve), resolve)); + FileSpec file_spec = FileSpec(definition.default_cstr_value); + if (resolve) + FileSystem::Instance().Resolve(file_spec); + m_value_sp.reset(new OptionValueFileSpec(file_spec, resolve)); break; } @@ -233,7 +231,10 @@ void Property::Dump(const ExecutionContext *exe_ctx, Stream &strm, uint32_t dump_mask) const { if (m_value_sp) { const bool dump_desc = dump_mask & OptionValue::eDumpOptionDescription; + const bool dump_cmd = dump_mask & OptionValue::eDumpOptionCommand; const bool transparent = m_value_sp->ValueIsTransparent(); + if (dump_cmd && !transparent) + strm << "settings set -f "; if (dump_desc || !transparent) { if ((dump_mask & OptionValue::eDumpOptionName) && m_name) { DumpQualifiedName(strm); diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp index e0e293d7ae68..9055660f2d6c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp @@ -9,19 +9,13 @@ #include "ABIMacOSX_arm.h" -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" @@ -30,6 +24,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/ARMDefines.h" @@ -1327,16 +1323,13 @@ size_t ABIMacOSX_arm::GetRedZoneSize() const { return 0; } ABISP ABIMacOSX_arm::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor(); if (vendor_type == llvm::Triple::Apple) { if ((arch_type == llvm::Triple::arm) || (arch_type == llvm::Triple::thumb)) { - if (!g_abi_sp) - g_abi_sp.reset(new ABIMacOSX_arm(process_sp)); - return g_abi_sp; + return ABISP(new ABIMacOSX_arm(process_sp)); } } @@ -1477,14 +1470,16 @@ bool ABIMacOSX_arm::GetArgumentValues(Thread &thread, ValueList &values) const { if (compiler_type) { bool is_signed = false; size_t bit_width = 0; - if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - bit_width = compiler_type.GetBitSize(&thread); - } else if (compiler_type.IsPointerOrReferenceType()) { - bit_width = compiler_type.GetBitSize(&thread); - } else { + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (!bit_size) + return false; + if (compiler_type.IsIntegerOrEnumerationType(is_signed)) + bit_width = *bit_size; + else if (compiler_type.IsPointerOrReferenceType()) + bit_width = *bit_size; + else // We only handle integer, pointer and reference types currently... return false; - } if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) { if (value_idx < 4) { @@ -1581,9 +1576,11 @@ ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl( const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfoByName("r0", 0); if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - size_t bit_width = compiler_type.GetBitSize(&thread); + llvm::Optional bit_width = compiler_type.GetBitSize(&thread); + if (!bit_width) + return return_valobj_sp; - switch (bit_width) { + switch (*bit_width) { default: return return_valobj_sp; case 128: @@ -1599,14 +1596,17 @@ ValueObjectSP ABIMacOSX_arm::GetReturnValueObjectImpl( const RegisterInfo *r3_reg_info = reg_ctx->GetRegisterInfoByName("r3", 0); if (r1_reg_info && r2_reg_info && r3_reg_info) { - const size_t byte_size = compiler_type.GetByteSize(&thread); + llvm::Optional byte_size = + compiler_type.GetByteSize(&thread); + if (!byte_size) + return return_valobj_sp; ProcessSP process_sp(thread.GetProcess()); - if (byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size + - r2_reg_info->byte_size + - r3_reg_info->byte_size && + if (*byte_size <= r0_reg_info->byte_size + r1_reg_info->byte_size + + r2_reg_info->byte_size + + r3_reg_info->byte_size && process_sp) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = process_sp->GetByteOrder(); RegisterValue r0_reg_value; RegisterValue r1_reg_value; diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h index d3c20e1e618f..94f1e31a1235 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABIMacOSX_arm_h_ #define liblldb_ABIMacOSX_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp index 85f864ec7561..d8706c4a9cdd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.cpp @@ -9,18 +9,13 @@ #include "ABIMacOSX_arm64.h" -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" @@ -30,6 +25,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "Utility/ARM64_DWARF_Registers.h" @@ -1667,15 +1664,12 @@ size_t ABIMacOSX_arm64::GetRedZoneSize() const { return 128; } ABISP ABIMacOSX_arm64::CreateInstance(ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor(); if (vendor_type == llvm::Triple::Apple) { if (arch_type == llvm::Triple::aarch64) { - if (!g_abi_sp) - g_abi_sp.reset(new ABIMacOSX_arm64(process_sp)); - return g_abi_sp; + return ABISP(new ABIMacOSX_arm64(process_sp)); } } @@ -1768,90 +1762,92 @@ bool ABIMacOSX_arm64::GetArgumentValues(Thread &thread, return false; CompilerType value_type = value->GetCompilerType(); - if (value_type) { - bool is_signed = false; - size_t bit_width = 0; - if (value_type.IsIntegerOrEnumerationType(is_signed)) { - bit_width = value_type.GetBitSize(&thread); - } else if (value_type.IsPointerOrReferenceType()) { - bit_width = value_type.GetBitSize(&thread); - } else { - // We only handle integer, pointer and reference types currently... - return false; - } + llvm::Optional bit_size = value_type.GetBitSize(&thread); + if (!bit_size) + return false; - if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) { - if (value_idx < 8) { - // Arguments 1-6 are in x0-x5... - const RegisterInfo *reg_info = nullptr; - // Search by generic ID first, then fall back to by name - uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( - eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx); - if (arg_reg_num != LLDB_INVALID_REGNUM) { - reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num); - } else { - switch (value_idx) { - case 0: - reg_info = reg_ctx->GetRegisterInfoByName("x0"); - break; - case 1: - reg_info = reg_ctx->GetRegisterInfoByName("x1"); - break; - case 2: - reg_info = reg_ctx->GetRegisterInfoByName("x2"); - break; - case 3: - reg_info = reg_ctx->GetRegisterInfoByName("x3"); - break; - case 4: - reg_info = reg_ctx->GetRegisterInfoByName("x4"); - break; - case 5: - reg_info = reg_ctx->GetRegisterInfoByName("x5"); - break; - case 6: - reg_info = reg_ctx->GetRegisterInfoByName("x6"); - break; - case 7: - reg_info = reg_ctx->GetRegisterInfoByName("x7"); - break; - } - } + bool is_signed = false; + size_t bit_width = 0; + if (value_type.IsIntegerOrEnumerationType(is_signed)) { + bit_width = *bit_size; + } else if (value_type.IsPointerOrReferenceType()) { + bit_width = *bit_size; + } else { + // We only handle integer, pointer and reference types currently... + return false; + } - if (reg_info) { - RegisterValue reg_value; - - if (reg_ctx->ReadRegister(reg_info, reg_value)) { - if (is_signed) - reg_value.SignExtend(bit_width); - if (!reg_value.GetScalarValue(value->GetScalar())) - return false; - continue; - } - } - return false; + if (bit_width <= (exe_ctx.GetProcessRef().GetAddressByteSize() * 8)) { + if (value_idx < 8) { + // Arguments 1-6 are in x0-x5... + const RegisterInfo *reg_info = nullptr; + // Search by generic ID first, then fall back to by name + uint32_t arg_reg_num = reg_ctx->ConvertRegisterKindToRegisterNumber( + eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + value_idx); + if (arg_reg_num != LLDB_INVALID_REGNUM) { + reg_info = reg_ctx->GetRegisterInfoAtIndex(arg_reg_num); } else { - if (sp == 0) { - // Read the stack pointer if we already haven't read it - sp = reg_ctx->GetSP(0); - if (sp == 0) + switch (value_idx) { + case 0: + reg_info = reg_ctx->GetRegisterInfoByName("x0"); + break; + case 1: + reg_info = reg_ctx->GetRegisterInfoByName("x1"); + break; + case 2: + reg_info = reg_ctx->GetRegisterInfoByName("x2"); + break; + case 3: + reg_info = reg_ctx->GetRegisterInfoByName("x3"); + break; + case 4: + reg_info = reg_ctx->GetRegisterInfoByName("x4"); + break; + case 5: + reg_info = reg_ctx->GetRegisterInfoByName("x5"); + break; + case 6: + reg_info = reg_ctx->GetRegisterInfoByName("x6"); + break; + case 7: + reg_info = reg_ctx->GetRegisterInfoByName("x7"); + break; + } + } + + if (reg_info) { + RegisterValue reg_value; + + if (reg_ctx->ReadRegister(reg_info, reg_value)) { + if (is_signed) + reg_value.SignExtend(bit_width); + if (!reg_value.GetScalarValue(value->GetScalar())) return false; + continue; } - - // Arguments 5 on up are on the stack - const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8; - Status error; - if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory( - sp, arg_byte_size, is_signed, value->GetScalar(), error)) + } + return false; + } else { + if (sp == 0) { + // Read the stack pointer if we already haven't read it + sp = reg_ctx->GetSP(0); + if (sp == 0) return false; + } - sp += arg_byte_size; - // Align up to the next 8 byte boundary if needed - if (sp % 8) { - sp >>= 3; - sp += 1; - sp <<= 3; - } + // Arguments 5 on up are on the stack + const uint32_t arg_byte_size = (bit_width + (8 - 1)) / 8; + Status error; + if (!exe_ctx.GetProcessRef().ReadScalarIntegerFromMemory( + sp, arg_byte_size, is_signed, value->GetScalar(), error)) + return false; + + sp += arg_byte_size; + // Align up to the next 8 byte boundary if needed + if (sp % 8) { + sp >>= 3; + sp += 1; + sp <<= 3; } } } @@ -2115,13 +2111,12 @@ static bool LoadValueFromConsecutiveGPRRegisters( uint32_t &NGRN, // NGRN (see ABI documentation) uint32_t &NSRN, // NSRN (see ABI documentation) DataExtractor &data) { - const size_t byte_size = value_type.GetByteSize(nullptr); - - if (byte_size == 0) + llvm::Optional byte_size = value_type.GetByteSize(nullptr); + if (!byte_size || *byte_size == 0) return false; std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); Status error; @@ -2133,7 +2128,9 @@ static bool LoadValueFromConsecutiveGPRRegisters( if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) { if (!base_type) return false; - const size_t base_byte_size = base_type.GetByteSize(nullptr); + llvm::Optional base_byte_size = base_type.GetByteSize(nullptr); + if (!base_byte_size) + return false; uint32_t data_offset = 0; for (uint32_t i = 0; i < homogeneous_count; ++i) { @@ -2144,7 +2141,7 @@ static bool LoadValueFromConsecutiveGPRRegisters( if (reg_info == nullptr) return false; - if (base_byte_size > reg_info->byte_size) + if (*base_byte_size > reg_info->byte_size) return false; RegisterValue reg_value; @@ -2153,11 +2150,11 @@ static bool LoadValueFromConsecutiveGPRRegisters( return false; // Make sure we have enough room in "heap_data_ap" - if ((data_offset + base_byte_size) <= heap_data_ap->GetByteSize()) { + if ((data_offset + *base_byte_size) <= heap_data_ap->GetByteSize()) { const size_t bytes_copied = reg_value.GetAsMemoryData( - reg_info, heap_data_ap->GetBytes() + data_offset, base_byte_size, + reg_info, heap_data_ap->GetBytes() + data_offset, *base_byte_size, byte_order, error); - if (bytes_copied != base_byte_size) + if (bytes_copied != *base_byte_size) return false; data_offset += bytes_copied; ++NSRN; @@ -2172,10 +2169,10 @@ static bool LoadValueFromConsecutiveGPRRegisters( } const size_t max_reg_byte_size = 16; - if (byte_size <= max_reg_byte_size) { - size_t bytes_left = byte_size; + if (*byte_size <= max_reg_byte_size) { + size_t bytes_left = *byte_size; uint32_t data_offset = 0; - while (data_offset < byte_size) { + while (data_offset < *byte_size) { if (NGRN >= 8) return false; @@ -2267,7 +2264,10 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( if (!reg_ctx) return return_valobj_sp; - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (!byte_size) + return return_valobj_sp; const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr); if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { @@ -2276,7 +2276,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( bool success = false; if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { // Extract the register context so we can read arguments from registers - if (byte_size <= 8) { + if (*byte_size <= 8) { const RegisterInfo *x0_reg_info = reg_ctx->GetRegisterInfoByName("x0", 0); if (x0_reg_info) { @@ -2284,7 +2284,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, 0); const bool is_signed = (type_flags & eTypeIsSigned) != 0; - switch (byte_size) { + switch (*byte_size) { default: break; case 16: // uint128_t @@ -2294,10 +2294,10 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( reg_ctx->GetRegisterInfoByName("x1", 0); if (x1_reg_info) { - if (byte_size <= + if (*byte_size <= x0_reg_info->byte_size + x1_reg_info->byte_size) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); RegisterValue x0_reg_value; @@ -2362,7 +2362,7 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( if (type_flags & eTypeIsComplex) { // Don't handle complex yet. } else { - if (byte_size <= sizeof(long double)) { + if (*byte_size <= sizeof(long double)) { const RegisterInfo *v0_reg_info = reg_ctx->GetRegisterInfoByName("v0", 0); RegisterValue v0_value; @@ -2370,13 +2370,13 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( DataExtractor data; if (v0_value.GetData(data)) { lldb::offset_t offset = 0; - if (byte_size == sizeof(float)) { + if (*byte_size == sizeof(float)) { value.GetScalar() = data.GetFloat(&offset); success = true; - } else if (byte_size == sizeof(double)) { + } else if (*byte_size == sizeof(double)) { value.GetScalar() = data.GetDouble(&offset); success = true; - } else if (byte_size == sizeof(long double)) { + } else if (*byte_size == sizeof(long double)) { value.GetScalar() = data.GetLongDouble(&offset); success = true; } @@ -2390,14 +2390,14 @@ ValueObjectSP ABIMacOSX_arm64::GetReturnValueObjectImpl( return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsVector) { - if (byte_size > 0) { + if (*byte_size > 0) { const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); if (v0_info) { - if (byte_size <= v0_info->byte_size) { + if (*byte_size <= v0_info->byte_size) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); RegisterValue reg_value; if (reg_ctx->ReadRegister(v0_info, reg_value)) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h index 2dd7337542db..7a9444c775f4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-arm64/ABIMacOSX_arm64.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABIMacOSX_arm64_h_ #define liblldb_ABIMacOSX_arm64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp index 9e5e39ec28ca..a297bd1473b2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp @@ -9,19 +9,13 @@ #include "ABIMacOSX_i386.h" -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Process.h" @@ -29,6 +23,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" using namespace lldb; @@ -714,13 +710,10 @@ size_t ABIMacOSX_i386::GetRedZoneSize() const { return 0; } ABISP ABIMacOSX_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; if ((arch.GetTriple().getArch() == llvm::Triple::x86) && (arch.GetTriple().isMacOSX() || arch.GetTriple().isiOS() || arch.GetTriple().isWatchOS())) { - if (!g_abi_sp) - g_abi_sp.reset(new ABIMacOSX_i386(process_sp)); - return g_abi_sp; + return ABISP(new ABIMacOSX_i386(process_sp)); } return ABISP(); } @@ -831,18 +824,15 @@ bool ABIMacOSX_i386::GetArgumentValues(Thread &thread, // We currently only support extracting values with Clang QualTypes. Do we // care about others? CompilerType compiler_type(value->GetCompilerType()); - if (compiler_type) { + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (bit_size) { bool is_signed; - - if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - ReadIntegerArgument(value->GetScalar(), - compiler_type.GetBitSize(&thread), is_signed, + if (compiler_type.IsIntegerOrEnumerationType(is_signed)) + ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread.GetProcess().get(), current_stack_argument); - } else if (compiler_type.IsPointerType()) { - ReadIntegerArgument(value->GetScalar(), - compiler_type.GetBitSize(&thread), false, + else if (compiler_type.IsPointerType()) + ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread.GetProcess().get(), current_stack_argument); - } } } @@ -943,14 +933,15 @@ ABIMacOSX_i386::GetReturnValueObjectImpl(Thread &thread, bool is_signed; if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - size_t bit_width = compiler_type.GetBitSize(&thread); - + llvm::Optional bit_width = compiler_type.GetBitSize(&thread); + if (!bit_width) + return return_valobj_sp; unsigned eax_id = reg_ctx->GetRegisterInfoByName("eax", 0)->kinds[eRegisterKindLLDB]; unsigned edx_id = reg_ctx->GetRegisterInfoByName("edx", 0)->kinds[eRegisterKindLLDB]; - switch (bit_width) { + switch (*bit_width) { default: case 128: // Scalar can't hold 128-bit literals, so we don't handle this diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h index e026e3248672..536132d02586 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABIMacOSX_i386_h_ #define liblldb_ABIMacOSX_i386_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Value.h" #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp index af7ac469e6db..b93a8525010c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.cpp @@ -9,19 +9,13 @@ #include "ABISysV_arm.h" -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" @@ -30,6 +24,8 @@ #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/ARMDefines.h" @@ -1328,16 +1324,13 @@ size_t ABISysV_arm::GetRedZoneSize() const { return 0; } ABISP ABISysV_arm::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor(); if (vendor_type != llvm::Triple::Apple) { if ((arch_type == llvm::Triple::arm) || (arch_type == llvm::Triple::thumb)) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_arm(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_arm(process_sp)); } } @@ -1447,10 +1440,7 @@ bool ABISysV_arm::PrepareTrivialCall(Thread &thread, addr_t sp, ~1ull; // clear bit zero since the CPSR will take care of the mode for us // Set "pc" to the address requested - if (!reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr)) - return false; - - return true; + return reg_ctx->WriteRegisterFromUnsigned(pc_reg_num, function_addr); } bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const { @@ -1481,10 +1471,10 @@ bool ABISysV_arm::GetArgumentValues(Thread &thread, ValueList &values) const { if (compiler_type) { bool is_signed = false; size_t bit_width = 0; - if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - bit_width = compiler_type.GetBitSize(&thread); - } else if (compiler_type.IsPointerOrReferenceType()) { - bit_width = compiler_type.GetBitSize(&thread); + if (compiler_type.IsIntegerOrEnumerationType(is_signed) || + compiler_type.IsPointerOrReferenceType()) { + if (llvm::Optional size = compiler_type.GetBitSize(&thread)) + bit_width = *size; } else { // We only handle integer, pointer and reference types currently... return false; @@ -1590,11 +1580,13 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( const RegisterInfo *r0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); - size_t bit_width = compiler_type.GetBitSize(&thread); - size_t byte_size = compiler_type.GetByteSize(&thread); + llvm::Optional bit_width = compiler_type.GetBitSize(&thread); + llvm::Optional byte_size = compiler_type.GetByteSize(&thread); + if (!bit_width || !byte_size) + return return_valobj_sp; if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - switch (bit_width) { + switch (*bit_width) { default: return return_valobj_sp; case 64: { @@ -1641,28 +1633,28 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( UINT32_MAX; value.GetScalar() = ptr; } else if (compiler_type.IsVectorType(nullptr, nullptr)) { - if (IsArmHardFloat(thread) && (byte_size == 8 || byte_size == 16)) { + if (IsArmHardFloat(thread) && (*byte_size == 8 || *byte_size == 16)) { is_vfp_candidate = true; vfp_byte_size = 8; - vfp_count = (byte_size == 8 ? 1 : 2); - } else if (byte_size <= 16) { + vfp_count = (*byte_size == 8 ? 1 : 2); + } else if (*byte_size <= 16) { DataBufferHeap buffer(16, 0); uint32_t *buffer_ptr = (uint32_t *)buffer.GetBytes(); - for (uint32_t i = 0; 4 * i < byte_size; ++i) { + for (uint32_t i = 0; 4 * i < *byte_size; ++i) { const RegisterInfo *reg_info = reg_ctx->GetRegisterInfo( eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1 + i); buffer_ptr[i] = reg_ctx->ReadRegisterAsUnsigned(reg_info, 0) & UINT32_MAX; } - value.SetBytes(buffer.GetBytes(), byte_size); + value.SetBytes(buffer.GetBytes(), *byte_size); } else { - if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value)) + if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value)) return return_valobj_sp; } } else if (compiler_type.IsFloatingPointType(float_count, is_complex)) { if (float_count == 1 && !is_complex) { - switch (bit_width) { + switch (*bit_width) { default: return return_valobj_sp; case 64: { @@ -1710,9 +1702,9 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( } else if (is_complex && float_count == 2) { if (IsArmHardFloat(thread)) { is_vfp_candidate = true; - vfp_byte_size = byte_size / 2; + vfp_byte_size = *byte_size / 2; vfp_count = 2; - } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, bit_width / 8, + } else if (!GetReturnValuePassedInMemory(thread, reg_ctx, *bit_width / 8, value)) return return_valobj_sp; } else @@ -1725,19 +1717,21 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( compiler_type.IsHomogeneousAggregate(&base_type); if (homogeneous_count > 0 && homogeneous_count <= 4) { + llvm::Optional base_byte_size = + base_type.GetByteSize(nullptr); if (base_type.IsVectorType(nullptr, nullptr)) { - uint64_t base_byte_size = base_type.GetByteSize(nullptr); - if (base_byte_size == 8 || base_byte_size == 16) { + if (base_byte_size && + (*base_byte_size == 8 || *base_byte_size == 16)) { is_vfp_candidate = true; vfp_byte_size = 8; - vfp_count = - (base_type.GetByteSize(nullptr) == 8 ? homogeneous_count - : homogeneous_count * 2); + vfp_count = (*base_byte_size == 8 ? homogeneous_count + : homogeneous_count * 2); } } else if (base_type.IsFloatingPointType(float_count, is_complex)) { if (float_count == 1 && !is_complex) { is_vfp_candidate = true; - vfp_byte_size = base_type.GetByteSize(nullptr); + if (base_byte_size) + vfp_byte_size = *base_byte_size; vfp_count = homogeneous_count; } } @@ -1752,12 +1746,14 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( compiler_type.GetFieldAtIndex(index, name, NULL, NULL, NULL); if (base_type.IsFloatingPointType(float_count, is_complex)) { + llvm::Optional base_byte_size = + base_type.GetByteSize(nullptr); if (float_count == 2 && is_complex) { - if (index != 0 && - vfp_byte_size != base_type.GetByteSize(nullptr)) + if (index != 0 && base_byte_size && + vfp_byte_size != *base_byte_size) break; - else - vfp_byte_size = base_type.GetByteSize(nullptr); + else if (base_byte_size) + vfp_byte_size = *base_byte_size; } else break; } else @@ -1773,13 +1769,13 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( } } - if (byte_size <= 4) { + if (*byte_size <= 4) { RegisterValue r0_reg_value; uint32_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r0_reg_info, 0) & UINT32_MAX; - value.SetBytes(&raw_value, byte_size); + value.SetBytes(&raw_value, *byte_size); } else if (!is_vfp_candidate) { - if (!GetReturnValuePassedInMemory(thread, reg_ctx, byte_size, value)) + if (!GetReturnValuePassedInMemory(thread, reg_ctx, *byte_size, value)) return return_valobj_sp; } } else { @@ -1791,7 +1787,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( ProcessSP process_sp(thread.GetProcess()); ByteOrder byte_order = process_sp->GetByteOrder(); - DataBufferSP data_sp(new DataBufferHeap(byte_size, 0)); + DataBufferSP data_sp(new DataBufferHeap(*byte_size, 0)); uint32_t data_offset = 0; for (uint32_t reg_index = 0; reg_index < vfp_count; reg_index++) { @@ -1826,7 +1822,7 @@ ValueObjectSP ABISysV_arm::GetReturnValueObjectImpl( } } - if (data_offset == byte_size) { + if (data_offset == *byte_size) { DataExtractor data; data.SetByteOrder(byte_order); data.SetAddressByteSize(process_sp->GetAddressByteSize()); diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h index f046968c213d..7f2d658541ab 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm/ABISysV_arm.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_arm_h_ #define liblldb_ABISysV_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp index 2c221689954c..dd3f47303be5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp @@ -9,19 +9,13 @@ #include "ABISysV_arm64.h" -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Symbol/UnwindPlan.h" @@ -31,6 +25,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "Utility/ARM64_DWARF_Registers.h" @@ -1671,15 +1667,12 @@ size_t ABISysV_arm64::GetRedZoneSize() const { return 128; } ABISP ABISysV_arm64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); const llvm::Triple::VendorType vendor_type = arch.GetTriple().getVendor(); if (vendor_type != llvm::Triple::Apple) { if (arch_type == llvm::Triple::aarch64) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_arm64(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_arm64(process_sp)); } } @@ -1774,10 +1767,13 @@ bool ABISysV_arm64::GetArgumentValues(Thread &thread, ValueList &values) const { if (value_type) { bool is_signed = false; size_t bit_width = 0; + llvm::Optional bit_size = value_type.GetBitSize(&thread); + if (!bit_size) + return false; if (value_type.IsIntegerOrEnumerationType(is_signed)) { - bit_width = value_type.GetBitSize(&thread); + bit_width = *bit_size; } else if (value_type.IsPointerOrReferenceType()) { - bit_width = value_type.GetBitSize(&thread); + bit_width = *bit_size; } else { // We only handle integer, pointer and reference types currently... return false; @@ -2090,13 +2086,13 @@ static bool LoadValueFromConsecutiveGPRRegisters( uint32_t &NGRN, // NGRN (see ABI documentation) uint32_t &NSRN, // NSRN (see ABI documentation) DataExtractor &data) { - const size_t byte_size = value_type.GetByteSize(nullptr); + llvm::Optional byte_size = value_type.GetByteSize(nullptr); - if (byte_size == 0) + if (byte_size || *byte_size == 0) return false; std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); Status error; @@ -2108,7 +2104,9 @@ static bool LoadValueFromConsecutiveGPRRegisters( if (NSRN < 8 && (8 - NSRN) >= homogeneous_count) { if (!base_type) return false; - const size_t base_byte_size = base_type.GetByteSize(nullptr); + llvm::Optional base_byte_size = base_type.GetByteSize(nullptr); + if (!base_byte_size) + return false; uint32_t data_offset = 0; for (uint32_t i = 0; i < homogeneous_count; ++i) { @@ -2119,7 +2117,7 @@ static bool LoadValueFromConsecutiveGPRRegisters( if (reg_info == nullptr) return false; - if (base_byte_size > reg_info->byte_size) + if (*base_byte_size > reg_info->byte_size) return false; RegisterValue reg_value; @@ -2128,11 +2126,11 @@ static bool LoadValueFromConsecutiveGPRRegisters( return false; // Make sure we have enough room in "heap_data_ap" - if ((data_offset + base_byte_size) <= heap_data_ap->GetByteSize()) { + if ((data_offset + *base_byte_size) <= heap_data_ap->GetByteSize()) { const size_t bytes_copied = reg_value.GetAsMemoryData( - reg_info, heap_data_ap->GetBytes() + data_offset, base_byte_size, + reg_info, heap_data_ap->GetBytes() + data_offset, *base_byte_size, byte_order, error); - if (bytes_copied != base_byte_size) + if (bytes_copied != *base_byte_size) return false; data_offset += bytes_copied; ++NSRN; @@ -2147,10 +2145,10 @@ static bool LoadValueFromConsecutiveGPRRegisters( } const size_t max_reg_byte_size = 16; - if (byte_size <= max_reg_byte_size) { - size_t bytes_left = byte_size; + if (*byte_size <= max_reg_byte_size) { + size_t bytes_left = *byte_size; uint32_t data_offset = 0; - while (data_offset < byte_size) { + while (data_offset < *byte_size) { if (NGRN >= 8) return false; @@ -2235,7 +2233,10 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( if (!reg_ctx) return return_valobj_sp; - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (!byte_size) + return return_valobj_sp; const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr); if (type_flags & eTypeIsScalar || type_flags & eTypeIsPointer) { @@ -2244,7 +2245,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( bool success = false; if (type_flags & eTypeIsInteger || type_flags & eTypeIsPointer) { // Extract the register context so we can read arguments from registers - if (byte_size <= 8) { + if (*byte_size <= 8) { const RegisterInfo *x0_reg_info = nullptr; x0_reg_info = reg_ctx->GetRegisterInfo(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_ARG1); @@ -2253,7 +2254,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( thread.GetRegisterContext()->ReadRegisterAsUnsigned(x0_reg_info, 0); const bool is_signed = (type_flags & eTypeIsSigned) != 0; - switch (byte_size) { + switch (*byte_size) { default: break; case 16: // uint128_t @@ -2264,10 +2265,10 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( LLDB_REGNUM_GENERIC_ARG2); if (x1_reg_info) { - if (byte_size <= + if (*byte_size <= x0_reg_info->byte_size + x1_reg_info->byte_size) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); RegisterValue x0_reg_value; @@ -2332,7 +2333,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( if (type_flags & eTypeIsComplex) { // Don't handle complex yet. } else { - if (byte_size <= sizeof(long double)) { + if (*byte_size <= sizeof(long double)) { const RegisterInfo *v0_reg_info = reg_ctx->GetRegisterInfoByName("v0", 0); RegisterValue v0_value; @@ -2340,13 +2341,13 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( DataExtractor data; if (v0_value.GetData(data)) { lldb::offset_t offset = 0; - if (byte_size == sizeof(float)) { + if (*byte_size == sizeof(float)) { value.GetScalar() = data.GetFloat(&offset); success = true; - } else if (byte_size == sizeof(double)) { + } else if (*byte_size == sizeof(double)) { value.GetScalar() = data.GetDouble(&offset); success = true; - } else if (byte_size == sizeof(long double)) { + } else if (*byte_size == sizeof(long double)) { value.GetScalar() = data.GetLongDouble(&offset); success = true; } @@ -2359,13 +2360,13 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( if (success) return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); - } else if (type_flags & eTypeIsVector && byte_size <= 16) { - if (byte_size > 0) { + } else if (type_flags & eTypeIsVector && *byte_size <= 16) { + if (*byte_size > 0) { const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0); if (v0_info) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder(); RegisterValue reg_value; if (reg_ctx->ReadRegister(v0_info, reg_value)) { @@ -2382,7 +2383,7 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl( } } } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass || - (type_flags & eTypeIsVector && byte_size > 16)) { + (type_flags & eTypeIsVector && *byte_size > 16)) { DataExtractor data; uint32_t NGRN = 0; // Search ABI docs for NGRN diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h index 8d23c2419bab..b36b4547e626 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_arm64_h_ #define liblldb_ABISysV_arm64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp index a30416cf5a8e..ca40e9a04d7c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.cpp @@ -9,16 +9,11 @@ #include "ABISysV_hexagon.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/Triple.h" #include "llvm/IR/DerivedTypes.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +27,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; @@ -1020,11 +1016,8 @@ size_t ABISysV_hexagon::GetRedZoneSize() const { return 0; } ABISP ABISysV_hexagon::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; if (arch.GetTriple().getArch() == llvm::Triple::hexagon) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_hexagon(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_hexagon(process_sp)); } return ABISP(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h index 5a6809371d9f..6e39c0792e2a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-hexagon/ABISysV_hexagon.h @@ -11,10 +11,6 @@ #ifndef liblldb_ABISysV_hexagon_h_ #define liblldb_ABISysV_hexagon_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp index e7ddfccea338..3358eb8c2774 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.cpp @@ -8,16 +8,11 @@ #include "ABISysV_i386.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -31,6 +26,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; @@ -203,12 +199,9 @@ ABISysV_i386::GetRegisterInfoArray(uint32_t &count) { ABISP ABISysV_i386::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; if (arch.GetTriple().getVendor() != llvm::Triple::Apple) { if (arch.GetTriple().getArch() == llvm::Triple::x86) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_i386(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_i386(process_sp)); } } return ABISP(); @@ -315,15 +308,14 @@ bool ABISysV_i386::GetArgumentValues(Thread &thread, ValueList &values) const { // Currently: Support for extracting values with Clang QualTypes only. CompilerType compiler_type(value->GetCompilerType()); - if (compiler_type) { + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (bit_size) { bool is_signed; if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - ReadIntegerArgument(value->GetScalar(), - compiler_type.GetBitSize(&thread), is_signed, + ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread.GetProcess().get(), current_stack_argument); } else if (compiler_type.IsPointerType()) { - ReadIntegerArgument(value->GetScalar(), - compiler_type.GetBitSize(&thread), false, + ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread.GetProcess().get(), current_stack_argument); } } @@ -521,7 +513,10 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( (type_flags & eTypeIsEnumeration)) //'Integral' + 'Floating Point' { value.SetValueType(Value::eValueTypeScalar); - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (!byte_size) + return return_valobj_sp; bool success = false; if (type_flags & eTypeIsInteger) // 'Integral' except enum @@ -535,7 +530,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( 0xffffffff) << 32; - switch (byte_size) { + switch (*byte_size) { default: break; @@ -591,7 +586,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsFloat) // 'Floating Point' { - if (byte_size <= 12) // handles float, double, long double, __float80 + if (*byte_size <= 12) // handles float, double, long double, __float80 { const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("st0", 0); RegisterValue st0_value; @@ -602,21 +597,20 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( lldb::offset_t offset = 0; long double value_long_double = data.GetLongDouble(&offset); - if (byte_size == 4) // float is 4 bytes - { + // float is 4 bytes. + if (*byte_size == 4) { float value_float = (float)value_long_double; value.GetScalar() = value_float; success = true; - } else if (byte_size == 8) // double is 8 bytes - { + } else if (*byte_size == 8) { + // double is 8 bytes // On Android Platform: long double is also 8 bytes It will be // handled here only. double value_double = (double)value_long_double; value.GetScalar() = value_double; success = true; - } else if (byte_size == - 12) // long double and __float80 are 12 bytes on i386 - { + } else if (*byte_size == 12) { + // long double and __float80 are 12 bytes on i386. value.GetScalar() = value_long_double; success = true; } @@ -626,7 +620,7 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( if (success) return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); - } else if (byte_size == 16) // handles __float128 + } else if (*byte_size == 16) // handles __float128 { lldb::addr_t storage_addr = (uint32_t)( thread.GetRegisterContext()->ReadRegisterAsUnsigned(eax_id, 0) & @@ -644,18 +638,19 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( // ToDo: Yet to be implemented } else if (type_flags & eTypeIsVector) // 'Packed' { - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); - if (byte_size > 0) { + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (byte_size && *byte_size > 0) { const RegisterInfo *vec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0); if (vec_reg == nullptr) vec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0); if (vec_reg) { - if (byte_size <= vec_reg->byte_size) { + if (*byte_size <= vec_reg->byte_size) { ProcessSP process_sp(thread.GetProcess()); if (process_sp) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = process_sp->GetByteOrder(); RegisterValue reg_value; if (reg_ctx->ReadRegister(vec_reg, reg_value)) { @@ -672,14 +667,14 @@ ValueObjectSP ABISysV_i386::GetReturnValueObjectSimple( } } } - } else if (byte_size <= vec_reg->byte_size * 2) { + } else if (*byte_size <= vec_reg->byte_size * 2) { const RegisterInfo *vec_reg2 = reg_ctx->GetRegisterInfoByName("xmm1", 0); if (vec_reg2) { ProcessSP process_sp(thread.GetProcess()); if (process_sp) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = process_sp->GetByteOrder(); RegisterValue reg_value; RegisterValue reg_value2; diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.h index 4dce54c4f073..336a2754c6ca 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-i386/ABISysV_i386.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_i386_h_ #define liblldb_ABISysV_i386_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp index ce02f8677a63..6f3d2e3b3696 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.cpp @@ -9,16 +9,11 @@ #include "ABISysV_mips.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +27,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; @@ -560,13 +556,10 @@ size_t ABISysV_mips::GetRedZoneSize() const { return 0; } ABISP ABISysV_mips::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); if ((arch_type == llvm::Triple::mips) || (arch_type == llvm::Triple::mipsel)) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_mips(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_mips(process_sp)); } return ABISP(); } @@ -819,9 +812,11 @@ ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl( // In MIPS register "r2" (v0) holds the integer function return values const RegisterInfo *r2_reg_info = reg_ctx->GetRegisterInfoByName("r2", 0); - size_t bit_width = return_compiler_type.GetBitSize(&thread); + llvm::Optional bit_width = return_compiler_type.GetBitSize(&thread); + if (!bit_width) + return return_valobj_sp; if (return_compiler_type.IsIntegerOrEnumerationType(is_signed)) { - switch (bit_width) { + switch (*bit_width) { default: return return_valobj_sp; case 64: { @@ -880,7 +875,7 @@ ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl( uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_reg_info, 0); if (count != 1 && is_complex) return return_valobj_sp; - switch (bit_width) { + switch (*bit_width) { default: return return_valobj_sp; case 32: @@ -912,7 +907,7 @@ ValueObjectSP ABISysV_mips::GetReturnValueObjectImpl( lldb::offset_t offset = 0; if (count == 1 && !is_complex) { - switch (bit_width) { + switch (*bit_width) { default: return return_valobj_sp; case 64: { diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.h index 0de8e7751fce..d23dbe9d97bd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips/ABISysV_mips.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_mips_h_ #define liblldb_ABISysV_mips_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp index b958abf25637..1d6738d9fda9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.cpp @@ -9,16 +9,11 @@ #include "ABISysV_mips64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +27,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; @@ -560,13 +556,10 @@ size_t ABISysV_mips64::GetRedZoneSize() const { return 0; } ABISP ABISysV_mips64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; const llvm::Triple::ArchType arch_type = arch.GetTriple().getArch(); if ((arch_type == llvm::Triple::mips64) || (arch_type == llvm::Triple::mips64el)) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_mips64(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_mips64(process_sp)); } return ABISP(); } @@ -769,7 +762,10 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( Target *target = exe_ctx.GetTargetPtr(); const ArchSpec target_arch = target->GetArchitecture(); ByteOrder target_byte_order = target_arch.GetByteOrder(); - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (!byte_size) + return return_valobj_sp; const uint32_t type_flags = return_compiler_type.GetTypeInfo(nullptr); uint32_t fp_flag = target_arch.GetFlags() & lldb_private::ArchSpec::eMIPS_ABI_FP_mask; @@ -788,7 +784,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0); const bool is_signed = (type_flags & eTypeIsSigned) != 0; - switch (byte_size) { + switch (*byte_size) { default: break; @@ -829,7 +825,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( // Don't handle complex yet. } else if (IsSoftFloat(fp_flag)) { uint64_t raw_value = reg_ctx->ReadRegisterAsUnsigned(r2_info, 0); - switch (byte_size) { + switch (*byte_size) { case 4: value.GetScalar() = *((float *)(&raw_value)); success = true; @@ -854,7 +850,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( } } else { - if (byte_size <= sizeof(long double)) { + if (*byte_size <= sizeof(long double)) { const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); RegisterValue f0_value; @@ -865,13 +861,13 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( f0_value.GetData(f0_data); lldb::offset_t offset = 0; - if (byte_size == sizeof(float)) { + if (*byte_size == sizeof(float)) { value.GetScalar() = (float)f0_data.GetFloat(&offset); success = true; - } else if (byte_size == sizeof(double)) { + } else if (*byte_size == sizeof(double)) { value.GetScalar() = (double)f0_data.GetDouble(&offset); success = true; - } else if (byte_size == sizeof(long double)) { + } else if (*byte_size == sizeof(long double)) { const RegisterInfo *f2_info = reg_ctx->GetRegisterInfoByName("f2", 0); RegisterValue f2_value; @@ -886,21 +882,21 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( if (target_byte_order == eByteOrderLittle) { copy_from_extractor = &f0_data; copy_from_extractor->CopyByteOrderedData( - 0, 8, data_sp->GetBytes(), byte_size - 8, target_byte_order); + 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order); f2_value.GetData(f2_data); copy_from_extractor = &f2_data; copy_from_extractor->CopyByteOrderedData( - 0, 8, data_sp->GetBytes() + 8, byte_size - 8, + 0, 8, data_sp->GetBytes() + 8, *byte_size - 8, target_byte_order); } else { copy_from_extractor = &f0_data; copy_from_extractor->CopyByteOrderedData( - 0, 8, data_sp->GetBytes() + 8, byte_size - 8, + 0, 8, data_sp->GetBytes() + 8, *byte_size - 8, target_byte_order); f2_value.GetData(f2_data); copy_from_extractor = &f2_data; copy_from_extractor->CopyByteOrderedData( - 0, 8, data_sp->GetBytes(), byte_size - 8, target_byte_order); + 0, 8, data_sp->GetBytes(), *byte_size - 8, target_byte_order); } return_valobj_sp = ValueObjectConstResult::Create( @@ -917,7 +913,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass || type_flags & eTypeIsVector) { // Any structure of up to 16 bytes in size is returned in the registers. - if (byte_size <= 16) { + if (*byte_size <= 16) { DataBufferSP data_sp(new DataBufferHeap(16, 0)); DataExtractor return_ext(data_sp, target_byte_order, target->GetArchitecture().GetAddressByteSize()); @@ -975,8 +971,10 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( idx, name, &field_bit_offset, nullptr, nullptr); - const size_t field_byte_width = + llvm::Optional field_byte_width = field_compiler_type.GetByteSize(nullptr); + if (!field_byte_width) + return return_valobj_sp; DataExtractor *copy_from_extractor = nullptr; uint64_t return_value[2]; @@ -984,7 +982,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( if (idx == 0) { // This case is for long double type. - if (field_byte_width == 16) { + if (*field_byte_width == 16) { // If structure contains long double type, then it is returned // in fp0/fp1 registers. @@ -1002,7 +1000,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( return_value[0] = f1_data.GetU64(&offset); } - f0_data.SetData(return_value, field_byte_width, + f0_data.SetData(return_value, *field_byte_width, target_byte_order); } copy_from_extractor = &f0_data; // This is in f0, copy from @@ -1016,13 +1014,13 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( // Sanity check to avoid crash if (!copy_from_extractor || - field_byte_width > copy_from_extractor->GetByteSize()) + *field_byte_width > copy_from_extractor->GetByteSize()) return return_valobj_sp; // copy the register contents into our data buffer copy_from_extractor->CopyByteOrderedData( - 0, field_byte_width, - data_sp->GetBytes() + (field_bit_offset / 8), field_byte_width, + 0, *field_byte_width, + data_sp->GetBytes() + (field_bit_offset / 8), *field_byte_width, target_byte_order); } @@ -1045,12 +1043,12 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( idx, name, &field_bit_offset, nullptr, nullptr); - const size_t field_byte_width = + llvm::Optional field_byte_width = field_compiler_type.GetByteSize(nullptr); // if we don't know the size of the field (e.g. invalid type), just // bail out - if (field_byte_width == 0) + if (!field_byte_width || *field_byte_width == 0) break; uint32_t field_byte_offset = field_bit_offset / 8; @@ -1062,24 +1060,24 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( if (integer_bytes < 8) { // We have not yet consumed r2 completely. - if (integer_bytes + field_byte_width + padding <= 8) { + if (integer_bytes + *field_byte_width + padding <= 8) { // This field fits in r2, copy its value from r2 to our result // structure - integer_bytes = integer_bytes + field_byte_width + + integer_bytes = integer_bytes + *field_byte_width + padding; // Increase the consumed bytes. use_r2 = 1; } else { // There isn't enough space left in r2 for this field, so this // will be in r3. - integer_bytes = integer_bytes + field_byte_width + + integer_bytes = integer_bytes + *field_byte_width + padding; // Increase the consumed bytes. use_r3 = 1; } } // We already have consumed at-least 8 bytes that means r2 is done, // and this field will be in r3. Check if this field can fit in r3. - else if (integer_bytes + field_byte_width + padding <= 16) { - integer_bytes = integer_bytes + field_byte_width + padding; + else if (integer_bytes + *field_byte_width + padding <= 16) { + integer_bytes = integer_bytes + *field_byte_width + padding; use_r3 = 1; } else { // There isn't any space left for this field, this should not @@ -1092,7 +1090,7 @@ ValueObjectSP ABISysV_mips64::GetReturnValueObjectImpl( } // Vector types up to 16 bytes are returned in GP return registers if (type_flags & eTypeIsVector) { - if (byte_size <= 8) + if (*byte_size <= 8) use_r2 = 1; else { use_r2 = 1; diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h index 6258c08e35f9..c7670f467114 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-mips64/ABISysV_mips64.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_mips64_h_ #define liblldb_ABISysV_mips64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp index e93dcdbe1a59..1fe7a6718a91 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.cpp @@ -9,16 +9,11 @@ #include "ABISysV_ppc.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +27,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; @@ -224,11 +220,8 @@ size_t ABISysV_ppc::GetRedZoneSize() const { return 224; } ABISP ABISysV_ppc::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; if (arch.GetTriple().getArch() == llvm::Triple::ppc) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_ppc(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_ppc(process_sp)); } return ABISP(); } @@ -405,19 +398,18 @@ bool ABISysV_ppc::GetArgumentValues(Thread &thread, ValueList &values) const { // We currently only support extracting values with Clang QualTypes. Do we // care about others? CompilerType compiler_type = value->GetCompilerType(); - if (!compiler_type) + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (!bit_size) return false; bool is_signed; - - if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), - is_signed, thread, argument_register_ids, - current_argument_register, current_stack_argument); - } else if (compiler_type.IsPointerType()) { - ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), - false, thread, argument_register_ids, - current_argument_register, current_stack_argument); - } + if (compiler_type.IsIntegerOrEnumerationType(is_signed)) + ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread, + argument_register_ids, current_argument_register, + current_stack_argument); + else if (compiler_type.IsPointerType()) + ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread, + argument_register_ids, current_argument_register, + current_stack_argument); } return true; @@ -474,8 +466,13 @@ Status ABISysV_ppc::SetReturnValueObject(lldb::StackFrameSP &frame_sp, error.SetErrorString( "We don't support returning complex values at present"); else { - size_t bit_width = compiler_type.GetBitSize(frame_sp.get()); - if (bit_width <= 64) { + llvm::Optional bit_width = + compiler_type.GetBitSize(frame_sp.get()); + if (!bit_width) { + error.SetErrorString("can't get type size"); + return error; + } + if (*bit_width <= 64) { DataExtractor data; Status data_error; size_t num_bytes = new_value_sp->GetData(data, data_error); @@ -533,11 +530,14 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple( if (type_flags & eTypeIsInteger) { // Extract the register context so we can read arguments from registers - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (!byte_size) + return return_valobj_sp; uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned( reg_ctx->GetRegisterInfoByName("r3", 0), 0); const bool is_signed = (type_flags & eTypeIsSigned) != 0; - switch (byte_size) { + switch (*byte_size) { default: break; @@ -577,18 +577,19 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple( if (type_flags & eTypeIsComplex) { // Don't handle complex yet. } else { - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); - if (byte_size <= sizeof(long double)) { + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (byte_size && *byte_size <= sizeof(long double)) { const RegisterInfo *f1_info = reg_ctx->GetRegisterInfoByName("f1", 0); RegisterValue f1_value; if (reg_ctx->ReadRegister(f1_info, f1_value)) { DataExtractor data; if (f1_value.GetData(data)) { lldb::offset_t offset = 0; - if (byte_size == sizeof(float)) { + if (*byte_size == sizeof(float)) { value.GetScalar() = (float)data.GetFloat(&offset); success = true; - } else if (byte_size == sizeof(double)) { + } else if (*byte_size == sizeof(double)) { value.GetScalar() = (double)data.GetDouble(&offset); success = true; } @@ -610,15 +611,16 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple( return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsVector) { - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); - if (byte_size > 0) { + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (byte_size && *byte_size > 0) { const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("v2", 0); if (altivec_reg) { - if (byte_size <= altivec_reg->byte_size) { + if (*byte_size <= altivec_reg->byte_size) { ProcessSP process_sp(thread.GetProcess()); if (process_sp) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = process_sp->GetByteOrder(); RegisterValue reg_value; if (reg_ctx->ReadRegister(altivec_reg, reg_value)) { @@ -627,9 +629,10 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectSimple( altivec_reg, heap_data_ap->GetBytes(), heap_data_ap->GetByteSize(), byte_order, error)) { DataExtractor data(DataBufferSP(heap_data_ap.release()), - byte_order, process_sp->GetTarget() - .GetArchitecture() - .GetAddressByteSize()); + byte_order, + process_sp->GetTarget() + .GetArchitecture() + .GetAddressByteSize()); return_valobj_sp = ValueObjectConstResult::Create( &thread, return_compiler_type, ConstString(""), data); } @@ -659,11 +662,13 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl( if (!reg_ctx_sp) return return_valobj_sp; - const size_t bit_width = return_compiler_type.GetBitSize(&thread); + llvm::Optional bit_width = return_compiler_type.GetBitSize(&thread); + if (!bit_width) + return return_valobj_sp; if (return_compiler_type.IsAggregateType()) { Target *target = exe_ctx.GetTargetPtr(); bool is_memory = true; - if (bit_width <= 128) { + if (*bit_width <= 128) { ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder(); DataBufferSP data_sp(new DataBufferHeap(16, 0)); DataExtractor return_ext(data_sp, target_byte_order, @@ -701,15 +706,18 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl( CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( idx, name, &field_bit_offset, nullptr, nullptr); - const size_t field_bit_width = field_compiler_type.GetBitSize(&thread); + llvm::Optional field_bit_width = + field_compiler_type.GetBitSize(&thread); + if (!field_bit_width) + return return_valobj_sp; // If there are any unaligned fields, this is stored in memory. - if (field_bit_offset % field_bit_width != 0) { + if (field_bit_offset % *field_bit_width != 0) { is_memory = true; break; } - uint32_t field_byte_width = field_bit_width / 8; + uint32_t field_byte_width = *field_bit_width / 8; uint32_t field_byte_offset = field_bit_offset / 8; DataExtractor *copy_from_extractor = nullptr; @@ -742,13 +750,13 @@ ValueObjectSP ABISysV_ppc::GetReturnValueObjectImpl( } } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) { // Structs with long doubles are always passed in memory. - if (field_bit_width == 128) { + if (*field_bit_width == 128) { is_memory = true; break; - } else if (field_bit_width == 64) { + } else if (*field_bit_width == 64) { copy_from_offset = 0; fp_bytes += field_byte_width; - } else if (field_bit_width == 32) { + } else if (*field_bit_width == 32) { // This one is kind of complicated. If we are in an "eightbyte" // with another float, we'll be stuffed into an xmm register with // it. If we are in an "eightbyte" with one or more ints, then we diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h index df3ebe83faf8..3559cbb45200 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc/ABISysV_ppc.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_ppc_h_ #define liblldb_ABISysV_ppc_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp index d0140a0c894a..fb46b7dc7fb6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.cpp @@ -9,18 +9,13 @@ #include "ABISysV_ppc64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "Utility/PPC64LE_DWARF_Registers.h" #include "Utility/PPC64_DWARF_Registers.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -35,6 +30,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "clang/AST/ASTContext.h" @@ -284,18 +280,19 @@ bool ABISysV_ppc64::GetArgumentValues(Thread &thread, ValueList &values) const { // We currently only support extracting values with Clang QualTypes. Do we // care about others? CompilerType compiler_type = value->GetCompilerType(); - if (!compiler_type) + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (!bit_size) return false; bool is_signed; if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), - is_signed, thread, argument_register_ids, - current_argument_register, current_stack_argument); + ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread, + argument_register_ids, current_argument_register, + current_stack_argument); } else if (compiler_type.IsPointerType()) { - ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), - false, thread, argument_register_ids, - current_argument_register, current_stack_argument); + ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread, + argument_register_ids, current_argument_register, + current_stack_argument); } } @@ -353,8 +350,13 @@ Status ABISysV_ppc64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, error.SetErrorString( "We don't support returning complex values at present"); else { - size_t bit_width = compiler_type.GetBitSize(frame_sp.get()); - if (bit_width <= 64) { + llvm::Optional bit_width = + compiler_type.GetBitSize(frame_sp.get()); + if (!bit_width) { + error.SetErrorString("can't get size of type"); + return error; + } + if (*bit_width <= 64) { DataExtractor data; Status data_error; size_t num_bytes = new_value_sp->GetData(data, data_error); @@ -575,7 +577,7 @@ private: ReturnValueExtractor(Thread &thread, CompilerType &type, RegisterContext *reg_ctx, ProcessSP process_sp) : m_thread(thread), m_type(type), - m_byte_size(m_type.GetByteSize(nullptr)), + m_byte_size(m_type.GetByteSize(nullptr).getValueOr(0)), m_data_ap(new DataBufferHeap(m_byte_size, 0)), m_reg_ctx(reg_ctx), m_process_sp(process_sp), m_byte_order(process_sp->GetByteOrder()), m_addr_size( @@ -643,7 +645,7 @@ private: uint64_t raw_data; auto reg = GetFPR(reg_index); if (!reg.GetRawData(raw_data)) - return ValueSP(); + return {}; // build value from data ValueSP value_sp(NewScalarValue(type)); @@ -651,8 +653,10 @@ private: DataExtractor de(&raw_data, sizeof(raw_data), m_byte_order, m_addr_size); offset_t offset = 0; - size_t byte_size = type.GetByteSize(nullptr); - switch (byte_size) { + llvm::Optional byte_size = type.GetByteSize(nullptr); + if (!byte_size) + return {}; + switch (*byte_size) { case sizeof(float): value_sp->GetScalar() = (float)de.GetDouble(&offset); break; @@ -759,7 +763,7 @@ private: uint64_t addr; auto reg = GetGPR(0); if (!reg.GetRawData(addr)) - return ValueObjectSP(); + return {}; Status error; size_t rc = m_process_sp->ReadMemory(addr, m_data_ap->GetBytes(), @@ -773,37 +777,39 @@ private: // get number of children const bool omit_empty_base_classes = true; - uint32_t n = m_type.GetNumChildren(omit_empty_base_classes); + uint32_t n = m_type.GetNumChildren(omit_empty_base_classes, nullptr); if (!n) { LLDB_LOG(m_log, LOG_PREFIX "No children found in struct"); - return ValueObjectSP(); + return {}; } // case 2: homogeneous double or float aggregate CompilerType elem_type; if (m_type.IsHomogeneousAggregate(&elem_type)) { uint32_t type_flags = elem_type.GetTypeInfo(); - uint64_t elem_size = elem_type.GetByteSize(nullptr); + llvm::Optional elem_size = elem_type.GetByteSize(nullptr); + if (!elem_size) + return {}; if (type_flags & eTypeIsComplex || !(type_flags & eTypeIsFloat)) { LLDB_LOG(m_log, LOG_PREFIX "Unexpected type found in homogeneous aggregate"); - return ValueObjectSP(); + return {}; } for (uint32_t i = 0; i < n; i++) { ValueSP val_sp = GetFloatValue(elem_type, i); if (!val_sp) - return ValueObjectSP(); + return {}; // copy to buffer Status error; size_t rc = val_sp->GetScalar().GetAsMemoryData( - m_data_ap->GetBytes() + m_dst_offs, elem_size, m_byte_order, error); - if (rc != elem_size) { + m_data_ap->GetBytes() + m_dst_offs, *elem_size, m_byte_order, error); + if (rc != *elem_size) { LLDB_LOG(m_log, LOG_PREFIX "Failed to get float data"); - return ValueObjectSP(); + return {}; } - m_dst_offs += elem_size; + m_dst_offs += *elem_size; } return BuildValueObject(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h index 52765a773c0b..54f461e1001b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-ppc64/ABISysV_ppc64.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_ppc64_h_ #define liblldb_ABISysV_ppc64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp index 31e2825c0fa2..d8056ea7d356 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.cpp @@ -9,16 +9,11 @@ #include "ABISysV_s390x.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,6 +27,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; @@ -206,11 +202,8 @@ size_t ABISysV_s390x::GetRedZoneSize() const { return 0; } ABISP ABISysV_s390x::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; if (arch.GetTriple().getArch() == llvm::Triple::systemz) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_s390x(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_s390x(process_sp)); } return ABISP(); } @@ -383,18 +376,19 @@ bool ABISysV_s390x::GetArgumentValues(Thread &thread, ValueList &values) const { // We currently only support extracting values with Clang QualTypes. Do we // care about others? CompilerType compiler_type = value->GetCompilerType(); - if (!compiler_type) + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (!bit_size) return false; bool is_signed; if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), - is_signed, thread, argument_register_ids, - current_argument_register, current_stack_argument); + ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread, + argument_register_ids, current_argument_register, + current_stack_argument); } else if (compiler_type.IsPointerType()) { - ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), - false, thread, argument_register_ids, - current_argument_register, current_stack_argument); + ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread, + argument_register_ids, current_argument_register, + current_stack_argument); } } @@ -452,8 +446,13 @@ Status ABISysV_s390x::SetReturnValueObject(lldb::StackFrameSP &frame_sp, error.SetErrorString( "We don't support returning complex values at present"); else { - size_t bit_width = compiler_type.GetBitSize(frame_sp.get()); - if (bit_width <= 64) { + llvm::Optional bit_width = + compiler_type.GetBitSize(frame_sp.get()); + if (!bit_width) { + error.SetErrorString("can't get type size"); + return error; + } + if (*bit_width <= 64) { const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); RegisterValue f0_value; DataExtractor data; @@ -513,13 +512,15 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple( bool success = false; if (type_flags & eTypeIsInteger) { - // Extract the register context so we can read arguments from registers - - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); + // Extract the register context so we can read arguments from registers. + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (!byte_size) + return return_valobj_sp; uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned( reg_ctx->GetRegisterInfoByName("r2", 0), 0); const bool is_signed = (type_flags & eTypeIsSigned) != 0; - switch (byte_size) { + switch (*byte_size) { default: break; @@ -559,21 +560,22 @@ ValueObjectSP ABISysV_s390x::GetReturnValueObjectSimple( if (type_flags & eTypeIsComplex) { // Don't handle complex yet. } else { - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); - if (byte_size <= sizeof(long double)) { + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (byte_size && *byte_size <= sizeof(long double)) { const RegisterInfo *f0_info = reg_ctx->GetRegisterInfoByName("f0", 0); RegisterValue f0_value; if (reg_ctx->ReadRegister(f0_info, f0_value)) { DataExtractor data; if (f0_value.GetData(data)) { lldb::offset_t offset = 0; - if (byte_size == sizeof(float)) { + if (*byte_size == sizeof(float)) { value.GetScalar() = (float)data.GetFloat(&offset); success = true; - } else if (byte_size == sizeof(double)) { + } else if (*byte_size == sizeof(double)) { value.GetScalar() = (double)data.GetDouble(&offset); success = true; - } else if (byte_size == sizeof(long double)) { + } else if (*byte_size == sizeof(long double)) { // Don't handle long double yet. } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h index 5e3d20d7898b..5433ebb4593e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-s390x/ABISysV_s390x.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_s390x_h_ #define liblldb_ABISysV_s390x_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" @@ -61,9 +57,7 @@ public: bool CodeAddressIsValid(lldb::addr_t pc) override { // Code addressed must be 2 byte aligned - if (pc & 1ull) - return false; - return true; + return (pc & 1ull) == 0; } const lldb_private::RegisterInfo * diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp index 36ae3a49827c..dc3e475e3b8e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp @@ -9,17 +9,12 @@ #include "ABISysV_x86_64.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -33,6 +28,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; @@ -1095,11 +1091,8 @@ size_t ABISysV_x86_64::GetRedZoneSize() const { return 128; } ABISP ABISysV_x86_64::CreateInstance(lldb::ProcessSP process_sp, const ArchSpec &arch) { - static ABISP g_abi_sp; if (arch.GetTriple().getArch() == llvm::Triple::x86_64) { - if (!g_abi_sp) - g_abi_sp.reset(new ABISysV_x86_64(process_sp)); - return g_abi_sp; + return ABISP(new ABISysV_x86_64(process_sp)); } return ABISP(); } @@ -1270,18 +1263,19 @@ bool ABISysV_x86_64::GetArgumentValues(Thread &thread, // We currently only support extracting values with Clang QualTypes. Do we // care about others? CompilerType compiler_type = value->GetCompilerType(); - if (!compiler_type) + llvm::Optional bit_size = compiler_type.GetBitSize(&thread); + if (!bit_size) return false; bool is_signed; if (compiler_type.IsIntegerOrEnumerationType(is_signed)) { - ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), - is_signed, thread, argument_register_ids, - current_argument_register, current_stack_argument); + ReadIntegerArgument(value->GetScalar(), *bit_size, is_signed, thread, + argument_register_ids, current_argument_register, + current_stack_argument); } else if (compiler_type.IsPointerType()) { - ReadIntegerArgument(value->GetScalar(), compiler_type.GetBitSize(&thread), - false, thread, argument_register_ids, - current_argument_register, current_stack_argument); + ReadIntegerArgument(value->GetScalar(), *bit_size, false, thread, + argument_register_ids, current_argument_register, + current_stack_argument); } } @@ -1339,8 +1333,13 @@ Status ABISysV_x86_64::SetReturnValueObject(lldb::StackFrameSP &frame_sp, error.SetErrorString( "We don't support returning complex values at present"); else { - size_t bit_width = compiler_type.GetBitSize(frame_sp.get()); - if (bit_width <= 64) { + llvm::Optional bit_width = + compiler_type.GetBitSize(frame_sp.get()); + if (!bit_width) { + error.SetErrorString("can't get type size"); + return error; + } + if (*bit_width <= 64) { const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0); RegisterValue xmm0_value; @@ -1403,11 +1402,14 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( if (type_flags & eTypeIsInteger) { // Extract the register context so we can read arguments from registers - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (!byte_size) + return return_valobj_sp; uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned( reg_ctx->GetRegisterInfoByName("rax", 0), 0); const bool is_signed = (type_flags & eTypeIsSigned) != 0; - switch (byte_size) { + switch (*byte_size) { default: break; @@ -1447,8 +1449,9 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( if (type_flags & eTypeIsComplex) { // Don't handle complex yet. } else { - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); - if (byte_size <= sizeof(long double)) { + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (byte_size && *byte_size <= sizeof(long double)) { const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0); RegisterValue xmm0_value; @@ -1456,13 +1459,13 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( DataExtractor data; if (xmm0_value.GetData(data)) { lldb::offset_t offset = 0; - if (byte_size == sizeof(float)) { + if (*byte_size == sizeof(float)) { value.GetScalar() = (float)data.GetFloat(&offset); success = true; - } else if (byte_size == sizeof(double)) { + } else if (*byte_size == sizeof(double)) { value.GetScalar() = (double)data.GetDouble(&offset); success = true; - } else if (byte_size == sizeof(long double)) { + } else if (*byte_size == sizeof(long double)) { // Don't handle long double since that can be encoded as 80 bit // floats... } @@ -1485,19 +1488,20 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( return_valobj_sp = ValueObjectConstResult::Create( thread.GetStackFrameAtIndex(0).get(), value, ConstString("")); } else if (type_flags & eTypeIsVector) { - const size_t byte_size = return_compiler_type.GetByteSize(nullptr); - if (byte_size > 0) { + llvm::Optional byte_size = + return_compiler_type.GetByteSize(nullptr); + if (byte_size && *byte_size > 0) { const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0); if (altivec_reg == nullptr) altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0); if (altivec_reg) { - if (byte_size <= altivec_reg->byte_size) { + if (*byte_size <= altivec_reg->byte_size) { ProcessSP process_sp(thread.GetProcess()); if (process_sp) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = process_sp->GetByteOrder(); RegisterValue reg_value; if (reg_ctx->ReadRegister(altivec_reg, reg_value)) { @@ -1514,14 +1518,14 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectSimple( } } } - } else if (byte_size <= altivec_reg->byte_size * 2) { + } else if (*byte_size <= altivec_reg->byte_size * 2) { const RegisterInfo *altivec_reg2 = reg_ctx->GetRegisterInfoByName("xmm1", 0); if (altivec_reg2) { ProcessSP process_sp(thread.GetProcess()); if (process_sp) { std::unique_ptr heap_data_ap( - new DataBufferHeap(byte_size, 0)); + new DataBufferHeap(*byte_size, 0)); const ByteOrder byte_order = process_sp->GetByteOrder(); RegisterValue reg_value; RegisterValue reg_value2; @@ -1571,11 +1575,13 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl( if (!reg_ctx_sp) return return_valobj_sp; - const size_t bit_width = return_compiler_type.GetBitSize(&thread); + llvm::Optional bit_width = return_compiler_type.GetBitSize(&thread); + if (!bit_width) + return return_valobj_sp; if (return_compiler_type.IsAggregateType()) { Target *target = exe_ctx.GetTargetPtr(); bool is_memory = true; - if (bit_width <= 128) { + if (*bit_width <= 128) { ByteOrder target_byte_order = target->GetArchitecture().GetByteOrder(); DataBufferSP data_sp(new DataBufferHeap(16, 0)); DataExtractor return_ext(data_sp, target_byte_order, @@ -1622,20 +1628,21 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl( CompilerType field_compiler_type = return_compiler_type.GetFieldAtIndex( idx, name, &field_bit_offset, nullptr, nullptr); - const size_t field_bit_width = field_compiler_type.GetBitSize(&thread); + llvm::Optional field_bit_width = + field_compiler_type.GetBitSize(&thread); // if we don't know the size of the field (e.g. invalid type), just // bail out - if (field_bit_width == 0) + if (!field_bit_width || *field_bit_width == 0) break; // If there are any unaligned fields, this is stored in memory. - if (field_bit_offset % field_bit_width != 0) { + if (field_bit_offset % *field_bit_width != 0) { is_memory = true; break; } - uint32_t field_byte_width = field_bit_width / 8; + uint32_t field_byte_width = *field_bit_width / 8; uint32_t field_byte_offset = field_bit_offset / 8; DataExtractor *copy_from_extractor = nullptr; @@ -1668,10 +1675,10 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl( } } else if (field_compiler_type.IsFloatingPointType(count, is_complex)) { // Structs with long doubles are always passed in memory. - if (field_bit_width == 128) { + if (*field_bit_width == 128) { is_memory = true; break; - } else if (field_bit_width == 64) { + } else if (*field_bit_width == 64) { // These have to be in a single xmm register. if (fp_bytes == 0) copy_from_extractor = &xmm0_data; @@ -1680,7 +1687,7 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl( copy_from_offset = 0; fp_bytes += field_byte_width; - } else if (field_bit_width == 32) { + } else if (*field_bit_width == 32) { // This one is kind of complicated. If we are in an "eightbyte" // with another float, we'll be stuffed into an xmm register with // it. If we are in an "eightbyte" with one or more ints, then we diff --git a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h index 5b67e8656d36..4afc8c4cad62 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h @@ -10,10 +10,6 @@ #ifndef liblldb_ABISysV_x86_64_h_ #define liblldb_ABISysV_x86_64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp index 1b7ecc88c35e..6993222ba5d4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.cpp @@ -126,3 +126,33 @@ void ArchitectureArm::OverrideStopInfo(Thread &thread) const { } } } + +addr_t ArchitectureArm::GetCallableLoadAddress(addr_t code_addr, + AddressClass addr_class) const { + bool is_alternate_isa = false; + + switch (addr_class) { + case AddressClass::eData: + case AddressClass::eDebug: + return LLDB_INVALID_ADDRESS; + case AddressClass::eCodeAlternateISA: + is_alternate_isa = true; + break; + default: break; + } + + if ((code_addr & 2u) || is_alternate_isa) + return code_addr | 1u; + return code_addr; +} + +addr_t ArchitectureArm::GetOpcodeLoadAddress(addr_t opcode_addr, + AddressClass addr_class) const { + switch (addr_class) { + case AddressClass::eData: + case AddressClass::eDebug: + return LLDB_INVALID_ADDRESS; + default: break; + } + return opcode_addr & ~(1ull); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h b/contrib/llvm/tools/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h index 484c4a52fcc6..1a052c76b2c9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Architecture/Arm/ArchitectureArm.h @@ -25,6 +25,12 @@ public: void OverrideStopInfo(Thread &thread) const override; + lldb::addr_t GetCallableLoadAddress(lldb::addr_t load_addr, + AddressClass addr_class) const override; + + lldb::addr_t GetOpcodeLoadAddress(lldb::addr_t load_addr, + AddressClass addr_class) const override; + private: static std::unique_ptr Create(const ArchSpec &arch); ArchitectureArm() = default; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp b/contrib/llvm/tools/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp new file mode 100644 index 000000000000..0cbbd9922321 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.cpp @@ -0,0 +1,241 @@ +//===-- ArchitectureMips.cpp -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Plugins/Architecture/Mips/ArchitectureMips.h" +#include "lldb/Core/Address.h" +#include "lldb/Core/Disassembler.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Symbol/Function.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/Target.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Log.h" + +using namespace lldb_private; +using namespace lldb; + +ConstString ArchitectureMips::GetPluginNameStatic() { + return ConstString("mips"); +} + +void ArchitectureMips::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + "Mips-specific algorithms", + &ArchitectureMips::Create); +} + +void ArchitectureMips::Terminate() { + PluginManager::UnregisterPlugin(&ArchitectureMips::Create); +} + +std::unique_ptr ArchitectureMips::Create(const ArchSpec &arch) { + return arch.IsMIPS() ? + std::unique_ptr(new ArchitectureMips(arch)) : nullptr; +} + +ConstString ArchitectureMips::GetPluginName() { return GetPluginNameStatic(); } +uint32_t ArchitectureMips::GetPluginVersion() { return 1; } + +addr_t ArchitectureMips::GetCallableLoadAddress(addr_t code_addr, + AddressClass addr_class) const { + bool is_alternate_isa = false; + + switch (addr_class) { + case AddressClass::eData: + case AddressClass::eDebug: + return LLDB_INVALID_ADDRESS; + case AddressClass::eCodeAlternateISA: + is_alternate_isa = true; + break; + default: break; + } + + if ((code_addr & 2ull) || is_alternate_isa) + return code_addr | 1u; + return code_addr; +} + +addr_t ArchitectureMips::GetOpcodeLoadAddress(addr_t opcode_addr, + AddressClass addr_class) const { + switch (addr_class) { + case AddressClass::eData: + case AddressClass::eDebug: + return LLDB_INVALID_ADDRESS; + default: break; + } + return opcode_addr & ~(1ull); +} + +lldb::addr_t ArchitectureMips::GetBreakableLoadAddress(lldb::addr_t addr, + Target &target) const { + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); + + Address resolved_addr; + + SectionLoadList §ion_load_list = target.GetSectionLoadList(); + if (section_load_list.IsEmpty()) + // No sections are loaded, so we must assume we are not running yet and + // need to operate only on file address. + target.ResolveFileAddress(addr, resolved_addr); + else + target.ResolveLoadAddress(addr, resolved_addr); + + addr_t current_offset = 0; + + // Get the function boundaries to make sure we don't scan back before the + // beginning of the current function. + ModuleSP temp_addr_module_sp(resolved_addr.GetModule()); + if (temp_addr_module_sp) { + SymbolContext sc; + SymbolContextItem resolve_scope = + eSymbolContextFunction | eSymbolContextSymbol; + temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr, + resolve_scope, sc); + Address sym_addr; + if (sc.function) + sym_addr = sc.function->GetAddressRange().GetBaseAddress(); + else if (sc.symbol) + sym_addr = sc.symbol->GetAddress(); + + addr_t function_start = sym_addr.GetLoadAddress(&target); + if (function_start == LLDB_INVALID_ADDRESS) + function_start = sym_addr.GetFileAddress(); + + if (function_start) + current_offset = addr - function_start; + } + + // If breakpoint address is start of function then we dont have to do + // anything. + if (current_offset == 0) + return addr; + + ExecutionContext ctx; + target.CalculateExecutionContext(ctx); + auto insn = GetInstructionAtAddress(ctx, current_offset, addr); + + if (nullptr == insn || !insn->HasDelaySlot()) + return addr; + + // Adjust the breakable address + uint64_t breakable_addr = addr - insn->GetOpcode().GetByteSize(); + if (log) + log->Printf("Target::%s Breakpoint at 0x%8.8" PRIx64 + " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n", + __FUNCTION__, addr, breakable_addr); + + return breakable_addr; +} + +Instruction *ArchitectureMips::GetInstructionAtAddress( + const ExecutionContext &exe_ctx, const Address &resolved_addr, + addr_t symbol_offset) const { + + auto loop_count = symbol_offset / 2; + + uint32_t arch_flags = m_arch.GetFlags(); + bool IsMips16 = arch_flags & ArchSpec::eMIPSAse_mips16; + bool IsMicromips = arch_flags & ArchSpec::eMIPSAse_micromips; + + if (loop_count > 3) { + // Scan previous 6 bytes + if (IsMips16 | IsMicromips) + loop_count = 3; + // For mips-only, instructions are always 4 bytes, so scan previous 4 + // bytes only. + else + loop_count = 2; + } + + // Create Disassembler Instance + lldb::DisassemblerSP disasm_sp( + Disassembler::FindPlugin(m_arch, nullptr, nullptr)); + + InstructionList instruction_list; + InstructionSP prev_insn; + bool prefer_file_cache = true; // Read from file + uint32_t inst_to_choose = 0; + + Address addr = resolved_addr; + + for (uint32_t i = 1; i <= loop_count; i++) { + // Adjust the address to read from. + addr.Slide(-2); + AddressRange range(addr, i * 2); + uint32_t insn_size = 0; + + disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache); + + uint32_t num_insns = disasm_sp->GetInstructionList().GetSize(); + if (num_insns) { + prev_insn = disasm_sp->GetInstructionList().GetInstructionAtIndex(0); + insn_size = prev_insn->GetOpcode().GetByteSize(); + if (i == 1 && insn_size == 2) { + // This looks like a valid 2-byte instruction (but it could be a part + // of upper 4 byte instruction). + instruction_list.Append(prev_insn); + inst_to_choose = 1; + } + else if (i == 2) { + // Here we may get one 4-byte instruction or two 2-byte instructions. + if (num_insns == 2) { + // Looks like there are two 2-byte instructions above our + // breakpoint target address. Now the upper 2-byte instruction is + // either a valid 2-byte instruction or could be a part of it's + // upper 4-byte instruction. In both cases we don't care because in + // this case lower 2-byte instruction is definitely a valid + // instruction and whatever i=1 iteration has found out is true. + inst_to_choose = 1; + break; + } + else if (insn_size == 4) { + // This instruction claims its a valid 4-byte instruction. But it + // could be a part of it's upper 4-byte instruction. Lets try + // scanning upper 2 bytes to verify this. + instruction_list.Append(prev_insn); + inst_to_choose = 2; + } + } + else if (i == 3) { + if (insn_size == 4) + // FIXME: We reached here that means instruction at [target - 4] has + // already claimed to be a 4-byte instruction, and now instruction + // at [target - 6] is also claiming that it's a 4-byte instruction. + // This can not be true. In this case we can not decide the valid + // previous instruction so we let lldb set the breakpoint at the + // address given by user. + inst_to_choose = 0; + else + // This is straight-forward + inst_to_choose = 2; + break; + } + } + else { + // Decode failed, bytes do not form a valid instruction. So whatever + // previous iteration has found out is true. + if (i > 1) { + inst_to_choose = i - 1; + break; + } + } + } + + // Check if we are able to find any valid instruction. + if (inst_to_choose) { + if (inst_to_choose > instruction_list.GetSize()) + inst_to_choose--; + return instruction_list.GetInstructionAtIndex(inst_to_choose - 1).get(); + } + + return nullptr; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h b/contrib/llvm/tools/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h new file mode 100644 index 000000000000..2338daf2e468 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Architecture/Mips/ArchitectureMips.h @@ -0,0 +1,52 @@ +//===-- ArchitectureMips.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGIN_ARCHITECTURE_MIPS_H +#define LLDB_PLUGIN_ARCHITECTURE_MIPS_H + +#include "lldb/Core/Architecture.h" +#include "lldb/Utility/ArchSpec.h" + +namespace lldb_private { + +class ArchitectureMips : public Architecture { +public: + static ConstString GetPluginNameStatic(); + static void Initialize(); + static void Terminate(); + + ConstString GetPluginName() override; + uint32_t GetPluginVersion() override; + + void OverrideStopInfo(Thread &thread) const override {} + + lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr, + Target &) const override; + + lldb::addr_t GetCallableLoadAddress(lldb::addr_t load_addr, + AddressClass addr_class) const override; + + lldb::addr_t GetOpcodeLoadAddress(lldb::addr_t load_addr, + AddressClass addr_class) const override; + +private: + Instruction *GetInstructionAtAddress(const ExecutionContext &exe_ctx, + const Address &resolved_addr, + lldb::addr_t symbol_offset) const; + + + static std::unique_ptr Create(const ArchSpec &arch); + ArchitectureMips(const ArchSpec &arch) : m_arch(arch) {} + + ArchSpec m_arch; +}; + +} // namespace lldb_private + +#endif // LLDB_PLUGIN_ARCHITECTURE_MIPS_H diff --git a/contrib/llvm/tools/lldb/source/Plugins/Architecture/PPC64/CMakeLists.txt b/contrib/llvm/tools/lldb/source/Plugins/Architecture/PPC64/CMakeLists.txt deleted file mode 100644 index 2cba112cf882..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Architecture/PPC64/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_lldb_library(lldbPluginArchitecturePPC64 PLUGIN - ArchitecturePPC64.cpp - - LINK_LIBS - lldbPluginProcessUtility - lldbCore - lldbTarget - lldbUtility - LINK_COMPONENTS - Support - ) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp b/contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp index 9b381dd3b96c..5df842250591 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Project includes #include "DisassemblerLLVMC.h" -// Other libraries and framework includes #include "llvm-c/Disassembler.h" #include "llvm/ADT/SmallString.h" #include "llvm/MC/MCAsmInfo.h" @@ -98,16 +94,15 @@ public: bool DoesBranch() override { if (m_does_branch == eLazyBoolCalculate) { - std::shared_ptr disasm_sp(GetDisassembler()); - if (disasm_sp) { - disasm_sp->Lock(this, NULL); + DisassemblerScope disasm(*this); + if (disasm) { DataExtractor data; if (m_opcode.GetData(data)) { bool is_alternate_isa; lldb::addr_t pc = m_address.GetFileAddress(); DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr = - GetDisasmToUse(is_alternate_isa); + GetDisasmToUse(is_alternate_isa, disasm); const uint8_t *opcode_data = data.GetDataStart(); const size_t opcode_data_len = data.GetByteSize(); llvm::MCInst inst; @@ -125,7 +120,6 @@ public: m_does_branch = eLazyBoolNo; } } - disasm_sp->Unlock(); } } return m_does_branch == eLazyBoolYes; @@ -133,16 +127,15 @@ public: bool HasDelaySlot() override { if (m_has_delay_slot == eLazyBoolCalculate) { - std::shared_ptr disasm_sp(GetDisassembler()); - if (disasm_sp) { - disasm_sp->Lock(this, NULL); + DisassemblerScope disasm(*this); + if (disasm) { DataExtractor data; if (m_opcode.GetData(data)) { bool is_alternate_isa; lldb::addr_t pc = m_address.GetFileAddress(); DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr = - GetDisasmToUse(is_alternate_isa); + GetDisasmToUse(is_alternate_isa, disasm); const uint8_t *opcode_data = data.GetDataStart(); const size_t opcode_data_len = data.GetByteSize(); llvm::MCInst inst; @@ -160,27 +153,14 @@ public: m_has_delay_slot = eLazyBoolNo; } } - disasm_sp->Unlock(); } } return m_has_delay_slot == eLazyBoolYes; } DisassemblerLLVMC::MCDisasmInstance *GetDisasmToUse(bool &is_alternate_isa) { - is_alternate_isa = false; - std::shared_ptr disasm_sp(GetDisassembler()); - if (disasm_sp) { - if (disasm_sp->m_alternate_disasm_up) { - const AddressClass address_class = GetAddressClass(); - - if (address_class == AddressClass::eCodeAlternateISA) { - is_alternate_isa = true; - return disasm_sp->m_alternate_disasm_up.get(); - } - } - return disasm_sp->m_disasm_up.get(); - } - return nullptr; + DisassemblerScope disasm(*this); + return GetDisasmToUse(is_alternate_isa, disasm); } size_t Decode(const lldb_private::Disassembler &disassembler, @@ -189,9 +169,9 @@ public: // All we have to do is read the opcode which can be easy for some // architectures bool got_op = false; - std::shared_ptr disasm_sp(GetDisassembler()); - if (disasm_sp) { - const ArchSpec &arch = disasm_sp->GetArchitecture(); + DisassemblerScope disasm(*this); + if (disasm) { + const ArchSpec &arch = disasm->GetArchitecture(); const lldb::ByteOrder byte_order = data.GetByteOrder(); const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize(); @@ -232,7 +212,7 @@ public: if (!got_op) { bool is_alternate_isa = false; DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr = - GetDisasmToUse(is_alternate_isa); + GetDisasmToUse(is_alternate_isa, disasm); const llvm::Triple::ArchType machine = arch.GetMachine(); if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) { @@ -261,10 +241,8 @@ public: const addr_t pc = m_address.GetFileAddress(); llvm::MCInst inst; - disasm_sp->Lock(this, NULL); const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst); - disasm_sp->Unlock(); if (inst_size == 0) m_opcode.Clear(); else { @@ -296,19 +274,19 @@ public: std::string out_string; std::string comment_string; - std::shared_ptr disasm_sp(GetDisassembler()); - if (disasm_sp) { + DisassemblerScope disasm(*this, exe_ctx); + if (disasm) { DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr; if (address_class == AddressClass::eCodeAlternateISA) - mc_disasm_ptr = disasm_sp->m_alternate_disasm_up.get(); + mc_disasm_ptr = disasm->m_alternate_disasm_up.get(); else - mc_disasm_ptr = disasm_sp->m_disasm_up.get(); + mc_disasm_ptr = disasm->m_disasm_up.get(); lldb::addr_t pc = m_address.GetFileAddress(); m_using_file_addr = true; - const bool data_from_file = disasm_sp->m_data_from_file; + const bool data_from_file = disasm->m_data_from_file; bool use_hex_immediates = true; Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC; @@ -328,8 +306,6 @@ public: } } - disasm_sp->Lock(this, exe_ctx); - const uint8_t *opcode_data = data.GetDataStart(); const size_t opcode_data_len = data.GetByteSize(); llvm::MCInst inst; @@ -345,8 +321,6 @@ public: } } - disasm_sp->Unlock(); - if (inst_size == 0) { m_comment.assign("unknown opcode"); inst_size = m_opcode.GetByteSize(); @@ -423,9 +397,27 @@ public: bool UsingFileAddress() const { return m_using_file_addr; } size_t GetByteSize() const { return m_opcode.GetByteSize(); } - std::shared_ptr GetDisassembler() { - return m_disasm_wp.lock(); - } + /// Grants exclusive access to the disassembler and initializes it with the + /// given InstructionLLVMC and an optional ExecutionContext. + class DisassemblerScope { + std::shared_ptr m_disasm; + + public: + explicit DisassemblerScope( + InstructionLLVMC &i, + const lldb_private::ExecutionContext *exe_ctx = nullptr) + : m_disasm(i.m_disasm_wp.lock()) { + m_disasm->m_mutex.lock(); + m_disasm->m_inst = &i; + m_disasm->m_exe_ctx = exe_ctx; + } + ~DisassemblerScope() { m_disasm->m_mutex.unlock(); } + + /// Evaluates to true if this scope contains a valid disassembler. + operator bool() const { return static_cast(m_disasm); } + + std::shared_ptr operator->() { return m_disasm; } + }; static llvm::StringRef::const_iterator ConsumeWhitespace(llvm::StringRef::const_iterator osi, @@ -876,16 +868,15 @@ public: bool IsCall() override { if (m_is_call == eLazyBoolCalculate) { - std::shared_ptr disasm_sp(GetDisassembler()); - if (disasm_sp) { - disasm_sp->Lock(this, NULL); + DisassemblerScope disasm(*this); + if (disasm) { DataExtractor data; if (m_opcode.GetData(data)) { bool is_alternate_isa; lldb::addr_t pc = m_address.GetFileAddress(); DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr = - GetDisasmToUse(is_alternate_isa); + GetDisasmToUse(is_alternate_isa, disasm); const uint8_t *opcode_data = data.GetDataStart(); const size_t opcode_data_len = data.GetByteSize(); llvm::MCInst inst; @@ -900,7 +891,6 @@ public: m_is_call = eLazyBoolNo; } } - disasm_sp->Unlock(); } } return m_is_call == eLazyBoolYes; @@ -913,6 +903,24 @@ protected: LazyBool m_is_call; bool m_is_valid; bool m_using_file_addr; + +private: + DisassemblerLLVMC::MCDisasmInstance * + GetDisasmToUse(bool &is_alternate_isa, DisassemblerScope &disasm) { + is_alternate_isa = false; + if (disasm) { + if (disasm->m_alternate_disasm_up) { + const AddressClass address_class = GetAddressClass(); + + if (address_class == AddressClass::eCodeAlternateISA) { + is_alternate_isa = true; + return disasm->m_alternate_disasm_up.get(); + } + } + return disasm->m_disasm_up.get(); + } + return nullptr; + } }; std::unique_ptr @@ -1114,11 +1122,13 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, triple.getSubArch() == llvm::Triple::NoSubArch) triple.setArchName("armv8.2a"); + std::string features_str = ""; const char *triple_str = triple.getTriple().c_str(); // ARM Cortex M0-M7 devices only execute thumb instructions if (arch.IsAlwaysThumbInstructions()) { triple_str = thumb_arch.GetTriple().getTriple().c_str(); + features_str += "+fp-armv8,"; } const char *cpu = ""; @@ -1169,7 +1179,6 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, break; } - std::string features_str = ""; if (triple.getArch() == llvm::Triple::mips || triple.getArch() == llvm::Triple::mipsel || triple.getArch() == llvm::Triple::mips64 || @@ -1201,7 +1210,8 @@ DisassemblerLLVMC::DisassemblerLLVMC(const ArchSpec &arch, if (llvm_arch == llvm::Triple::arm) { std::string thumb_triple(thumb_arch.GetTriple().getTriple()); m_alternate_disasm_up = - MCDisasmInstance::Create(thumb_triple.c_str(), "", "", flavor, *this); + MCDisasmInstance::Create(thumb_triple.c_str(), "", features_str.c_str(), + flavor, *this); if (!m_alternate_disasm_up) m_disasm_up.reset(); @@ -1326,10 +1336,7 @@ bool DisassemblerLLVMC::FlavorValidForArchSpec( if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64) { - if (strcmp(flavor, "intel") == 0 || strcmp(flavor, "att") == 0) - return true; - else - return false; + return strcmp(flavor, "intel") == 0 || strcmp(flavor, "att") == 0; } else return false; } @@ -1368,7 +1375,7 @@ const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr, } SymbolContext sym_ctx; - const uint32_t resolve_scope = + const SymbolContextItem resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; if (pc_so_addr.IsValid() && pc_so_addr.GetModule()) { pc_so_addr.GetModule()->ResolveSymbolContextForAddress( diff --git a/contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h b/contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h index b7e9ccb34701..8b9f7c37d2b8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h @@ -10,13 +10,10 @@ #ifndef liblldb_DisassemblerLLVMC_h_ #define liblldb_DisassemblerLLVMC_h_ -// C Includes -// C++ Includes #include #include #include -// Project includes #include "lldb/Core/Address.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/PluginManager.h" @@ -77,19 +74,6 @@ protected: uint64_t ReferencePC, const char **ReferenceName); - void Lock(InstructionLLVMC *inst, - const lldb_private::ExecutionContext *exe_ctx) { - m_mutex.lock(); - m_inst = inst; - m_exe_ctx = exe_ctx; - } - - void Unlock() { - m_inst = NULL; - m_exe_ctx = NULL; - m_mutex.unlock(); - } - const lldb_private::ExecutionContext *m_exe_ctx; InstructionLLVMC *m_inst; std::mutex m_mutex; diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp index 5ca20229d018..81eab8fdd970 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" @@ -179,7 +176,7 @@ ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() { return executable; // The target executable file does not exits - if (!executable->GetFileSpec().Exists()) + if (!FileSystem::Instance().Exists(executable->GetFileSpec())) return executable; // Prep module for loading @@ -205,8 +202,7 @@ ModuleSP DynamicLoaderHexagonDYLD::GetTargetExecutable() { if (executable.get() != target.GetExecutableModulePointer()) { // Don't load dependent images since we are in dyld where we will know and // find out about all images that are loaded - const bool get_dependent_images = false; - target.SetExecutableModule(executable, get_dependent_images); + target.SetExecutableModule(executable, eLoadDependentsNo); } return executable; @@ -368,7 +364,8 @@ void DynamicLoaderHexagonDYLD::RefreshModules() { E = m_rendezvous.loaded_end(); for (I = m_rendezvous.loaded_begin(); I != E; ++I) { - FileSpec file(I->path, true); + FileSpec file(I->path); + FileSystem::Instance().Resolve(file); ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr, true); if (module_sp.get()) { @@ -392,7 +389,8 @@ void DynamicLoaderHexagonDYLD::RefreshModules() { E = m_rendezvous.unloaded_end(); for (I = m_rendezvous.unloaded_begin(); I != E; ++I) { - FileSpec file(I->path, true); + FileSpec file(I->path); + FileSystem::Instance().Resolve(file); ModuleSpec module_spec(file); ModuleSP module_sp = loaded_modules.FindFirstModule(module_spec); @@ -455,7 +453,7 @@ DynamicLoaderHexagonDYLD::GetStepThroughTrampolinePlan(Thread &thread, AddressVector::iterator start = addrs.begin(); AddressVector::iterator end = addrs.end(); - std::sort(start, end); + llvm::sort(start, end); addrs.erase(std::unique(start, end), end); thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop)); } @@ -486,7 +484,7 @@ void DynamicLoaderHexagonDYLD::LoadAllCurrentModules() { for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I) { const char *module_path = I->path.c_str(); - FileSpec file(module_path, false); + FileSpec file(module_path); ModuleSP module_sp = LoadModuleAtAddress(file, I->link_addr, I->base_addr, true); if (module_sp.get()) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h index 200a4171bd1c..d39f14e8b3fb 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.h @@ -10,10 +10,6 @@ #ifndef liblldb_DynamicLoaderHexagonDYLD_h_ #define liblldb_DynamicLoaderHexagonDYLD_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Target/DynamicLoader.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h index bdf6bae75197..758f358dc618 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.h @@ -10,14 +10,11 @@ #ifndef liblldb_HexagonDYLDRendezvous_H_ #define liblldb_HexagonDYLDRendezvous_H_ -// C Includes -#include // for PATH_MAX -// C++ Includes +#include #include #include #include -// Other libraries and framework includes #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp index 7dd2b57da0cb..8068795df53a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp @@ -100,7 +100,7 @@ const char *AuxVector::GetEntryName(EntryType type) { #define ENTRY_NAME(_type) \ _type: \ - name = #_type + 5 + name = &#_type[5] switch (type) { case ENTRY_NAME(AUXV_AT_NULL); break; case ENTRY_NAME(AUXV_AT_IGNORE); break; diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h index 3b06fe18f0c6..25446e33afd4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h @@ -10,11 +10,8 @@ #ifndef liblldb_AuxVector_H_ #define liblldb_AuxVector_H_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "lldb/lldb-forward.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp index b1513b51a90a..b30a1ab2cf1f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -243,7 +243,7 @@ bool DYLDRendezvous::FillSOEntryFromModuleInfo( entry.base_addr = base_addr; entry.dyn_addr = dyn_addr; - entry.file_spec.SetFile(name, false, FileSpec::Style::native); + entry.file_spec.SetFile(name, FileSpec::Style::native); UpdateBaseAddrIfNecessary(entry, name); @@ -455,14 +455,10 @@ static bool isLoadBiasIncorrect(Target &target, const std::string &file_path) { // On Android L (API 21, 22) the load address of the "/system/bin/linker" // isn't filled in correctly. unsigned os_major = target.GetPlatform()->GetOSVersion().getMajor(); - if (target.GetArchitecture().GetTriple().isAndroid() && - (os_major == 21 || os_major == 22) && - (file_path == "/system/bin/linker" || - file_path == "/system/bin/linker64")) { - return true; - } - - return false; + return target.GetArchitecture().GetTriple().isAndroid() && + (os_major == 21 || os_major == 22) && + (file_path == "/system/bin/linker" || + file_path == "/system/bin/linker64"); } void DYLDRendezvous::UpdateBaseAddrIfNecessary(SOEntry &entry, @@ -517,7 +513,7 @@ bool DYLDRendezvous::ReadSOEntryFromMemory(lldb::addr_t addr, SOEntry &entry) { return false; std::string file_path = ReadStringFromMemory(entry.path_addr); - entry.file_spec.SetFile(file_path, false, FileSpec::Style::native); + entry.file_spec.SetFile(file_path, FileSpec::Style::native); UpdateBaseAddrIfNecessary(entry, file_path); diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h index a7071801f569..f1a62c3bf9d8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h @@ -10,12 +10,9 @@ #ifndef liblldb_Rendezvous_H_ #define liblldb_Rendezvous_H_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-defines.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 26825d879f04..6774b4fd1291 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -10,10 +10,8 @@ // Main header include #include "DynamicLoaderPOSIXDYLD.h" -// Project includes #include "AuxVector.h" -// Other libraries and framework includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" @@ -29,8 +27,6 @@ #include "lldb/Target/ThreadPlanRunToAddress.h" #include "lldb/Utility/Log.h" -// C++ Includes -// C Includes using namespace lldb; using namespace lldb_private; @@ -121,7 +117,7 @@ void DynamicLoaderPOSIXDYLD::DidAttach() { EvalSpecialModulesStatus(); // if we dont have a load address we cant re-base - bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true; + bool rebase_exec = load_offset != LLDB_INVALID_ADDRESS; // if we have a valid executable if (executable_sp.get()) { @@ -500,7 +496,7 @@ DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, AddressVector::iterator start = addrs.begin(); AddressVector::iterator end = addrs.end(); - std::sort(start, end); + llvm::sort(start, end); addrs.erase(std::unique(start, end), end); thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop)); } @@ -512,7 +508,7 @@ void DynamicLoaderPOSIXDYLD::LoadVDSO() { if (m_vdso_base == LLDB_INVALID_ADDRESS) return; - FileSpec file("[vdso]", false); + FileSpec file("[vdso]"); MemoryRegionInfo info; Status status = m_process->GetMemoryRegionInfo(m_vdso_base, info); @@ -543,7 +539,7 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { return nullptr; } - FileSpec file(info.GetName().GetCString(), false); + FileSpec file(info.GetName().GetCString()); ModuleSpec module_spec(file, target.GetArchitecture()); if (ModuleSP module_sp = target.GetSharedModule(module_spec)) { @@ -756,7 +752,7 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( return; } - target.SetExecutableModule(module_sp, false); + target.SetExecutableModule(module_sp, eLoadDependentsNo); } bool DynamicLoaderPOSIXDYLD::AlwaysRelyOnEHUnwindInfo( diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h index 0456baf4a658..c5f2d3bcffbc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h @@ -10,13 +10,9 @@ #ifndef liblldb_DynamicLoaderPOSIXDYLD_h_ #define liblldb_DynamicLoaderPOSIXDYLD_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "DYLDRendezvous.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/ModuleList.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h index 2d18ec86afd3..7f8f82c76f72 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.h @@ -10,10 +10,6 @@ #ifndef liblldb_DynamicLoaderStatic_h_ #define liblldb_DynamicLoaderStatic_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp index 6502d7a7a58c..9405b1a5cfdc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.cpp @@ -10,12 +10,14 @@ #include "DynamicLoaderWindowsDYLD.h" +#include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadPlanStepInstruction.h" +#include "lldb/Utility/Log.h" #include "llvm/ADT/Triple.h" @@ -60,7 +62,39 @@ DynamicLoader *DynamicLoaderWindowsDYLD::CreateInstance(Process *process, return nullptr; } -void DynamicLoaderWindowsDYLD::DidAttach() {} +void DynamicLoaderWindowsDYLD::DidAttach() { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); + if (log) + log->Printf("DynamicLoaderWindowsDYLD::%s()", __FUNCTION__); + + ModuleSP executable = GetTargetExecutable(); + + if (!executable.get()) + return; + + // Try to fetch the load address of the file from the process, since there + // could be randomization of the load address. + + // It might happen that the remote has a different dir for the file, so we + // only send the basename of the executable in the query. I think this is safe + // because I doubt that two executables with the same basenames are loaded in + // memory... + FileSpec file_spec( + executable->GetPlatformFileSpec().GetFilename().GetCString()); + bool is_loaded; + addr_t base_addr = 0; + lldb::addr_t load_addr; + Status error = m_process->GetFileLoadAddress(file_spec, is_loaded, load_addr); + if (error.Success() && is_loaded) { + base_addr = load_addr; + UpdateLoadedSections(executable, LLDB_INVALID_ADDRESS, base_addr, false); + } + + ModuleList module_list; + module_list.Append(executable); + m_process->GetTarget().ModulesDidLoad(module_list); + m_process->LoadModules(); +} void DynamicLoaderWindowsDYLD::DidLaunch() {} diff --git a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h index de6e295f7891..342b32b10927 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h +++ b/contrib/llvm/tools/lldb/source/Plugins/DynamicLoader/Windows-DYLD/DynamicLoaderWindowsDYLD.h @@ -10,10 +10,6 @@ #ifndef liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_ #define liblldb_Plugins_Process_Windows_DynamicLoaderWindowsDYLD_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/DynamicLoader.h" #include "lldb/lldb-forward.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp index fa49a51f32a6..c2bc18a04e95 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -87,7 +87,8 @@ void ASTResultSynthesizer::TransformTopLevelDecl(Decl *D) { SynthesizeObjCMethodResult(method_decl); } } else if (FunctionDecl *function_decl = dyn_cast(D)) { - if (m_ast_context && + // When completing user input the body of the function may be a nullptr. + if (m_ast_context && function_decl->hasBody() && !function_decl->getNameInfo().getAsString().compare("$__lldb_expr")) { RecordPersistentTypes(function_decl); SynthesizeFunctionResult(function_decl); diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index d98a2b25fbb7..84771e59531d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -332,11 +332,9 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { TypeList types; - SymbolContext null_sc; ConstString name(tag_decl->getName().str().c_str()); - i->first->FindTypesInNamespace(null_sc, name, &i->second, UINT32_MAX, - types); + i->first->FindTypesInNamespace(name, &i->second, UINT32_MAX, types); for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) { lldb::TypeSP type = types.GetTypeAtIndex(ti); @@ -366,7 +364,6 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { } else { TypeList types; - SymbolContext null_sc; ConstString name(tag_decl->getName().str().c_str()); CompilerDeclContext namespace_decl; @@ -374,7 +371,7 @@ void ClangASTSource::CompleteType(TagDecl *tag_decl) { bool exact_match = false; llvm::DenseSet searched_symbol_files; - module_list.FindTypes(null_sc, name, exact_match, UINT32_MAX, + module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX, searched_symbol_files, types); for (uint32_t ti = 0, te = types.GetSize(); ti != te && !found; ++ti) { @@ -771,18 +768,16 @@ bool ClangASTSource::IgnoreName(const ConstString name, static const ConstString id_name("id"); static const ConstString Class_name("Class"); - if (name == id_name || name == Class_name) - return true; + if (m_ast_context->getLangOpts().ObjC) + if (name == id_name || name == Class_name) + return true; StringRef name_string_ref = name.GetStringRef(); // The ClangASTSource is not responsible for finding $-names. - if (name_string_ref.empty() || - (ignore_all_dollar_names && name_string_ref.startswith("$")) || - name_string_ref.startswith("_$")) - return true; - - return false; + return name_string_ref.empty() || + (ignore_all_dollar_names && name_string_ref.startswith("$")) || + name_string_ref.startswith("_$"); } void ClangASTSource::FindExternalVisibleDecls( @@ -804,10 +799,8 @@ void ClangASTSource::FindExternalVisibleDecls( SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(); if (symbol_vendor) { - SymbolContext null_sc; - found_namespace_decl = - symbol_vendor->FindNamespace(null_sc, name, &namespace_decl); + symbol_vendor->FindNamespace(name, &namespace_decl); if (found_namespace_decl) { context.m_namespace_map->push_back( @@ -837,10 +830,8 @@ void ClangASTSource::FindExternalVisibleDecls( if (!symbol_vendor) continue; - SymbolContext null_sc; - found_namespace_decl = - symbol_vendor->FindNamespace(null_sc, name, &namespace_decl); + symbol_vendor->FindNamespace(name, &namespace_decl); if (found_namespace_decl) { context.m_namespace_map->push_back( @@ -860,15 +851,12 @@ void ClangASTSource::FindExternalVisibleDecls( break; TypeList types; - SymbolContext null_sc; const bool exact_match = true; llvm::DenseSet searched_symbol_files; if (module_sp && namespace_decl) - module_sp->FindTypesInNamespace(null_sc, name, &namespace_decl, 1, types); + module_sp->FindTypesInNamespace(name, &namespace_decl, 1, types); else { - SymbolContext sc; - sc.module_sp = module_sp; - m_target->GetImages().FindTypes(sc, name, exact_match, 1, + m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1, searched_symbol_files, types); } @@ -1655,10 +1643,10 @@ static bool ImportOffsetMap(llvm::DenseMap &destination_map, std::vector sorted_items; sorted_items.reserve(source_map.size()); sorted_items.assign(source_map.begin(), source_map.end()); - std::sort(sorted_items.begin(), sorted_items.end(), - [](const PairType &lhs, const PairType &rhs) { - return lhs.second < rhs.second; - }); + llvm::sort(sorted_items.begin(), sorted_items.end(), + [](const PairType &lhs, const PairType &rhs) { + return lhs.second < rhs.second; + }); for (const auto &item : sorted_items) { DeclFromUser user_decl(const_cast(item.first)); @@ -1883,10 +1871,8 @@ void ClangASTSource::CompleteNamespaceMap( if (!symbol_vendor) continue; - SymbolContext null_sc; - - found_namespace_decl = symbol_vendor->FindNamespace( - null_sc, name, &module_parent_namespace_decl); + found_namespace_decl = + symbol_vendor->FindNamespace(name, &module_parent_namespace_decl); if (!found_namespace_decl) continue; @@ -1918,10 +1904,8 @@ void ClangASTSource::CompleteNamespaceMap( if (!symbol_vendor) continue; - SymbolContext null_sc; - found_namespace_decl = - symbol_vendor->FindNamespace(null_sc, name, &null_namespace_decl); + symbol_vendor->FindNamespace(name, &null_namespace_decl); if (!found_namespace_decl) continue; diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp index 0811a7999920..9c2f8c4b6c92 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp @@ -17,7 +17,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/Materializer.h" @@ -44,6 +43,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "lldb/lldb-private.h" #include "clang/AST/ASTConsumer.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h index b67387930190..93fa57876bce 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.h @@ -10,18 +10,14 @@ #ifndef liblldb_ClangExpressionDeclMap_h_ #define liblldb_ClangExpressionDeclMap_h_ -// C Includes #include #include -// C++ Includes #include #include "ClangASTSource.h" #include "ClangExpressionVariable.h" -// Other libraries and framework includes -// Project includes #include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" #include "lldb/Expression/Materializer.h" @@ -325,12 +321,6 @@ public: /// @param[in] namespace_decl /// If valid and module is non-NULL, the parent namespace. /// - /// @param[in] name - /// The name as a plain C string. The NameSearchContext contains - /// a DeclarationName for the name so at first the name may seem - /// redundant, but ClangExpressionDeclMap operates in RTTI land so - /// it can't access DeclarationName. - /// /// @param[in] current_id /// The ID for the current FindExternalVisibleDecls invocation, /// for logging purposes. diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h index e0d3ace15bd1..b5b640c9185f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionHelper.h @@ -10,14 +10,10 @@ #ifndef liblldb_ClangExpression_h_ #define liblldb_ClangExpression_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/ClangForward.h" #include "lldb/Expression/ExpressionTypeSystemHelper.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index c5406fcc3340..6650c0db967f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -7,12 +7,11 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes +#include #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/PrettyPrinter.h" #include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceLocation.h" @@ -34,6 +33,8 @@ #include "clang/Parse/ParseAST.h" #include "clang/Rewrite/Core/Rewriter.h" #include "clang/Rewrite/Frontend/FrontendActions.h" +#include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Sema/Sema.h" #include "clang/Sema/SemaConsumer.h" #include "llvm/ADT/StringRef.h" @@ -55,7 +56,6 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Signals.h" -// Project includes #include "ClangDiagnostic.h" #include "ClangExpressionParser.h" @@ -222,7 +222,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, Expression &expr, bool generate_debug_info) : ExpressionParser(exe_scope, expr, generate_debug_info), m_compiler(), - m_code_generator(), m_pp_callbacks(nullptr) { + m_pp_callbacks(nullptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // We can't compile expressions without a target. So if the exe_scope is @@ -377,8 +377,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, m_compiler->getLangOpts().CPlusPlus = true; break; case lldb::eLanguageTypeObjC: - m_compiler->getLangOpts().ObjC1 = true; - m_compiler->getLangOpts().ObjC2 = true; + m_compiler->getLangOpts().ObjC = true; // FIXME: the following language option is a temporary workaround, // to "ask for ObjC, get ObjC++" (see comment above). m_compiler->getLangOpts().CPlusPlus = true; @@ -399,16 +398,14 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, LLVM_FALLTHROUGH; case lldb::eLanguageTypeC_plus_plus_03: m_compiler->getLangOpts().CPlusPlus = true; - // FIXME: the following language option is a temporary workaround, - // to "ask for C++, get ObjC++". Apple hopes to remove this requirement on - // non-Apple platforms, but for now it is needed. - m_compiler->getLangOpts().ObjC1 = true; + if (process_sp) + m_compiler->getLangOpts().ObjC = + process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC) != nullptr; break; case lldb::eLanguageTypeObjC_plus_plus: case lldb::eLanguageTypeUnknown: default: - m_compiler->getLangOpts().ObjC1 = true; - m_compiler->getLangOpts().ObjC2 = true; + m_compiler->getLangOpts().ObjC = true; m_compiler->getLangOpts().CPlusPlus = true; m_compiler->getLangOpts().CPlusPlus11 = true; m_compiler->getHeaderSearchOpts().UseLibcxx = true; @@ -432,7 +429,7 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, // long time parsing and importing debug information. m_compiler->getLangOpts().SpellChecking = false; - if (process_sp && m_compiler->getLangOpts().ObjC1) { + if (process_sp && m_compiler->getLangOpts().ObjC) { if (process_sp->GetObjCLanguageRuntime()) { if (process_sp->GetObjCLanguageRuntime()->GetRuntimeVersion() == ObjCLanguageRuntime::ObjCRuntimeVersions::eAppleObjC_V2) @@ -452,6 +449,10 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, false; // Debuggers get universal access m_compiler->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name + // We enable all builtin functions beside the builtins from libc/libm (e.g. + // 'fopen'). Those libc functions are already correctly handled by LLDB, and + // additionally enabling them as expandable builtins is breaking Clang. + m_compiler->getLangOpts().NoBuiltin = true; // Set CodeGen options m_compiler->getCodeGenOpts().EmitDeclMetadata = true; @@ -507,15 +508,14 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, // 8. Most of this we get from the CompilerInstance, but we also want to give // the context an ExternalASTSource. - m_selector_table.reset(new SelectorTable()); - m_builtin_context.reset(new Builtin::Context()); - std::unique_ptr ast_context( - new ASTContext(m_compiler->getLangOpts(), m_compiler->getSourceManager(), - m_compiler->getPreprocessor().getIdentifierTable(), - *m_selector_table.get(), *m_builtin_context.get())); + auto &PP = m_compiler->getPreprocessor(); + auto &builtin_context = PP.getBuiltinInfo(); + builtin_context.initializeBuiltins(PP.getIdentifierTable(), + m_compiler->getLangOpts()); - ast_context->InitBuiltinTypes(m_compiler->getTarget()); + m_compiler->createASTContext(); + clang::ASTContext &ast_context = m_compiler->getASTContext(); ClangExpressionHelper *type_system_helper = dyn_cast(m_expr.GetTypeSystemHelper()); @@ -524,14 +524,13 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, if (decl_map) { llvm::IntrusiveRefCntPtr ast_source( decl_map->CreateProxy()); - decl_map->InstallASTContext(*ast_context, m_compiler->getFileManager()); - ast_context->setExternalSource(ast_source); + decl_map->InstallASTContext(ast_context, m_compiler->getFileManager()); + ast_context.setExternalSource(ast_source); } m_ast_context.reset( new ClangASTContext(m_compiler->getTargetOpts().Triple.c_str())); - m_ast_context->setASTContext(ast_context.get()); - m_compiler->setASTContext(ast_context.release()); + m_ast_context->setASTContext(&ast_context); std::string module_name("$__lldb_module"); @@ -544,7 +543,270 @@ ClangExpressionParser::ClangExpressionParser(ExecutionContextScope *exe_scope, ClangExpressionParser::~ClangExpressionParser() {} +namespace { + +//---------------------------------------------------------------------- +/// @class CodeComplete +/// +/// A code completion consumer for the clang Sema that is responsible for +/// creating the completion suggestions when a user requests completion +/// of an incomplete `expr` invocation. +//---------------------------------------------------------------------- +class CodeComplete : public CodeCompleteConsumer { + CodeCompletionTUInfo m_info; + + std::string m_expr; + unsigned m_position = 0; + CompletionRequest &m_request; + /// The printing policy we use when printing declarations for our completion + /// descriptions. + clang::PrintingPolicy m_desc_policy; + + /// Returns true if the given character can be used in an identifier. + /// This also returns true for numbers because for completion we usually + /// just iterate backwards over iterators. + /// + /// Note: lldb uses '$' in its internal identifiers, so we also allow this. + static bool IsIdChar(char c) { + return c == '_' || std::isalnum(c) || c == '$'; + } + + /// Returns true if the given character is used to separate arguments + /// in the command line of lldb. + static bool IsTokenSeparator(char c) { return c == ' ' || c == '\t'; } + + /// Drops all tokens in front of the expression that are unrelated for + /// the completion of the cmd line. 'unrelated' means here that the token + /// is not interested for the lldb completion API result. + StringRef dropUnrelatedFrontTokens(StringRef cmd) { + if (cmd.empty()) + return cmd; + + // If we are at the start of a word, then all tokens are unrelated to + // the current completion logic. + if (IsTokenSeparator(cmd.back())) + return StringRef(); + + // Remove all previous tokens from the string as they are unrelated + // to completing the current token. + StringRef to_remove = cmd; + while (!to_remove.empty() && !IsTokenSeparator(to_remove.back())) { + to_remove = to_remove.drop_back(); + } + cmd = cmd.drop_front(to_remove.size()); + + return cmd; + } + + /// Removes the last identifier token from the given cmd line. + StringRef removeLastToken(StringRef cmd) { + while (!cmd.empty() && IsIdChar(cmd.back())) { + cmd = cmd.drop_back(); + } + return cmd; + } + + /// Attemps to merge the given completion from the given position into the + /// existing command. Returns the completion string that can be returned to + /// the lldb completion API. + std::string mergeCompletion(StringRef existing, unsigned pos, + StringRef completion) { + StringRef existing_command = existing.substr(0, pos); + // We rewrite the last token with the completion, so let's drop that + // token from the command. + existing_command = removeLastToken(existing_command); + // We also should remove all previous tokens from the command as they + // would otherwise be added to the completion that already has the + // completion. + existing_command = dropUnrelatedFrontTokens(existing_command); + return existing_command.str() + completion.str(); + } + +public: + /// Constructs a CodeComplete consumer that can be attached to a Sema. + /// @param[out] matches + /// The list of matches that the lldb completion API expects as a result. + /// This may already contain matches, so it's only allowed to append + /// to this variable. + /// @param[out] expr + /// The whole expression string that we are currently parsing. This + /// string needs to be equal to the input the user typed, and NOT the + /// final code that Clang is parsing. + /// @param[out] position + /// The character position of the user cursor in the `expr` parameter. + /// + CodeComplete(CompletionRequest &request, clang::LangOptions ops, + std::string expr, unsigned position) + : CodeCompleteConsumer(CodeCompleteOptions(), false), + m_info(std::make_shared()), m_expr(expr), + m_position(position), m_request(request), m_desc_policy(ops) { + + // Ensure that the printing policy is producing a description that is as + // short as possible. + m_desc_policy.SuppressScope = true; + m_desc_policy.SuppressTagKeyword = true; + m_desc_policy.FullyQualifiedName = false; + m_desc_policy.TerseOutput = true; + m_desc_policy.IncludeNewlines = false; + m_desc_policy.UseVoidForZeroParams = false; + m_desc_policy.Bool = true; + } + + /// Deregisters and destroys this code-completion consumer. + virtual ~CodeComplete() {} + + /// \name Code-completion filtering + /// Check if the result should be filtered out. + bool isResultFilteredOut(StringRef Filter, + CodeCompletionResult Result) override { + // This code is mostly copied from CodeCompleteConsumer. + switch (Result.Kind) { + case CodeCompletionResult::RK_Declaration: + return !( + Result.Declaration->getIdentifier() && + Result.Declaration->getIdentifier()->getName().startswith(Filter)); + case CodeCompletionResult::RK_Keyword: + return !StringRef(Result.Keyword).startswith(Filter); + case CodeCompletionResult::RK_Macro: + return !Result.Macro->getName().startswith(Filter); + case CodeCompletionResult::RK_Pattern: + return !StringRef(Result.Pattern->getAsString()).startswith(Filter); + } + // If we trigger this assert or the above switch yields a warning, then + // CodeCompletionResult has been enhanced with more kinds of completion + // results. Expand the switch above in this case. + assert(false && "Unknown completion result type?"); + // If we reach this, then we should just ignore whatever kind of unknown + // result we got back. We probably can't turn it into any kind of useful + // completion suggestion with the existing code. + return true; + } + + /// \name Code-completion callbacks + /// Process the finalized code-completion results. + void ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context, + CodeCompletionResult *Results, + unsigned NumResults) override { + + // The Sema put the incomplete token we try to complete in here during + // lexing, so we need to retrieve it here to know what we are completing. + StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter(); + + // Iterate over all the results. Filter out results we don't want and + // process the rest. + for (unsigned I = 0; I != NumResults; ++I) { + // Filter the results with the information from the Sema. + if (!Filter.empty() && isResultFilteredOut(Filter, Results[I])) + continue; + + CodeCompletionResult &R = Results[I]; + std::string ToInsert; + std::string Description; + // Handle the different completion kinds that come from the Sema. + switch (R.Kind) { + case CodeCompletionResult::RK_Declaration: { + const NamedDecl *D = R.Declaration; + ToInsert = R.Declaration->getNameAsString(); + // If we have a function decl that has no arguments we want to + // complete the empty parantheses for the user. If the function has + // arguments, we at least complete the opening bracket. + if (const FunctionDecl *F = dyn_cast(D)) { + if (F->getNumParams() == 0) + ToInsert += "()"; + else + ToInsert += "("; + raw_string_ostream OS(Description); + F->print(OS, m_desc_policy, false); + OS.flush(); + } else if (const VarDecl *V = dyn_cast(D)) { + Description = V->getType().getAsString(m_desc_policy); + } else if (const FieldDecl *F = dyn_cast(D)) { + Description = F->getType().getAsString(m_desc_policy); + } else if (const NamespaceDecl *N = dyn_cast(D)) { + // If we try to complete a namespace, then we can directly append + // the '::'. + if (!N->isAnonymousNamespace()) + ToInsert += "::"; + } + break; + } + case CodeCompletionResult::RK_Keyword: + ToInsert = R.Keyword; + break; + case CodeCompletionResult::RK_Macro: + ToInsert = R.Macro->getName().str(); + break; + case CodeCompletionResult::RK_Pattern: + ToInsert = R.Pattern->getTypedText(); + break; + } + // At this point all information is in the ToInsert string. + + // We also filter some internal lldb identifiers here. The user + // shouldn't see these. + if (StringRef(ToInsert).startswith("$__lldb_")) + continue; + if (!ToInsert.empty()) { + // Merge the suggested Token into the existing command line to comply + // with the kind of result the lldb API expects. + std::string CompletionSuggestion = + mergeCompletion(m_expr, m_position, ToInsert); + m_request.AddCompletion(CompletionSuggestion, Description); + } + } + } + + /// \param S the semantic-analyzer object for which code-completion is being + /// done. + /// + /// \param CurrentArg the index of the current argument. + /// + /// \param Candidates an array of overload candidates. + /// + /// \param NumCandidates the number of overload candidates + void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg, + OverloadCandidate *Candidates, + unsigned NumCandidates, + SourceLocation OpenParLoc) override { + // At the moment we don't filter out any overloaded candidates. + } + + CodeCompletionAllocator &getAllocator() override { + return m_info.getAllocator(); + } + + CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return m_info; } +}; +} // namespace + +bool ClangExpressionParser::Complete(CompletionRequest &request, unsigned line, + unsigned pos, unsigned typed_pos) { + DiagnosticManager mgr; + // We need the raw user expression here because that's what the CodeComplete + // class uses to provide completion suggestions. + // However, the `Text` method only gives us the transformed expression here. + // To actually get the raw user input here, we have to cast our expression to + // the LLVMUserExpression which exposes the right API. This should never fail + // as we always have a ClangUserExpression whenever we call this. + LLVMUserExpression &llvm_expr = *static_cast(&m_expr); + CodeComplete CC(request, m_compiler->getLangOpts(), llvm_expr.GetUserText(), + typed_pos); + // We don't need a code generator for parsing. + m_code_generator.reset(); + // Start parsing the expression with our custom code completion consumer. + ParseInternal(mgr, &CC, line, pos); + return true; +} + unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) { + return ParseInternal(diagnostic_manager); +} + +unsigned +ClangExpressionParser::ParseInternal(DiagnosticManager &diagnostic_manager, + CodeCompleteConsumer *completion_consumer, + unsigned completion_line, + unsigned completion_column) { ClangDiagnosticManagerAdapter *adapter = static_cast( m_compiler->getDiagnostics().getClient()); @@ -557,10 +819,20 @@ unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) { clang::SourceManager &source_mgr = m_compiler->getSourceManager(); bool created_main_file = false; - if (m_compiler->getCodeGenOpts().getDebugInfo() == - codegenoptions::FullDebugInfo) { + + // Clang wants to do completion on a real file known by Clang's file manager, + // so we have to create one to make this work. + // TODO: We probably could also simulate to Clang's file manager that there + // is a real file that contains our code. + bool should_create_file = completion_consumer != nullptr; + + // We also want a real file on disk if we generate full debug info. + should_create_file |= m_compiler->getCodeGenOpts().getDebugInfo() == + codegenoptions::FullDebugInfo; + + if (should_create_file) { int temp_fd = -1; - llvm::SmallString result_path; + llvm::SmallString<128> result_path; if (FileSpec tmpdir_file_spec = HostInfo::GetProcessTempDir()) { tmpdir_file_spec.AppendPathComponent("lldb-%%%%%%.expr"); std::string temp_source_path = tmpdir_file_spec.GetPath(); @@ -603,14 +875,30 @@ unsigned ClangExpressionParser::Parse(DiagnosticManager &diagnostic_manager) { if (ClangExpressionDeclMap *decl_map = type_system_helper->DeclMap()) decl_map->InstallCodeGenerator(m_code_generator.get()); + // If we want to parse for code completion, we need to attach our code + // completion consumer to the Sema and specify a completion position. + // While parsing the Sema will call this consumer with the provided + // completion suggestions. + if (completion_consumer) { + auto main_file = source_mgr.getFileEntryForID(source_mgr.getMainFileID()); + auto &PP = m_compiler->getPreprocessor(); + // Lines and columns start at 1 in Clang, but code completion positions are + // indexed from 0, so we need to add 1 to the line and column here. + ++completion_line; + ++completion_column; + PP.SetCodeCompletionPoint(main_file, completion_line, completion_column); + } + if (ast_transformer) { ast_transformer->Initialize(m_compiler->getASTContext()); ParseAST(m_compiler->getPreprocessor(), ast_transformer, - m_compiler->getASTContext()); + m_compiler->getASTContext(), false, TU_Complete, + completion_consumer); } else { m_code_generator->Initialize(m_compiler->getASTContext()); ParseAST(m_compiler->getPreprocessor(), m_code_generator.get(), - m_compiler->getASTContext()); + m_compiler->getASTContext(), false, TU_Complete, + completion_consumer); } diag_buf->EndSourceFile(); @@ -891,9 +1179,9 @@ lldb_private::Status ClangExpressionParser::PrepareForExecution( if (!dynamic_checkers->Install(install_diagnostics, exe_ctx)) { if (install_diagnostics.Diagnostics().size()) - err.SetErrorString("couldn't install checkers, unknown error"); - else err.SetErrorString(install_diagnostics.GetString().c_str()); + else + err.SetErrorString("couldn't install checkers, unknown error"); return err; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h index 4058ec1270b3..03ff55f614d5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h @@ -20,6 +20,10 @@ #include #include +namespace clang { +class CodeCompleteConsumer; +} + namespace lldb_private { class IRExecutionUnit; @@ -58,6 +62,9 @@ public: //------------------------------------------------------------------ ~ClangExpressionParser() override; + bool Complete(CompletionRequest &request, unsigned line, unsigned pos, + unsigned typed_pos) override; + //------------------------------------------------------------------ /// Parse a single expression and convert it to IR using Clang. Don't wrap /// the expression in anything at all. @@ -143,16 +150,39 @@ public: std::string GetClangTargetABI(const ArchSpec &target_arch); private: + //------------------------------------------------------------------ + /// Parses the expression. + /// + /// @param[in] diagnostic_manager + /// The diagnostic manager that should receive the diagnostics + /// from the parsing process. + /// + /// @param[in] completion + /// The completion consumer that should be used during parsing + /// (or a nullptr if no consumer should be attached). + /// + /// @param[in] completion_line + /// The line in which the completion marker should be placed. + /// The first line is represented by the value 0. + /// + /// @param[in] completion_column + /// The column in which the completion marker should be placed. + /// The first column is represented by the value 0. + /// + /// @return + /// The number of parsing errors. + //------------------------------------------------------------------- + unsigned ParseInternal(DiagnosticManager &diagnostic_manager, + clang::CodeCompleteConsumer *completion = nullptr, + unsigned completion_line = 0, + unsigned completion_column = 0); + std::unique_ptr m_llvm_context; ///< The LLVM context to generate IR into std::unique_ptr m_file_manager; ///< The Clang file manager object used by the compiler std::unique_ptr m_compiler; ///< The Clang compiler used to parse expressions into IR - std::unique_ptr - m_builtin_context; ///< Context for Clang built-ins - std::unique_ptr - m_selector_table; ///< Selector table for Objective-C methods std::unique_ptr m_code_generator; ///< The Clang object that generates IR diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h index 7d5ced5b4705..6886f0940adb 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionVariable.h @@ -10,20 +10,16 @@ #ifndef liblldb_ClangExpressionVariable_h_ #define liblldb_ClangExpressionVariable_h_ -// C Includes #include #include #include -// C++ Includes #include #include #include -// Other libraries and framework includes #include "llvm/Support/Casting.h" -// Project includes #include "lldb/Core/ClangForward.h" #include "lldb/Core/Value.h" #include "lldb/Expression/ExpressionVariable.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp index e3e0ed49181e..8ec9ff2235f5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.cpp @@ -12,9 +12,6 @@ #include "ASTStructExtractor.h" #include "ClangExpressionParser.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "clang/AST/ASTContext.h" #include "clang/AST/RecordLayout.h" #include "clang/CodeGen/CodeGenAction.h" @@ -25,9 +22,7 @@ #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/IR/Module.h" -// Project includes #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectList.h" #include "lldb/Expression/IRExecutionUnit.h" @@ -44,6 +39,7 @@ #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h index 438cf0c713da..9d933bfa6095 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangFunctionCaller.h @@ -10,10 +10,6 @@ #ifndef liblldb_ClangFunctionCaller_h_ #define liblldb_ClangFunctionCaller_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "ClangExpressionHelper.h" #include "lldb/Core/Address.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp index 4251d2ee75b9..44a13353818a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangHost.cpp @@ -17,7 +17,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/Threading.h" -// Project includes +#include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #if !defined(_WIN32) #include "lldb/Host/posix/HostInfoPosix.h" @@ -42,7 +42,7 @@ static bool DefaultComputeClangDirectory(FileSpec &file_spec) { #if defined(__APPLE__) static bool VerifyClangPath(const llvm::Twine &clang_path) { - if (llvm::sys::fs::is_directory(clang_path)) + if (FileSystem::Instance().IsDirectory(clang_path)) return true; Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST); if (log) @@ -84,7 +84,8 @@ bool lldb_private::ComputeClangDirectory(FileSpec &lldb_shlib_spec, "Developer/Toolchains/XcodeDefault.xctoolchain", swift_clang_resource_dir); if (!verify || VerifyClangPath(clang_path)) { - file_spec.SetFile(clang_path.c_str(), true, FileSpec::Style::native); + file_spec.SetFile(clang_path.c_str(), FileSpec::Style::native); + FileSystem::Instance().Resolve(file_spec); return true; } } else if (parent != r_end && *parent == "PrivateFrameworks" && @@ -98,7 +99,8 @@ bool lldb_private::ComputeClangDirectory(FileSpec &lldb_shlib_spec, raw_path.resize(parent - r_end); llvm::sys::path::append(clang_path, raw_path, swift_clang_resource_dir); if (!verify || VerifyClangPath(clang_path)) { - file_spec.SetFile(clang_path.c_str(), true, FileSpec::Style::native); + file_spec.SetFile(clang_path.c_str(), FileSpec::Style::native); + FileSystem::Instance().Resolve(file_spec); return true; } raw_path = lldb_shlib_spec.GetPath(); @@ -110,7 +112,8 @@ bool lldb_private::ComputeClangDirectory(FileSpec &lldb_shlib_spec, // Fall back to the Clang resource directory inside the framework. raw_path.append("LLDB.framework/Resources/Clang"); - file_spec.SetFile(raw_path.c_str(), true, FileSpec::Style::native); + file_spec.SetFile(raw_path.c_str(), FileSpec::Style::native); + FileSystem::Instance().Resolve(file_spec); return true; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp index 665195f01774..ced21dfe0dda 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp @@ -7,11 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "clang/Basic/TargetInfo.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendActions.h" @@ -24,7 +21,6 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Threading.h" -// Project includes #include "ClangHost.h" #include "ClangModulesDeclVendor.h" @@ -601,7 +597,7 @@ ClangModulesDeclVendor::Create(Target &target) { { FileSpec clang_resource_dir = GetClangResourceDir(); - if (llvm::sys::fs::is_directory(clang_resource_dir.GetPath())) { + if (FileSystem::Instance().IsDirectory(clang_resource_dir.GetPath())) { compiler_invocation_arguments.push_back("-resource-dir"); compiler_invocation_arguments.push_back(clang_resource_dir.GetPath()); } @@ -612,7 +608,8 @@ ClangModulesDeclVendor::Create(Target &target) { new StoringDiagnosticConsumer); std::vector compiler_invocation_argument_cstrs; - + compiler_invocation_argument_cstrs.reserve( + compiler_invocation_arguments.size()); for (const std::string &arg : compiler_invocation_arguments) { compiler_invocation_argument_cstrs.push_back(arg.c_str()); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h index 59126974616d..c4438c7e2203 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h @@ -10,12 +10,8 @@ #ifndef liblldb_ClangPersistentVariables_h_ #define liblldb_ClangPersistentVariables_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/DenseMap.h" -// Project includes #include "ClangExpressionVariable.h" #include "ClangModulesDeclVendor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp index 2e61f704127a..f42955df07aa 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.cpp @@ -376,9 +376,9 @@ static void SetupDeclVendor(ExecutionContext &exe_ctx, Target *target) { } } -llvm::Optional ClangUserExpression::GetLanguageForExpr( +void ClangUserExpression::UpdateLanguageForExpr( DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) { - lldb::LanguageType lang_type = lldb::LanguageType::eLanguageTypeUnknown; + m_expr_lang = lldb::LanguageType::eLanguageTypeUnknown; std::string prefix = m_expr_prefix; @@ -390,20 +390,29 @@ llvm::Optional ClangUserExpression::GetLanguageForExpr( m_expr_text.c_str())); if (m_in_cplusplus_method) - lang_type = lldb::eLanguageTypeC_plus_plus; + m_expr_lang = lldb::eLanguageTypeC_plus_plus; else if (m_in_objectivec_method) - lang_type = lldb::eLanguageTypeObjC; + m_expr_lang = lldb::eLanguageTypeObjC; else - lang_type = lldb::eLanguageTypeC; + m_expr_lang = lldb::eLanguageTypeC; - if (!source_code->GetText(m_transformed_text, lang_type, m_in_static_method, - exe_ctx)) { + if (!source_code->GetText(m_transformed_text, m_expr_lang, + m_in_static_method, exe_ctx)) { diagnostic_manager.PutString(eDiagnosticSeverityError, "couldn't construct expression body"); - return llvm::Optional(); + return; + } + + // Find and store the start position of the original code inside the + // transformed code. We need this later for the code completion. + std::size_t original_start; + std::size_t original_end; + bool found_bounds = source_code->GetOriginalBodyBounds( + m_transformed_text, m_expr_lang, original_start, original_end); + if (found_bounds) { + m_user_expression_start_pos = original_start; } } - return lang_type; } bool ClangUserExpression::PrepareForParsing( @@ -427,6 +436,8 @@ bool ClangUserExpression::PrepareForParsing( ApplyObjcCastHack(m_expr_text); SetupDeclVendor(exe_ctx, m_target); + + UpdateLanguageForExpr(diagnostic_manager, exe_ctx); return true; } @@ -440,11 +451,6 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, if (!PrepareForParsing(diagnostic_manager, exe_ctx)) return false; - lldb::LanguageType lang_type = lldb::LanguageType::eLanguageTypeUnknown; - if (auto new_lang = GetLanguageForExpr(diagnostic_manager, exe_ctx)) { - lang_type = new_lang.getValue(); - } - if (log) log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); @@ -504,7 +510,7 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, const std::string &fixed_expression = diagnostic_manager.GetFixedExpression(); if (ExpressionSourceCode::GetOriginalBodyBounds( - fixed_expression, lang_type, fixed_start, fixed_end)) + fixed_expression, m_expr_lang, fixed_start, fixed_end)) m_fixed_text = fixed_expression.substr(fixed_start, fixed_end - fixed_start); } @@ -591,6 +597,116 @@ bool ClangUserExpression::Parse(DiagnosticManager &diagnostic_manager, return true; } +//------------------------------------------------------------------ +/// Converts an absolute position inside a given code string into +/// a column/line pair. +/// +/// @param[in] abs_pos +/// A absolute position in the code string that we want to convert +/// to a column/line pair. +/// +/// @param[in] code +/// A multi-line string usually representing source code. +/// +/// @param[out] line +/// The line in the code that contains the given absolute position. +/// The first line in the string is indexed as 1. +/// +/// @param[out] column +/// The column in the line that contains the absolute position. +/// The first character in a line is indexed as 0. +//------------------------------------------------------------------ +static void AbsPosToLineColumnPos(size_t abs_pos, llvm::StringRef code, + unsigned &line, unsigned &column) { + // Reset to code position to beginning of the file. + line = 0; + column = 0; + + assert(abs_pos <= code.size() && "Absolute position outside code string?"); + + // We have to walk up to the position and count lines/columns. + for (std::size_t i = 0; i < abs_pos; ++i) { + // If we hit a line break, we go back to column 0 and enter a new line. + // We only handle \n because that's what we internally use to make new + // lines for our temporary code strings. + if (code[i] == '\n') { + ++line; + column = 0; + continue; + } + ++column; + } +} + +bool ClangUserExpression::Complete(ExecutionContext &exe_ctx, + CompletionRequest &request, + unsigned complete_pos) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); + + // We don't want any visible feedback when completing an expression. Mostly + // because the results we get from an incomplete invocation are probably not + // correct. + DiagnosticManager diagnostic_manager; + + if (!PrepareForParsing(diagnostic_manager, exe_ctx)) + return false; + + if (log) + log->Printf("Parsing the following code:\n%s", m_transformed_text.c_str()); + + ////////////////////////// + // Parse the expression + // + + m_materializer_ap.reset(new Materializer()); + + ResetDeclMap(exe_ctx, m_result_delegate, /*keep result in memory*/ true); + + OnExit on_exit([this]() { ResetDeclMap(); }); + + if (!DeclMap()->WillParse(exe_ctx, m_materializer_ap.get())) { + diagnostic_manager.PutString( + eDiagnosticSeverityError, + "current process state is unsuitable for expression parsing"); + + return false; + } + + if (m_options.GetExecutionPolicy() == eExecutionPolicyTopLevel) { + DeclMap()->SetLookupsEnabled(true); + } + + Process *process = exe_ctx.GetProcessPtr(); + ExecutionContextScope *exe_scope = process; + + if (!exe_scope) + exe_scope = exe_ctx.GetTargetPtr(); + + ClangExpressionParser parser(exe_scope, *this, false); + + // We have to find the source code location where the user text is inside + // the transformed expression code. When creating the transformed text, we + // already stored the absolute position in the m_transformed_text string. The + // only thing left to do is to transform it into the line:column format that + // Clang expects. + + // The line and column of the user expression inside the transformed source + // code. + unsigned user_expr_line, user_expr_column; + if (m_user_expression_start_pos.hasValue()) + AbsPosToLineColumnPos(*m_user_expression_start_pos, m_transformed_text, + user_expr_line, user_expr_column); + else + return false; + + // The actual column where we have to complete is the start column of the + // user expression + the offset inside the user code that we were given. + const unsigned completion_column = user_expr_column + complete_pos; + parser.Complete(request, user_expr_line, completion_column, complete_pos); + + return true; +} + bool ClangUserExpression::AddArguments(ExecutionContext &exe_ctx, std::vector &args, lldb::addr_t struct_address, diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h index ac363bf91747..7e4cba661850 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUserExpression.h @@ -10,12 +10,8 @@ #ifndef liblldb_ClangUserExpression_h_ #define liblldb_ClangUserExpression_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "ASTResultSynthesizer.h" #include "ASTStructExtractor.h" #include "ClangExpressionDeclMap.h" @@ -143,6 +139,9 @@ public: lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info) override; + bool Complete(ExecutionContext &exe_ctx, CompletionRequest &request, + unsigned complete_pos) override; + ExpressionTypeSystemHelper *GetTypeSystemHelper() override { return &m_type_system_helper; } @@ -174,8 +173,8 @@ private: lldb::addr_t struct_address, DiagnosticManager &diagnostic_manager) override; - llvm::Optional GetLanguageForExpr( - DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx); + void UpdateLanguageForExpr(DiagnosticManager &diagnostic_manager, + ExecutionContext &exe_ctx); bool SetupPersistentState(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx); bool PrepareForParsing(DiagnosticManager &diagnostic_manager, @@ -198,6 +197,13 @@ private: lldb::TargetSP m_target_sp; }; + /// The language type of the current expression. + lldb::LanguageType m_expr_lang = lldb::eLanguageTypeUnknown; + + /// The absolute character position in the transformed source code where the + /// user code (as typed by the user) starts. If the variable is empty, then we + /// were not able to calculate this position. + llvm::Optional m_user_expression_start_pos; ResultDelegate m_result_delegate; }; diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp index 0f2aeef27e57..fe6ca450a79d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.cpp @@ -11,13 +11,11 @@ #include "ClangExpressionDeclMap.h" #include "ClangExpressionParser.h" -// C Includes #include #if HAVE_SYS_TYPES_H #include #endif -// C++ Includes #include "lldb/Core/Module.h" #include "lldb/Core/StreamFile.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h index a897a2b17087..b0650f0eda02 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/ClangUtilityFunction.h @@ -10,14 +10,10 @@ #ifndef liblldb_ClangUtilityFunction_h_ #define liblldb_ClangUtilityFunction_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "ClangExpressionHelper.h" #include "lldb/Core/ClangForward.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp index e51c9ee07b9f..3a7cd58b70ab 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Clang/IRForTarget.cpp @@ -25,7 +25,6 @@ #include "clang/AST/ASTContext.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/dwarf.h" #include "lldb/Expression/IRExecutionUnit.h" #include "lldb/Expression/IRInterpreter.h" @@ -36,6 +35,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include @@ -310,12 +310,14 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { lldb::TargetSP target_sp(m_execution_unit.GetTarget()); lldb_private::ExecutionContext exe_ctx(target_sp, true); - if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) { + llvm::Optional bit_size = + m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()); + if (!bit_size) { lldb_private::StreamString type_desc_stream; m_result_type.DumpTypeDescription(&type_desc_stream); if (log) - log->Printf("Result type has size 0"); + log->Printf("Result type has unknown size"); m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' " "couldn't be determined\n", @@ -334,7 +336,8 @@ bool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) { if (log) log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64, - m_result_name.GetCString(), m_result_type.GetByteSize(nullptr)); + m_result_name.GetCString(), + m_result_type.GetByteSize(nullptr).getValueOr(0)); // Construct a new result global and set up its metadata @@ -778,11 +781,8 @@ bool IRForTarget::RewriteObjCConstStrings() { static bool IsObjCSelectorRef(Value *value) { GlobalVariable *global_variable = dyn_cast(value); - if (!global_variable || !global_variable->hasName() || - !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_")) - return false; - - return true; + return !(!global_variable || !global_variable->hasName() || + !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_")); } // This function does not report errors; its callers are responsible. @@ -953,11 +953,8 @@ bool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) { static bool IsObjCClassReference(Value *value) { GlobalVariable *global_variable = dyn_cast(value); - if (!global_variable || !global_variable->hasName() || - !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_")) - return false; - - return true; + return !(!global_variable || !global_variable->hasName() || + !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_")); } // This function does not report errors; its callers are responsible. @@ -1259,12 +1256,9 @@ bool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) { llvm::NextPowerOf2(constant_size) * 8); lldb_private::Status get_data_error; - if (!scalar.GetAsMemoryData(data, constant_size, - lldb_private::endian::InlHostByteOrder(), - get_data_error)) - return false; - - return true; + return scalar.GetAsMemoryData(data, constant_size, + lldb_private::endian::InlHostByteOrder(), + get_data_error) != 0; } else if (ConstantDataArray *array_initializer = dyn_cast(initializer)) { if (array_initializer->isString()) { @@ -1376,7 +1370,9 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { value_type = global_variable->getType(); } - const uint64_t value_size = compiler_type.GetByteSize(nullptr); + llvm::Optional value_size = compiler_type.GetByteSize(nullptr); + if (!value_size) + return false; lldb::offset_t value_alignment = (compiler_type.GetTypeBitAlign() + 7ull) / 8ull; @@ -1387,13 +1383,13 @@ bool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) { lldb_private::ClangUtil::GetQualType(compiler_type) .getAsString() .c_str(), - PrintType(value_type).c_str(), value_size, value_alignment); + PrintType(value_type).c_str(), *value_size, value_alignment); } if (named_decl && !m_decl_map->AddValueToStruct( named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr, - value_size, value_alignment)) { + *value_size, value_alignment)) { if (!global_variable->hasExternalLinkage()) return true; else diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoAST.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoAST.h deleted file mode 100644 index d24e6c548718..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoAST.h +++ /dev/null @@ -1,1977 +0,0 @@ -//===-- GoAST.h -------------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// DO NOT EDIT. -// Generated by gen_go_ast.py - -#ifndef liblldb_GoAST_h -#define liblldb_GoAST_h - -#include "Plugins/ExpressionParser/Go/GoLexer.h" -#include "lldb/lldb-forward.h" -#include "lldb/lldb-private.h" -#include "llvm/Support/Casting.h" - -namespace lldb_private { - -class GoASTNode { -public: - typedef GoLexer::TokenType TokenType; - typedef GoLexer::Token Token; - enum ChanDir { - eChanBidir, - eChanSend, - eChanRecv, - }; - enum NodeKind { - eBadDecl, - eFuncDecl, - eGenDecl, - eArrayType, - eBadExpr, - eBasicLit, - eBinaryExpr, - eIdent, - eCallExpr, - eChanType, - eCompositeLit, - eEllipsis, - eFuncType, - eFuncLit, - eIndexExpr, - eInterfaceType, - eKeyValueExpr, - eMapType, - eParenExpr, - eSelectorExpr, - eSliceExpr, - eStarExpr, - eStructType, - eTypeAssertExpr, - eUnaryExpr, - eImportSpec, - eTypeSpec, - eValueSpec, - eAssignStmt, - eBadStmt, - eBlockStmt, - eBranchStmt, - eCaseClause, - eCommClause, - eDeclStmt, - eDeferStmt, - eEmptyStmt, - eExprStmt, - eForStmt, - eGoStmt, - eIfStmt, - eIncDecStmt, - eLabeledStmt, - eRangeStmt, - eReturnStmt, - eSelectStmt, - eSendStmt, - eSwitchStmt, - eTypeSwitchStmt, - eField, - eFieldList, - }; - - virtual ~GoASTNode() = default; - - NodeKind GetKind() const { return m_kind; } - - virtual const char *GetKindName() const = 0; - - template void WalkChildren(V &v); - -protected: - explicit GoASTNode(NodeKind kind) : m_kind(kind) {} - -private: - const NodeKind m_kind; - - GoASTNode(const GoASTNode &) = delete; - const GoASTNode &operator=(const GoASTNode &) = delete; -}; - -class GoASTDecl : public GoASTNode { -public: - template R Visit(V *v) const; - - static bool classof(const GoASTNode *n) { - return n->GetKind() >= eBadDecl && n->GetKind() <= eGenDecl; - } - -protected: - explicit GoASTDecl(NodeKind kind) : GoASTNode(kind) {} - -private: - GoASTDecl(const GoASTDecl &) = delete; - const GoASTDecl &operator=(const GoASTDecl &) = delete; -}; - -class GoASTExpr : public GoASTNode { -public: - template R Visit(V *v) const; - - static bool classof(const GoASTNode *n) { - return n->GetKind() >= eArrayType && n->GetKind() <= eUnaryExpr; - } - -protected: - explicit GoASTExpr(NodeKind kind) : GoASTNode(kind) {} - -private: - GoASTExpr(const GoASTExpr &) = delete; - const GoASTExpr &operator=(const GoASTExpr &) = delete; -}; - -class GoASTSpec : public GoASTNode { -public: - template R Visit(V *v) const; - - static bool classof(const GoASTNode *n) { - return n->GetKind() >= eImportSpec && n->GetKind() <= eValueSpec; - } - -protected: - explicit GoASTSpec(NodeKind kind) : GoASTNode(kind) {} - -private: - GoASTSpec(const GoASTSpec &) = delete; - const GoASTSpec &operator=(const GoASTSpec &) = delete; -}; - -class GoASTStmt : public GoASTNode { -public: - template R Visit(V *v) const; - - static bool classof(const GoASTNode *n) { - return n->GetKind() >= eAssignStmt && n->GetKind() <= eTypeSwitchStmt; - } - -protected: - explicit GoASTStmt(NodeKind kind) : GoASTNode(kind) {} - -private: - GoASTStmt(const GoASTStmt &) = delete; - const GoASTStmt &operator=(const GoASTStmt &) = delete; -}; - -class GoASTArrayType : public GoASTExpr { -public: - GoASTArrayType(GoASTExpr *len, GoASTExpr *elt) - : GoASTExpr(eArrayType), m_len_up(len), m_elt_up(elt) {} - ~GoASTArrayType() override = default; - - const char *GetKindName() const override { return "ArrayType"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eArrayType; } - - const GoASTExpr *GetLen() const { return m_len_up.get(); } - void SetLen(GoASTExpr *len) { m_len_up.reset(len); } - - const GoASTExpr *GetElt() const { return m_elt_up.get(); } - void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); } - -private: - friend class GoASTNode; - std::unique_ptr m_len_up; - std::unique_ptr m_elt_up; - - GoASTArrayType(const GoASTArrayType &) = delete; - const GoASTArrayType &operator=(const GoASTArrayType &) = delete; -}; - -class GoASTAssignStmt : public GoASTStmt { -public: - explicit GoASTAssignStmt(bool define) - : GoASTStmt(eAssignStmt), m_define(define) {} - ~GoASTAssignStmt() override = default; - - const char *GetKindName() const override { return "AssignStmt"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eAssignStmt; - } - - size_t NumLhs() const { return m_lhs.size(); } - const GoASTExpr *GetLhs(int i) const { return m_lhs[i].get(); } - void AddLhs(GoASTExpr *lhs) { - m_lhs.push_back(std::unique_ptr(lhs)); - } - - size_t NumRhs() const { return m_rhs.size(); } - const GoASTExpr *GetRhs(int i) const { return m_rhs[i].get(); } - void AddRhs(GoASTExpr *rhs) { - m_rhs.push_back(std::unique_ptr(rhs)); - } - - bool GetDefine() const { return m_define; } - void SetDefine(bool define) { m_define = define; } - -private: - friend class GoASTNode; - std::vector> m_lhs; - std::vector> m_rhs; - bool m_define; - - GoASTAssignStmt(const GoASTAssignStmt &) = delete; - const GoASTAssignStmt &operator=(const GoASTAssignStmt &) = delete; -}; - -class GoASTBadDecl : public GoASTDecl { -public: - GoASTBadDecl() : GoASTDecl(eBadDecl) {} - ~GoASTBadDecl() override = default; - - const char *GetKindName() const override { return "BadDecl"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eBadDecl; } - - GoASTBadDecl(const GoASTBadDecl &) = delete; - const GoASTBadDecl &operator=(const GoASTBadDecl &) = delete; -}; - -class GoASTBadExpr : public GoASTExpr { -public: - GoASTBadExpr() : GoASTExpr(eBadExpr) {} - ~GoASTBadExpr() override = default; - - const char *GetKindName() const override { return "BadExpr"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eBadExpr; } - - GoASTBadExpr(const GoASTBadExpr &) = delete; - const GoASTBadExpr &operator=(const GoASTBadExpr &) = delete; -}; - -class GoASTBadStmt : public GoASTStmt { -public: - GoASTBadStmt() : GoASTStmt(eBadStmt) {} - ~GoASTBadStmt() override = default; - - const char *GetKindName() const override { return "BadStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eBadStmt; } - - GoASTBadStmt(const GoASTBadStmt &) = delete; - const GoASTBadStmt &operator=(const GoASTBadStmt &) = delete; -}; - -class GoASTBasicLit : public GoASTExpr { -public: - explicit GoASTBasicLit(Token value) : GoASTExpr(eBasicLit), m_value(value) {} - ~GoASTBasicLit() override = default; - - const char *GetKindName() const override { return "BasicLit"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eBasicLit; } - - Token GetValue() const { return m_value; } - void SetValue(Token value) { m_value = value; } - -private: - friend class GoASTNode; - Token m_value; - - GoASTBasicLit(const GoASTBasicLit &) = delete; - const GoASTBasicLit &operator=(const GoASTBasicLit &) = delete; -}; - -class GoASTBinaryExpr : public GoASTExpr { -public: - GoASTBinaryExpr(GoASTExpr *x, GoASTExpr *y, TokenType op) - : GoASTExpr(eBinaryExpr), m_x_up(x), m_y_up(y), m_op(op) {} - ~GoASTBinaryExpr() override = default; - - const char *GetKindName() const override { return "BinaryExpr"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eBinaryExpr; - } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - - const GoASTExpr *GetY() const { return m_y_up.get(); } - void SetY(GoASTExpr *y) { m_y_up.reset(y); } - - TokenType GetOp() const { return m_op; } - void SetOp(TokenType op) { m_op = op; } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - std::unique_ptr m_y_up; - TokenType m_op; - - GoASTBinaryExpr(const GoASTBinaryExpr &) = delete; - const GoASTBinaryExpr &operator=(const GoASTBinaryExpr &) = delete; -}; - -class GoASTBlockStmt : public GoASTStmt { -public: - GoASTBlockStmt() : GoASTStmt(eBlockStmt) {} - ~GoASTBlockStmt() override = default; - - const char *GetKindName() const override { return "BlockStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eBlockStmt; } - - size_t NumList() const { return m_list.size(); } - const GoASTStmt *GetList(int i) const { return m_list[i].get(); } - void AddList(GoASTStmt *list) { - m_list.push_back(std::unique_ptr(list)); - } - -private: - friend class GoASTNode; - std::vector> m_list; - - GoASTBlockStmt(const GoASTBlockStmt &) = delete; - const GoASTBlockStmt &operator=(const GoASTBlockStmt &) = delete; -}; - -class GoASTIdent : public GoASTExpr { -public: - explicit GoASTIdent(Token name) : GoASTExpr(eIdent), m_name(name) {} - ~GoASTIdent() override = default; - - const char *GetKindName() const override { return "Ident"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eIdent; } - - Token GetName() const { return m_name; } - void SetName(Token name) { m_name = name; } - -private: - friend class GoASTNode; - Token m_name; - - GoASTIdent(const GoASTIdent &) = delete; - const GoASTIdent &operator=(const GoASTIdent &) = delete; -}; - -class GoASTBranchStmt : public GoASTStmt { -public: - GoASTBranchStmt(GoASTIdent *label, TokenType tok) - : GoASTStmt(eBranchStmt), m_label_up(label), m_tok(tok) {} - ~GoASTBranchStmt() override = default; - - const char *GetKindName() const override { return "BranchStmt"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eBranchStmt; - } - - const GoASTIdent *GetLabel() const { return m_label_up.get(); } - void SetLabel(GoASTIdent *label) { m_label_up.reset(label); } - - TokenType GetTok() const { return m_tok; } - void SetTok(TokenType tok) { m_tok = tok; } - -private: - friend class GoASTNode; - std::unique_ptr m_label_up; - TokenType m_tok; - - GoASTBranchStmt(const GoASTBranchStmt &) = delete; - const GoASTBranchStmt &operator=(const GoASTBranchStmt &) = delete; -}; - -class GoASTCallExpr : public GoASTExpr { -public: - explicit GoASTCallExpr(bool ellipsis) - : GoASTExpr(eCallExpr), m_ellipsis(ellipsis) {} - ~GoASTCallExpr() override = default; - - const char *GetKindName() const override { return "CallExpr"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eCallExpr; } - - const GoASTExpr *GetFun() const { return m_fun_up.get(); } - void SetFun(GoASTExpr *fun) { m_fun_up.reset(fun); } - - size_t NumArgs() const { return m_args.size(); } - const GoASTExpr *GetArgs(int i) const { return m_args[i].get(); } - void AddArgs(GoASTExpr *args) { - m_args.push_back(std::unique_ptr(args)); - } - - bool GetEllipsis() const { return m_ellipsis; } - void SetEllipsis(bool ellipsis) { m_ellipsis = ellipsis; } - -private: - friend class GoASTNode; - std::unique_ptr m_fun_up; - std::vector> m_args; - bool m_ellipsis; - - GoASTCallExpr(const GoASTCallExpr &) = delete; - const GoASTCallExpr &operator=(const GoASTCallExpr &) = delete; -}; - -class GoASTCaseClause : public GoASTStmt { -public: - GoASTCaseClause() : GoASTStmt(eCaseClause) {} - ~GoASTCaseClause() override = default; - - const char *GetKindName() const override { return "CaseClause"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eCaseClause; - } - - size_t NumList() const { return m_list.size(); } - const GoASTExpr *GetList(int i) const { return m_list[i].get(); } - void AddList(GoASTExpr *list) { - m_list.push_back(std::unique_ptr(list)); - } - - size_t NumBody() const { return m_body.size(); } - const GoASTStmt *GetBody(int i) const { return m_body[i].get(); } - void AddBody(GoASTStmt *body) { - m_body.push_back(std::unique_ptr(body)); - } - -private: - friend class GoASTNode; - std::vector> m_list; - std::vector> m_body; - - GoASTCaseClause(const GoASTCaseClause &) = delete; - const GoASTCaseClause &operator=(const GoASTCaseClause &) = delete; -}; - -class GoASTChanType : public GoASTExpr { -public: - GoASTChanType(ChanDir dir, GoASTExpr *value) - : GoASTExpr(eChanType), m_dir(dir), m_value_up(value) {} - ~GoASTChanType() override = default; - - const char *GetKindName() const override { return "ChanType"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eChanType; } - - ChanDir GetDir() const { return m_dir; } - void SetDir(ChanDir dir) { m_dir = dir; } - - const GoASTExpr *GetValue() const { return m_value_up.get(); } - void SetValue(GoASTExpr *value) { m_value_up.reset(value); } - -private: - friend class GoASTNode; - ChanDir m_dir; - std::unique_ptr m_value_up; - - GoASTChanType(const GoASTChanType &) = delete; - const GoASTChanType &operator=(const GoASTChanType &) = delete; -}; - -class GoASTCommClause : public GoASTStmt { -public: - GoASTCommClause() : GoASTStmt(eCommClause) {} - ~GoASTCommClause() override = default; - - const char *GetKindName() const override { return "CommClause"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eCommClause; - } - - const GoASTStmt *GetComm() const { return m_comm_up.get(); } - void SetComm(GoASTStmt *comm) { m_comm_up.reset(comm); } - - size_t NumBody() const { return m_body.size(); } - const GoASTStmt *GetBody(int i) const { return m_body[i].get(); } - void AddBody(GoASTStmt *body) { - m_body.push_back(std::unique_ptr(body)); - } - -private: - friend class GoASTNode; - std::unique_ptr m_comm_up; - std::vector> m_body; - - GoASTCommClause(const GoASTCommClause &) = delete; - const GoASTCommClause &operator=(const GoASTCommClause &) = delete; -}; - -class GoASTCompositeLit : public GoASTExpr { -public: - GoASTCompositeLit() : GoASTExpr(eCompositeLit) {} - ~GoASTCompositeLit() override = default; - - const char *GetKindName() const override { return "CompositeLit"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eCompositeLit; - } - - const GoASTExpr *GetType() const { return m_type_up.get(); } - void SetType(GoASTExpr *type) { m_type_up.reset(type); } - - size_t NumElts() const { return m_elts.size(); } - const GoASTExpr *GetElts(int i) const { return m_elts[i].get(); } - void AddElts(GoASTExpr *elts) { - m_elts.push_back(std::unique_ptr(elts)); - } - -private: - friend class GoASTNode; - std::unique_ptr m_type_up; - std::vector> m_elts; - - GoASTCompositeLit(const GoASTCompositeLit &) = delete; - const GoASTCompositeLit &operator=(const GoASTCompositeLit &) = delete; -}; - -class GoASTDeclStmt : public GoASTStmt { -public: - explicit GoASTDeclStmt(GoASTDecl *decl) - : GoASTStmt(eDeclStmt), m_decl_up(decl) {} - ~GoASTDeclStmt() override = default; - - const char *GetKindName() const override { return "DeclStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eDeclStmt; } - - const GoASTDecl *GetDecl() const { return m_decl_up.get(); } - void SetDecl(GoASTDecl *decl) { m_decl_up.reset(decl); } - -private: - friend class GoASTNode; - std::unique_ptr m_decl_up; - - GoASTDeclStmt(const GoASTDeclStmt &) = delete; - const GoASTDeclStmt &operator=(const GoASTDeclStmt &) = delete; -}; - -class GoASTDeferStmt : public GoASTStmt { -public: - explicit GoASTDeferStmt(GoASTCallExpr *call) - : GoASTStmt(eDeferStmt), m_call_up(call) {} - ~GoASTDeferStmt() override = default; - - const char *GetKindName() const override { return "DeferStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eDeferStmt; } - - const GoASTCallExpr *GetCall() const { return m_call_up.get(); } - void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); } - -private: - friend class GoASTNode; - std::unique_ptr m_call_up; - - GoASTDeferStmt(const GoASTDeferStmt &) = delete; - const GoASTDeferStmt &operator=(const GoASTDeferStmt &) = delete; -}; - -class GoASTEllipsis : public GoASTExpr { -public: - explicit GoASTEllipsis(GoASTExpr *elt) - : GoASTExpr(eEllipsis), m_elt_up(elt) {} - ~GoASTEllipsis() override = default; - - const char *GetKindName() const override { return "Ellipsis"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eEllipsis; } - - const GoASTExpr *GetElt() const { return m_elt_up.get(); } - void SetElt(GoASTExpr *elt) { m_elt_up.reset(elt); } - -private: - friend class GoASTNode; - std::unique_ptr m_elt_up; - - GoASTEllipsis(const GoASTEllipsis &) = delete; - const GoASTEllipsis &operator=(const GoASTEllipsis &) = delete; -}; - -class GoASTEmptyStmt : public GoASTStmt { -public: - GoASTEmptyStmt() : GoASTStmt(eEmptyStmt) {} - ~GoASTEmptyStmt() override = default; - - const char *GetKindName() const override { return "EmptyStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eEmptyStmt; } - - GoASTEmptyStmt(const GoASTEmptyStmt &) = delete; - const GoASTEmptyStmt &operator=(const GoASTEmptyStmt &) = delete; -}; - -class GoASTExprStmt : public GoASTStmt { -public: - explicit GoASTExprStmt(GoASTExpr *x) : GoASTStmt(eExprStmt), m_x_up(x) {} - ~GoASTExprStmt() override = default; - - const char *GetKindName() const override { return "ExprStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eExprStmt; } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - - GoASTExprStmt(const GoASTExprStmt &) = delete; - const GoASTExprStmt &operator=(const GoASTExprStmt &) = delete; -}; - -class GoASTField : public GoASTNode { -public: - GoASTField() : GoASTNode(eField) {} - ~GoASTField() override = default; - - const char *GetKindName() const override { return "Field"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eField; } - - size_t NumNames() const { return m_names.size(); } - const GoASTIdent *GetNames(int i) const { return m_names[i].get(); } - void AddNames(GoASTIdent *names) { - m_names.push_back(std::unique_ptr(names)); - } - - const GoASTExpr *GetType() const { return m_type_up.get(); } - void SetType(GoASTExpr *type) { m_type_up.reset(type); } - - const GoASTBasicLit *GetTag() const { return m_tag_up.get(); } - void SetTag(GoASTBasicLit *tag) { m_tag_up.reset(tag); } - -private: - friend class GoASTNode; - std::vector> m_names; - std::unique_ptr m_type_up; - std::unique_ptr m_tag_up; - - GoASTField(const GoASTField &) = delete; - const GoASTField &operator=(const GoASTField &) = delete; -}; - -class GoASTFieldList : public GoASTNode { -public: - GoASTFieldList() : GoASTNode(eFieldList) {} - ~GoASTFieldList() override = default; - - const char *GetKindName() const override { return "FieldList"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eFieldList; } - - size_t NumList() const { return m_list.size(); } - const GoASTField *GetList(int i) const { return m_list[i].get(); } - void AddList(GoASTField *list) { - m_list.push_back(std::unique_ptr(list)); - } - -private: - friend class GoASTNode; - std::vector> m_list; - - GoASTFieldList(const GoASTFieldList &) = delete; - const GoASTFieldList &operator=(const GoASTFieldList &) = delete; -}; - -class GoASTForStmt : public GoASTStmt { -public: - GoASTForStmt(GoASTStmt *init, GoASTExpr *cond, GoASTStmt *post, - GoASTBlockStmt *body) - : GoASTStmt(eForStmt), m_init_up(init), m_cond_up(cond), m_post_up(post), - m_body_up(body) {} - ~GoASTForStmt() override = default; - - const char *GetKindName() const override { return "ForStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eForStmt; } - - const GoASTStmt *GetInit() const { return m_init_up.get(); } - void SetInit(GoASTStmt *init) { m_init_up.reset(init); } - - const GoASTExpr *GetCond() const { return m_cond_up.get(); } - void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); } - - const GoASTStmt *GetPost() const { return m_post_up.get(); } - void SetPost(GoASTStmt *post) { m_post_up.reset(post); } - - const GoASTBlockStmt *GetBody() const { return m_body_up.get(); } - void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); } - -private: - friend class GoASTNode; - std::unique_ptr m_init_up; - std::unique_ptr m_cond_up; - std::unique_ptr m_post_up; - std::unique_ptr m_body_up; - - GoASTForStmt(const GoASTForStmt &) = delete; - const GoASTForStmt &operator=(const GoASTForStmt &) = delete; -}; - -class GoASTFuncType : public GoASTExpr { -public: - GoASTFuncType(GoASTFieldList *params, GoASTFieldList *results) - : GoASTExpr(eFuncType), m_params_up(params), m_results_up(results) {} - ~GoASTFuncType() override = default; - - const char *GetKindName() const override { return "FuncType"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncType; } - - const GoASTFieldList *GetParams() const { return m_params_up.get(); } - void SetParams(GoASTFieldList *params) { m_params_up.reset(params); } - - const GoASTFieldList *GetResults() const { return m_results_up.get(); } - void SetResults(GoASTFieldList *results) { m_results_up.reset(results); } - -private: - friend class GoASTNode; - std::unique_ptr m_params_up; - std::unique_ptr m_results_up; - - GoASTFuncType(const GoASTFuncType &) = delete; - const GoASTFuncType &operator=(const GoASTFuncType &) = delete; -}; - -class GoASTFuncDecl : public GoASTDecl { -public: - GoASTFuncDecl(GoASTFieldList *recv, GoASTIdent *name, GoASTFuncType *type, - GoASTBlockStmt *body) - : GoASTDecl(eFuncDecl), m_recv_up(recv), m_name_up(name), m_type_up(type), - m_body_up(body) {} - ~GoASTFuncDecl() override = default; - - const char *GetKindName() const override { return "FuncDecl"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncDecl; } - - const GoASTFieldList *GetRecv() const { return m_recv_up.get(); } - void SetRecv(GoASTFieldList *recv) { m_recv_up.reset(recv); } - - const GoASTIdent *GetName() const { return m_name_up.get(); } - void SetName(GoASTIdent *name) { m_name_up.reset(name); } - - const GoASTFuncType *GetType() const { return m_type_up.get(); } - void SetType(GoASTFuncType *type) { m_type_up.reset(type); } - - const GoASTBlockStmt *GetBody() const { return m_body_up.get(); } - void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); } - -private: - friend class GoASTNode; - std::unique_ptr m_recv_up; - std::unique_ptr m_name_up; - std::unique_ptr m_type_up; - std::unique_ptr m_body_up; - - GoASTFuncDecl(const GoASTFuncDecl &) = delete; - const GoASTFuncDecl &operator=(const GoASTFuncDecl &) = delete; -}; - -class GoASTFuncLit : public GoASTExpr { -public: - GoASTFuncLit(GoASTFuncType *type, GoASTBlockStmt *body) - : GoASTExpr(eFuncLit), m_type_up(type), m_body_up(body) {} - ~GoASTFuncLit() override = default; - - const char *GetKindName() const override { return "FuncLit"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eFuncLit; } - - const GoASTFuncType *GetType() const { return m_type_up.get(); } - void SetType(GoASTFuncType *type) { m_type_up.reset(type); } - - const GoASTBlockStmt *GetBody() const { return m_body_up.get(); } - void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); } - -private: - friend class GoASTNode; - std::unique_ptr m_type_up; - std::unique_ptr m_body_up; - - GoASTFuncLit(const GoASTFuncLit &) = delete; - const GoASTFuncLit &operator=(const GoASTFuncLit &) = delete; -}; - -class GoASTGenDecl : public GoASTDecl { -public: - explicit GoASTGenDecl(TokenType tok) : GoASTDecl(eGenDecl), m_tok(tok) {} - ~GoASTGenDecl() override = default; - - const char *GetKindName() const override { return "GenDecl"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eGenDecl; } - - TokenType GetTok() const { return m_tok; } - void SetTok(TokenType tok) { m_tok = tok; } - - size_t NumSpecs() const { return m_specs.size(); } - const GoASTSpec *GetSpecs(int i) const { return m_specs[i].get(); } - void AddSpecs(GoASTSpec *specs) { - m_specs.push_back(std::unique_ptr(specs)); - } - -private: - friend class GoASTNode; - TokenType m_tok; - std::vector> m_specs; - - GoASTGenDecl(const GoASTGenDecl &) = delete; - const GoASTGenDecl &operator=(const GoASTGenDecl &) = delete; -}; - -class GoASTGoStmt : public GoASTStmt { -public: - explicit GoASTGoStmt(GoASTCallExpr *call) - : GoASTStmt(eGoStmt), m_call_up(call) {} - ~GoASTGoStmt() override = default; - - const char *GetKindName() const override { return "GoStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eGoStmt; } - - const GoASTCallExpr *GetCall() const { return m_call_up.get(); } - void SetCall(GoASTCallExpr *call) { m_call_up.reset(call); } - -private: - friend class GoASTNode; - std::unique_ptr m_call_up; - - GoASTGoStmt(const GoASTGoStmt &) = delete; - const GoASTGoStmt &operator=(const GoASTGoStmt &) = delete; -}; - -class GoASTIfStmt : public GoASTStmt { -public: - GoASTIfStmt(GoASTStmt *init, GoASTExpr *cond, GoASTBlockStmt *body, - GoASTStmt *els) - : GoASTStmt(eIfStmt), m_init_up(init), m_cond_up(cond), m_body_up(body), - m_els_up(els) {} - ~GoASTIfStmt() override = default; - - const char *GetKindName() const override { return "IfStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eIfStmt; } - - const GoASTStmt *GetInit() const { return m_init_up.get(); } - void SetInit(GoASTStmt *init) { m_init_up.reset(init); } - - const GoASTExpr *GetCond() const { return m_cond_up.get(); } - void SetCond(GoASTExpr *cond) { m_cond_up.reset(cond); } - - const GoASTBlockStmt *GetBody() const { return m_body_up.get(); } - void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); } - - const GoASTStmt *GetEls() const { return m_els_up.get(); } - void SetEls(GoASTStmt *els) { m_els_up.reset(els); } - -private: - friend class GoASTNode; - std::unique_ptr m_init_up; - std::unique_ptr m_cond_up; - std::unique_ptr m_body_up; - std::unique_ptr m_els_up; - - GoASTIfStmt(const GoASTIfStmt &) = delete; - const GoASTIfStmt &operator=(const GoASTIfStmt &) = delete; -}; - -class GoASTImportSpec : public GoASTSpec { -public: - GoASTImportSpec(GoASTIdent *name, GoASTBasicLit *path) - : GoASTSpec(eImportSpec), m_name_up(name), m_path_up(path) {} - ~GoASTImportSpec() override = default; - - const char *GetKindName() const override { return "ImportSpec"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eImportSpec; - } - - const GoASTIdent *GetName() const { return m_name_up.get(); } - void SetName(GoASTIdent *name) { m_name_up.reset(name); } - - const GoASTBasicLit *GetPath() const { return m_path_up.get(); } - void SetPath(GoASTBasicLit *path) { m_path_up.reset(path); } - -private: - friend class GoASTNode; - std::unique_ptr m_name_up; - std::unique_ptr m_path_up; - - GoASTImportSpec(const GoASTImportSpec &) = delete; - const GoASTImportSpec &operator=(const GoASTImportSpec &) = delete; -}; - -class GoASTIncDecStmt : public GoASTStmt { -public: - GoASTIncDecStmt(GoASTExpr *x, TokenType tok) - : GoASTStmt(eIncDecStmt), m_x_up(x), m_tok(tok) {} - ~GoASTIncDecStmt() override = default; - - const char *GetKindName() const override { return "IncDecStmt"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eIncDecStmt; - } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - - TokenType GetTok() const { return m_tok; } - void SetTok(TokenType tok) { m_tok = tok; } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - TokenType m_tok; - - GoASTIncDecStmt(const GoASTIncDecStmt &) = delete; - const GoASTIncDecStmt &operator=(const GoASTIncDecStmt &) = delete; -}; - -class GoASTIndexExpr : public GoASTExpr { -public: - GoASTIndexExpr(GoASTExpr *x, GoASTExpr *index) - : GoASTExpr(eIndexExpr), m_x_up(x), m_index_up(index) {} - ~GoASTIndexExpr() override = default; - - const char *GetKindName() const override { return "IndexExpr"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eIndexExpr; } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - - const GoASTExpr *GetIndex() const { return m_index_up.get(); } - void SetIndex(GoASTExpr *index) { m_index_up.reset(index); } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - std::unique_ptr m_index_up; - - GoASTIndexExpr(const GoASTIndexExpr &) = delete; - const GoASTIndexExpr &operator=(const GoASTIndexExpr &) = delete; -}; - -class GoASTInterfaceType : public GoASTExpr { -public: - explicit GoASTInterfaceType(GoASTFieldList *methods) - : GoASTExpr(eInterfaceType), m_methods_up(methods) {} - ~GoASTInterfaceType() override = default; - - const char *GetKindName() const override { return "InterfaceType"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eInterfaceType; - } - - const GoASTFieldList *GetMethods() const { return m_methods_up.get(); } - void SetMethods(GoASTFieldList *methods) { m_methods_up.reset(methods); } - -private: - friend class GoASTNode; - std::unique_ptr m_methods_up; - - GoASTInterfaceType(const GoASTInterfaceType &) = delete; - const GoASTInterfaceType &operator=(const GoASTInterfaceType &) = delete; -}; - -class GoASTKeyValueExpr : public GoASTExpr { -public: - GoASTKeyValueExpr(GoASTExpr *key, GoASTExpr *value) - : GoASTExpr(eKeyValueExpr), m_key_up(key), m_value_up(value) {} - ~GoASTKeyValueExpr() override = default; - - const char *GetKindName() const override { return "KeyValueExpr"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eKeyValueExpr; - } - - const GoASTExpr *GetKey() const { return m_key_up.get(); } - void SetKey(GoASTExpr *key) { m_key_up.reset(key); } - - const GoASTExpr *GetValue() const { return m_value_up.get(); } - void SetValue(GoASTExpr *value) { m_value_up.reset(value); } - -private: - friend class GoASTNode; - std::unique_ptr m_key_up; - std::unique_ptr m_value_up; - - GoASTKeyValueExpr(const GoASTKeyValueExpr &) = delete; - const GoASTKeyValueExpr &operator=(const GoASTKeyValueExpr &) = delete; -}; - -class GoASTLabeledStmt : public GoASTStmt { -public: - GoASTLabeledStmt(GoASTIdent *label, GoASTStmt *stmt) - : GoASTStmt(eLabeledStmt), m_label_up(label), m_stmt_up(stmt) {} - ~GoASTLabeledStmt() override = default; - - const char *GetKindName() const override { return "LabeledStmt"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eLabeledStmt; - } - - const GoASTIdent *GetLabel() const { return m_label_up.get(); } - void SetLabel(GoASTIdent *label) { m_label_up.reset(label); } - - const GoASTStmt *GetStmt() const { return m_stmt_up.get(); } - void SetStmt(GoASTStmt *stmt) { m_stmt_up.reset(stmt); } - -private: - friend class GoASTNode; - std::unique_ptr m_label_up; - std::unique_ptr m_stmt_up; - - GoASTLabeledStmt(const GoASTLabeledStmt &) = delete; - const GoASTLabeledStmt &operator=(const GoASTLabeledStmt &) = delete; -}; - -class GoASTMapType : public GoASTExpr { -public: - GoASTMapType(GoASTExpr *key, GoASTExpr *value) - : GoASTExpr(eMapType), m_key_up(key), m_value_up(value) {} - ~GoASTMapType() override = default; - - const char *GetKindName() const override { return "MapType"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eMapType; } - - const GoASTExpr *GetKey() const { return m_key_up.get(); } - void SetKey(GoASTExpr *key) { m_key_up.reset(key); } - - const GoASTExpr *GetValue() const { return m_value_up.get(); } - void SetValue(GoASTExpr *value) { m_value_up.reset(value); } - -private: - friend class GoASTNode; - std::unique_ptr m_key_up; - std::unique_ptr m_value_up; - - GoASTMapType(const GoASTMapType &) = delete; - const GoASTMapType &operator=(const GoASTMapType &) = delete; -}; - -class GoASTParenExpr : public GoASTExpr { -public: - explicit GoASTParenExpr(GoASTExpr *x) : GoASTExpr(eParenExpr), m_x_up(x) {} - ~GoASTParenExpr() override = default; - - const char *GetKindName() const override { return "ParenExpr"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eParenExpr; } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - - GoASTParenExpr(const GoASTParenExpr &) = delete; - const GoASTParenExpr &operator=(const GoASTParenExpr &) = delete; -}; - -class GoASTRangeStmt : public GoASTStmt { -public: - GoASTRangeStmt(GoASTExpr *key, GoASTExpr *value, bool define, GoASTExpr *x, - GoASTBlockStmt *body) - : GoASTStmt(eRangeStmt), m_key_up(key), m_value_up(value), - m_define(define), m_x_up(x), m_body_up(body) {} - ~GoASTRangeStmt() override = default; - - const char *GetKindName() const override { return "RangeStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eRangeStmt; } - - const GoASTExpr *GetKey() const { return m_key_up.get(); } - void SetKey(GoASTExpr *key) { m_key_up.reset(key); } - - const GoASTExpr *GetValue() const { return m_value_up.get(); } - void SetValue(GoASTExpr *value) { m_value_up.reset(value); } - - bool GetDefine() const { return m_define; } - void SetDefine(bool define) { m_define = define; } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - - const GoASTBlockStmt *GetBody() const { return m_body_up.get(); } - void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); } - -private: - friend class GoASTNode; - std::unique_ptr m_key_up; - std::unique_ptr m_value_up; - bool m_define; - std::unique_ptr m_x_up; - std::unique_ptr m_body_up; - - GoASTRangeStmt(const GoASTRangeStmt &) = delete; - const GoASTRangeStmt &operator=(const GoASTRangeStmt &) = delete; -}; - -class GoASTReturnStmt : public GoASTStmt { -public: - GoASTReturnStmt() : GoASTStmt(eReturnStmt) {} - ~GoASTReturnStmt() override = default; - - const char *GetKindName() const override { return "ReturnStmt"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eReturnStmt; - } - - size_t NumResults() const { return m_results.size(); } - const GoASTExpr *GetResults(int i) const { return m_results[i].get(); } - void AddResults(GoASTExpr *results) { - m_results.push_back(std::unique_ptr(results)); - } - -private: - friend class GoASTNode; - std::vector> m_results; - - GoASTReturnStmt(const GoASTReturnStmt &) = delete; - const GoASTReturnStmt &operator=(const GoASTReturnStmt &) = delete; -}; - -class GoASTSelectStmt : public GoASTStmt { -public: - explicit GoASTSelectStmt(GoASTBlockStmt *body) - : GoASTStmt(eSelectStmt), m_body_up(body) {} - ~GoASTSelectStmt() override = default; - - const char *GetKindName() const override { return "SelectStmt"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eSelectStmt; - } - - const GoASTBlockStmt *GetBody() const { return m_body_up.get(); } - void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); } - -private: - friend class GoASTNode; - std::unique_ptr m_body_up; - - GoASTSelectStmt(const GoASTSelectStmt &) = delete; - const GoASTSelectStmt &operator=(const GoASTSelectStmt &) = delete; -}; - -class GoASTSelectorExpr : public GoASTExpr { -public: - GoASTSelectorExpr(GoASTExpr *x, GoASTIdent *sel) - : GoASTExpr(eSelectorExpr), m_x_up(x), m_sel_up(sel) {} - ~GoASTSelectorExpr() override = default; - - const char *GetKindName() const override { return "SelectorExpr"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eSelectorExpr; - } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - - const GoASTIdent *GetSel() const { return m_sel_up.get(); } - void SetSel(GoASTIdent *sel) { m_sel_up.reset(sel); } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - std::unique_ptr m_sel_up; - - GoASTSelectorExpr(const GoASTSelectorExpr &) = delete; - const GoASTSelectorExpr &operator=(const GoASTSelectorExpr &) = delete; -}; - -class GoASTSendStmt : public GoASTStmt { -public: - GoASTSendStmt(GoASTExpr *chan, GoASTExpr *value) - : GoASTStmt(eSendStmt), m_chan_up(chan), m_value_up(value) {} - ~GoASTSendStmt() override = default; - - const char *GetKindName() const override { return "SendStmt"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eSendStmt; } - - const GoASTExpr *GetChan() const { return m_chan_up.get(); } - void SetChan(GoASTExpr *chan) { m_chan_up.reset(chan); } - - const GoASTExpr *GetValue() const { return m_value_up.get(); } - void SetValue(GoASTExpr *value) { m_value_up.reset(value); } - -private: - friend class GoASTNode; - std::unique_ptr m_chan_up; - std::unique_ptr m_value_up; - - GoASTSendStmt(const GoASTSendStmt &) = delete; - const GoASTSendStmt &operator=(const GoASTSendStmt &) = delete; -}; - -class GoASTSliceExpr : public GoASTExpr { -public: - GoASTSliceExpr(GoASTExpr *x, GoASTExpr *low, GoASTExpr *high, GoASTExpr *max, - bool slice3) - : GoASTExpr(eSliceExpr), m_x_up(x), m_low_up(low), m_high_up(high), - m_max_up(max), m_slice3(slice3) {} - ~GoASTSliceExpr() override = default; - - const char *GetKindName() const override { return "SliceExpr"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eSliceExpr; } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - - const GoASTExpr *GetLow() const { return m_low_up.get(); } - void SetLow(GoASTExpr *low) { m_low_up.reset(low); } - - const GoASTExpr *GetHigh() const { return m_high_up.get(); } - void SetHigh(GoASTExpr *high) { m_high_up.reset(high); } - - const GoASTExpr *GetMax() const { return m_max_up.get(); } - void SetMax(GoASTExpr *max) { m_max_up.reset(max); } - - bool GetSlice3() const { return m_slice3; } - void SetSlice3(bool slice3) { m_slice3 = slice3; } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - std::unique_ptr m_low_up; - std::unique_ptr m_high_up; - std::unique_ptr m_max_up; - bool m_slice3; - - GoASTSliceExpr(const GoASTSliceExpr &) = delete; - const GoASTSliceExpr &operator=(const GoASTSliceExpr &) = delete; -}; - -class GoASTStarExpr : public GoASTExpr { -public: - explicit GoASTStarExpr(GoASTExpr *x) : GoASTExpr(eStarExpr), m_x_up(x) {} - ~GoASTStarExpr() override = default; - - const char *GetKindName() const override { return "StarExpr"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eStarExpr; } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - - GoASTStarExpr(const GoASTStarExpr &) = delete; - const GoASTStarExpr &operator=(const GoASTStarExpr &) = delete; -}; - -class GoASTStructType : public GoASTExpr { -public: - explicit GoASTStructType(GoASTFieldList *fields) - : GoASTExpr(eStructType), m_fields_up(fields) {} - ~GoASTStructType() override = default; - - const char *GetKindName() const override { return "StructType"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eStructType; - } - - const GoASTFieldList *GetFields() const { return m_fields_up.get(); } - void SetFields(GoASTFieldList *fields) { m_fields_up.reset(fields); } - -private: - friend class GoASTNode; - std::unique_ptr m_fields_up; - - GoASTStructType(const GoASTStructType &) = delete; - const GoASTStructType &operator=(const GoASTStructType &) = delete; -}; - -class GoASTSwitchStmt : public GoASTStmt { -public: - GoASTSwitchStmt(GoASTStmt *init, GoASTExpr *tag, GoASTBlockStmt *body) - : GoASTStmt(eSwitchStmt), m_init_up(init), m_tag_up(tag), - m_body_up(body) {} - ~GoASTSwitchStmt() override = default; - - const char *GetKindName() const override { return "SwitchStmt"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eSwitchStmt; - } - - const GoASTStmt *GetInit() const { return m_init_up.get(); } - void SetInit(GoASTStmt *init) { m_init_up.reset(init); } - - const GoASTExpr *GetTag() const { return m_tag_up.get(); } - void SetTag(GoASTExpr *tag) { m_tag_up.reset(tag); } - - const GoASTBlockStmt *GetBody() const { return m_body_up.get(); } - void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); } - -private: - friend class GoASTNode; - std::unique_ptr m_init_up; - std::unique_ptr m_tag_up; - std::unique_ptr m_body_up; - - GoASTSwitchStmt(const GoASTSwitchStmt &) = delete; - const GoASTSwitchStmt &operator=(const GoASTSwitchStmt &) = delete; -}; - -class GoASTTypeAssertExpr : public GoASTExpr { -public: - GoASTTypeAssertExpr(GoASTExpr *x, GoASTExpr *type) - : GoASTExpr(eTypeAssertExpr), m_x_up(x), m_type_up(type) {} - ~GoASTTypeAssertExpr() override = default; - - const char *GetKindName() const override { return "TypeAssertExpr"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eTypeAssertExpr; - } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - - const GoASTExpr *GetType() const { return m_type_up.get(); } - void SetType(GoASTExpr *type) { m_type_up.reset(type); } - -private: - friend class GoASTNode; - std::unique_ptr m_x_up; - std::unique_ptr m_type_up; - - GoASTTypeAssertExpr(const GoASTTypeAssertExpr &) = delete; - const GoASTTypeAssertExpr &operator=(const GoASTTypeAssertExpr &) = delete; -}; - -class GoASTTypeSpec : public GoASTSpec { -public: - GoASTTypeSpec(GoASTIdent *name, GoASTExpr *type) - : GoASTSpec(eTypeSpec), m_name_up(name), m_type_up(type) {} - ~GoASTTypeSpec() override = default; - - const char *GetKindName() const override { return "TypeSpec"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eTypeSpec; } - - const GoASTIdent *GetName() const { return m_name_up.get(); } - void SetName(GoASTIdent *name) { m_name_up.reset(name); } - - const GoASTExpr *GetType() const { return m_type_up.get(); } - void SetType(GoASTExpr *type) { m_type_up.reset(type); } - -private: - friend class GoASTNode; - std::unique_ptr m_name_up; - std::unique_ptr m_type_up; - - GoASTTypeSpec(const GoASTTypeSpec &) = delete; - const GoASTTypeSpec &operator=(const GoASTTypeSpec &) = delete; -}; - -class GoASTTypeSwitchStmt : public GoASTStmt { -public: - GoASTTypeSwitchStmt(GoASTStmt *init, GoASTStmt *assign, GoASTBlockStmt *body) - : GoASTStmt(eTypeSwitchStmt), m_init_up(init), m_assign_up(assign), - m_body_up(body) {} - ~GoASTTypeSwitchStmt() override = default; - - const char *GetKindName() const override { return "TypeSwitchStmt"; } - - static bool classof(const GoASTNode *n) { - return n->GetKind() == eTypeSwitchStmt; - } - - const GoASTStmt *GetInit() const { return m_init_up.get(); } - void SetInit(GoASTStmt *init) { m_init_up.reset(init); } - - const GoASTStmt *GetAssign() const { return m_assign_up.get(); } - void SetAssign(GoASTStmt *assign) { m_assign_up.reset(assign); } - - const GoASTBlockStmt *GetBody() const { return m_body_up.get(); } - void SetBody(GoASTBlockStmt *body) { m_body_up.reset(body); } - -private: - friend class GoASTNode; - std::unique_ptr m_init_up; - std::unique_ptr m_assign_up; - std::unique_ptr m_body_up; - - GoASTTypeSwitchStmt(const GoASTTypeSwitchStmt &) = delete; - const GoASTTypeSwitchStmt &operator=(const GoASTTypeSwitchStmt &) = delete; -}; - -class GoASTUnaryExpr : public GoASTExpr { -public: - GoASTUnaryExpr(TokenType op, GoASTExpr *x) - : GoASTExpr(eUnaryExpr), m_op(op), m_x_up(x) {} - ~GoASTUnaryExpr() override = default; - - const char *GetKindName() const override { return "UnaryExpr"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eUnaryExpr; } - - TokenType GetOp() const { return m_op; } - void SetOp(TokenType op) { m_op = op; } - - const GoASTExpr *GetX() const { return m_x_up.get(); } - void SetX(GoASTExpr *x) { m_x_up.reset(x); } - -private: - friend class GoASTNode; - TokenType m_op; - std::unique_ptr m_x_up; - - GoASTUnaryExpr(const GoASTUnaryExpr &) = delete; - const GoASTUnaryExpr &operator=(const GoASTUnaryExpr &) = delete; -}; - -class GoASTValueSpec : public GoASTSpec { -public: - GoASTValueSpec() : GoASTSpec(eValueSpec) {} - ~GoASTValueSpec() override = default; - - const char *GetKindName() const override { return "ValueSpec"; } - - static bool classof(const GoASTNode *n) { return n->GetKind() == eValueSpec; } - - size_t NumNames() const { return m_names.size(); } - const GoASTIdent *GetNames(int i) const { return m_names[i].get(); } - void AddNames(GoASTIdent *names) { - m_names.push_back(std::unique_ptr(names)); - } - - const GoASTExpr *GetType() const { return m_type_up.get(); } - void SetType(GoASTExpr *type) { m_type_up.reset(type); } - - size_t NumValues() const { return m_values.size(); } - const GoASTExpr *GetValues(int i) const { return m_values[i].get(); } - void AddValues(GoASTExpr *values) { - m_values.push_back(std::unique_ptr(values)); - } - -private: - friend class GoASTNode; - std::vector> m_names; - std::unique_ptr m_type_up; - std::vector> m_values; - - GoASTValueSpec(const GoASTValueSpec &) = delete; - const GoASTValueSpec &operator=(const GoASTValueSpec &) = delete; -}; - -template R GoASTDecl::Visit(V *v) const { - switch (GetKind()) { - case eBadDecl: - return v->VisitBadDecl(llvm::cast(this)); - case eFuncDecl: - return v->VisitFuncDecl(llvm::cast(this)); - case eGenDecl: - return v->VisitGenDecl(llvm::cast(this)); - default: - assert(false && "Invalid kind"); - } -} - -template R GoASTExpr::Visit(V *v) const { - switch (GetKind()) { - case eArrayType: - return v->VisitArrayType(llvm::cast(this)); - case eBadExpr: - return v->VisitBadExpr(llvm::cast(this)); - case eBasicLit: - return v->VisitBasicLit(llvm::cast(this)); - case eBinaryExpr: - return v->VisitBinaryExpr(llvm::cast(this)); - case eIdent: - return v->VisitIdent(llvm::cast(this)); - case eCallExpr: - return v->VisitCallExpr(llvm::cast(this)); - case eChanType: - return v->VisitChanType(llvm::cast(this)); - case eCompositeLit: - return v->VisitCompositeLit(llvm::cast(this)); - case eEllipsis: - return v->VisitEllipsis(llvm::cast(this)); - case eFuncType: - return v->VisitFuncType(llvm::cast(this)); - case eFuncLit: - return v->VisitFuncLit(llvm::cast(this)); - case eIndexExpr: - return v->VisitIndexExpr(llvm::cast(this)); - case eInterfaceType: - return v->VisitInterfaceType(llvm::cast(this)); - case eKeyValueExpr: - return v->VisitKeyValueExpr(llvm::cast(this)); - case eMapType: - return v->VisitMapType(llvm::cast(this)); - case eParenExpr: - return v->VisitParenExpr(llvm::cast(this)); - case eSelectorExpr: - return v->VisitSelectorExpr(llvm::cast(this)); - case eSliceExpr: - return v->VisitSliceExpr(llvm::cast(this)); - case eStarExpr: - return v->VisitStarExpr(llvm::cast(this)); - case eStructType: - return v->VisitStructType(llvm::cast(this)); - case eTypeAssertExpr: - return v->VisitTypeAssertExpr(llvm::cast(this)); - case eUnaryExpr: - return v->VisitUnaryExpr(llvm::cast(this)); - default: - assert(false && "Invalid kind"); - return R(); - } -} - -template R GoASTSpec::Visit(V *v) const { - switch (GetKind()) { - case eImportSpec: - return v->VisitImportSpec(llvm::cast(this)); - case eTypeSpec: - return v->VisitTypeSpec(llvm::cast(this)); - case eValueSpec: - return v->VisitValueSpec(llvm::cast(this)); - default: - assert(false && "Invalid kind"); - } -} - -template R GoASTStmt::Visit(V *v) const { - switch (GetKind()) { - case eAssignStmt: - return v->VisitAssignStmt(llvm::cast(this)); - case eBadStmt: - return v->VisitBadStmt(llvm::cast(this)); - case eBlockStmt: - return v->VisitBlockStmt(llvm::cast(this)); - case eBranchStmt: - return v->VisitBranchStmt(llvm::cast(this)); - case eCaseClause: - return v->VisitCaseClause(llvm::cast(this)); - case eCommClause: - return v->VisitCommClause(llvm::cast(this)); - case eDeclStmt: - return v->VisitDeclStmt(llvm::cast(this)); - case eDeferStmt: - return v->VisitDeferStmt(llvm::cast(this)); - case eEmptyStmt: - return v->VisitEmptyStmt(llvm::cast(this)); - case eExprStmt: - return v->VisitExprStmt(llvm::cast(this)); - case eForStmt: - return v->VisitForStmt(llvm::cast(this)); - case eGoStmt: - return v->VisitGoStmt(llvm::cast(this)); - case eIfStmt: - return v->VisitIfStmt(llvm::cast(this)); - case eIncDecStmt: - return v->VisitIncDecStmt(llvm::cast(this)); - case eLabeledStmt: - return v->VisitLabeledStmt(llvm::cast(this)); - case eRangeStmt: - return v->VisitRangeStmt(llvm::cast(this)); - case eReturnStmt: - return v->VisitReturnStmt(llvm::cast(this)); - case eSelectStmt: - return v->VisitSelectStmt(llvm::cast(this)); - case eSendStmt: - return v->VisitSendStmt(llvm::cast(this)); - case eSwitchStmt: - return v->VisitSwitchStmt(llvm::cast(this)); - case eTypeSwitchStmt: - return v->VisitTypeSwitchStmt(llvm::cast(this)); - default: - assert(false && "Invalid kind"); - } -} - -template void GoASTNode::WalkChildren(V &v) { - switch (m_kind) { - - case eArrayType: { - GoASTArrayType *n = llvm::cast(this); - (void)n; - v(n->m_len_up.get()); - v(n->m_elt_up.get()); - return; - } - case eAssignStmt: { - GoASTAssignStmt *n = llvm::cast(this); - (void)n; - for (auto &e : n->m_lhs) { - v(e.get()); - } - for (auto &e : n->m_rhs) { - v(e.get()); - } - return; - } - case eBasicLit: { - GoASTBasicLit *n = llvm::cast(this); - (void)n; - return; - } - case eBinaryExpr: { - GoASTBinaryExpr *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - v(n->m_y_up.get()); - return; - } - case eBlockStmt: { - GoASTBlockStmt *n = llvm::cast(this); - (void)n; - for (auto &e : n->m_list) { - v(e.get()); - } - return; - } - case eIdent: { - GoASTIdent *n = llvm::cast(this); - (void)n; - return; - } - case eBranchStmt: { - GoASTBranchStmt *n = llvm::cast(this); - (void)n; - v(n->m_label_up.get()); - return; - } - case eCallExpr: { - GoASTCallExpr *n = llvm::cast(this); - (void)n; - v(n->m_fun_up.get()); - for (auto &e : n->m_args) { - v(e.get()); - } - return; - } - case eCaseClause: { - GoASTCaseClause *n = llvm::cast(this); - (void)n; - for (auto &e : n->m_list) { - v(e.get()); - } - for (auto &e : n->m_body) { - v(e.get()); - } - return; - } - case eChanType: { - GoASTChanType *n = llvm::cast(this); - (void)n; - v(n->m_value_up.get()); - return; - } - case eCommClause: { - GoASTCommClause *n = llvm::cast(this); - (void)n; - v(n->m_comm_up.get()); - for (auto &e : n->m_body) { - v(e.get()); - } - return; - } - case eCompositeLit: { - GoASTCompositeLit *n = llvm::cast(this); - (void)n; - v(n->m_type_up.get()); - for (auto &e : n->m_elts) { - v(e.get()); - } - return; - } - case eDeclStmt: { - GoASTDeclStmt *n = llvm::cast(this); - (void)n; - v(n->m_decl_up.get()); - return; - } - case eDeferStmt: { - GoASTDeferStmt *n = llvm::cast(this); - (void)n; - v(n->m_call_up.get()); - return; - } - case eEllipsis: { - GoASTEllipsis *n = llvm::cast(this); - (void)n; - v(n->m_elt_up.get()); - return; - } - case eExprStmt: { - GoASTExprStmt *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - return; - } - case eField: { - GoASTField *n = llvm::cast(this); - (void)n; - for (auto &e : n->m_names) { - v(e.get()); - } - v(n->m_type_up.get()); - v(n->m_tag_up.get()); - return; - } - case eFieldList: { - GoASTFieldList *n = llvm::cast(this); - (void)n; - for (auto &e : n->m_list) { - v(e.get()); - } - return; - } - case eForStmt: { - GoASTForStmt *n = llvm::cast(this); - (void)n; - v(n->m_init_up.get()); - v(n->m_cond_up.get()); - v(n->m_post_up.get()); - v(n->m_body_up.get()); - return; - } - case eFuncType: { - GoASTFuncType *n = llvm::cast(this); - (void)n; - v(n->m_params_up.get()); - v(n->m_results_up.get()); - return; - } - case eFuncDecl: { - GoASTFuncDecl *n = llvm::cast(this); - (void)n; - v(n->m_recv_up.get()); - v(n->m_name_up.get()); - v(n->m_type_up.get()); - v(n->m_body_up.get()); - return; - } - case eFuncLit: { - GoASTFuncLit *n = llvm::cast(this); - (void)n; - v(n->m_type_up.get()); - v(n->m_body_up.get()); - return; - } - case eGenDecl: { - GoASTGenDecl *n = llvm::cast(this); - (void)n; - for (auto &e : n->m_specs) { - v(e.get()); - } - return; - } - case eGoStmt: { - GoASTGoStmt *n = llvm::cast(this); - (void)n; - v(n->m_call_up.get()); - return; - } - case eIfStmt: { - GoASTIfStmt *n = llvm::cast(this); - (void)n; - v(n->m_init_up.get()); - v(n->m_cond_up.get()); - v(n->m_body_up.get()); - v(n->m_els_up.get()); - return; - } - case eImportSpec: { - GoASTImportSpec *n = llvm::cast(this); - (void)n; - v(n->m_name_up.get()); - v(n->m_path_up.get()); - return; - } - case eIncDecStmt: { - GoASTIncDecStmt *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - return; - } - case eIndexExpr: { - GoASTIndexExpr *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - v(n->m_index_up.get()); - return; - } - case eInterfaceType: { - GoASTInterfaceType *n = llvm::cast(this); - (void)n; - v(n->m_methods_up.get()); - return; - } - case eKeyValueExpr: { - GoASTKeyValueExpr *n = llvm::cast(this); - (void)n; - v(n->m_key_up.get()); - v(n->m_value_up.get()); - return; - } - case eLabeledStmt: { - GoASTLabeledStmt *n = llvm::cast(this); - (void)n; - v(n->m_label_up.get()); - v(n->m_stmt_up.get()); - return; - } - case eMapType: { - GoASTMapType *n = llvm::cast(this); - (void)n; - v(n->m_key_up.get()); - v(n->m_value_up.get()); - return; - } - case eParenExpr: { - GoASTParenExpr *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - return; - } - case eRangeStmt: { - GoASTRangeStmt *n = llvm::cast(this); - (void)n; - v(n->m_key_up.get()); - v(n->m_value_up.get()); - v(n->m_x_up.get()); - v(n->m_body_up.get()); - return; - } - case eReturnStmt: { - GoASTReturnStmt *n = llvm::cast(this); - (void)n; - for (auto &e : n->m_results) { - v(e.get()); - } - return; - } - case eSelectStmt: { - GoASTSelectStmt *n = llvm::cast(this); - (void)n; - v(n->m_body_up.get()); - return; - } - case eSelectorExpr: { - GoASTSelectorExpr *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - v(n->m_sel_up.get()); - return; - } - case eSendStmt: { - GoASTSendStmt *n = llvm::cast(this); - (void)n; - v(n->m_chan_up.get()); - v(n->m_value_up.get()); - return; - } - case eSliceExpr: { - GoASTSliceExpr *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - v(n->m_low_up.get()); - v(n->m_high_up.get()); - v(n->m_max_up.get()); - return; - } - case eStarExpr: { - GoASTStarExpr *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - return; - } - case eStructType: { - GoASTStructType *n = llvm::cast(this); - (void)n; - v(n->m_fields_up.get()); - return; - } - case eSwitchStmt: { - GoASTSwitchStmt *n = llvm::cast(this); - (void)n; - v(n->m_init_up.get()); - v(n->m_tag_up.get()); - v(n->m_body_up.get()); - return; - } - case eTypeAssertExpr: { - GoASTTypeAssertExpr *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - v(n->m_type_up.get()); - return; - } - case eTypeSpec: { - GoASTTypeSpec *n = llvm::cast(this); - (void)n; - v(n->m_name_up.get()); - v(n->m_type_up.get()); - return; - } - case eTypeSwitchStmt: { - GoASTTypeSwitchStmt *n = llvm::cast(this); - (void)n; - v(n->m_init_up.get()); - v(n->m_assign_up.get()); - v(n->m_body_up.get()); - return; - } - case eUnaryExpr: { - GoASTUnaryExpr *n = llvm::cast(this); - (void)n; - v(n->m_x_up.get()); - return; - } - case eValueSpec: { - GoASTValueSpec *n = llvm::cast(this); - (void)n; - for (auto &e : n->m_names) { - v(e.get()); - } - v(n->m_type_up.get()); - for (auto &e : n->m_values) { - v(e.get()); - } - return; - } - - case eEmptyStmt: - case eBadDecl: - case eBadExpr: - case eBadStmt: - break; - } -} - -} // namespace lldb_private - -#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoLexer.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoLexer.cpp deleted file mode 100644 index 63e267eaadc2..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoLexer.cpp +++ /dev/null @@ -1,350 +0,0 @@ -//===-- GoLexer.cpp ---------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include - -#include "GoLexer.h" - -using namespace lldb_private; - -llvm::StringMap *GoLexer::m_keywords; - -GoLexer::GoLexer(const char *src) - : m_src(src), m_end(src + strlen(src)), m_last_token(TOK_INVALID, "") {} - -bool GoLexer::SkipWhitespace() { - bool saw_newline = false; - for (; m_src < m_end; ++m_src) { - if (*m_src == '\n') - saw_newline = true; - if (*m_src == '/' && !SkipComment()) - return saw_newline; - else if (!IsWhitespace(*m_src)) - return saw_newline; - } - return saw_newline; -} - -bool GoLexer::SkipComment() { - if (m_src[0] == '/' && m_src[1] == '/') { - for (const char *c = m_src + 2; c < m_end; ++c) { - if (*c == '\n') { - m_src = c - 1; - return true; - } - } - return true; - } else if (m_src[0] == '/' && m_src[1] == '*') { - for (const char *c = m_src + 2; c < m_end; ++c) { - if (c[0] == '*' && c[1] == '/') { - m_src = c + 1; - return true; - } - } - } - return false; -} - -const GoLexer::Token &GoLexer::Lex() { - bool newline = SkipWhitespace(); - const char *start = m_src; - m_last_token.m_type = InternalLex(newline); - m_last_token.m_value = llvm::StringRef(start, m_src - start); - return m_last_token; -} - -GoLexer::TokenType GoLexer::InternalLex(bool newline) { - if (m_src >= m_end) { - return TOK_EOF; - } - if (newline) { - switch (m_last_token.m_type) { - case TOK_IDENTIFIER: - case LIT_FLOAT: - case LIT_IMAGINARY: - case LIT_INTEGER: - case LIT_RUNE: - case LIT_STRING: - case KEYWORD_BREAK: - case KEYWORD_CONTINUE: - case KEYWORD_FALLTHROUGH: - case KEYWORD_RETURN: - case OP_PLUS_PLUS: - case OP_MINUS_MINUS: - case OP_RPAREN: - case OP_RBRACK: - case OP_RBRACE: - return OP_SEMICOLON; - default: - break; - } - } - char c = *m_src; - switch (c) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return DoNumber(); - case '+': - case '-': - case '*': - case '/': - case '%': - case '&': - case '|': - case '^': - case '<': - case '>': - case '!': - case ':': - case ';': - case '(': - case ')': - case '[': - case ']': - case '{': - case '}': - case ',': - case '=': - return DoOperator(); - case '.': - if (IsDecimal(m_src[1])) - return DoNumber(); - return DoOperator(); - case '$': - // For lldb persistent vars. - return DoIdent(); - case '"': - case '`': - return DoString(); - case '\'': - return DoRune(); - default: - break; - } - if (IsLetterOrDigit(c)) - return DoIdent(); - ++m_src; - return TOK_INVALID; -} - -GoLexer::TokenType GoLexer::DoOperator() { - TokenType t = TOK_INVALID; - if (m_end - m_src > 2) { - t = LookupKeyword(llvm::StringRef(m_src, 3)); - if (t != TOK_INVALID) - m_src += 3; - } - if (t == TOK_INVALID && m_end - m_src > 1) { - t = LookupKeyword(llvm::StringRef(m_src, 2)); - if (t != TOK_INVALID) - m_src += 2; - } - if (t == TOK_INVALID) { - t = LookupKeyword(llvm::StringRef(m_src, 1)); - ++m_src; - } - return t; -} - -GoLexer::TokenType GoLexer::DoIdent() { - const char *start = m_src++; - while (m_src < m_end && IsLetterOrDigit(*m_src)) { - ++m_src; - } - TokenType kw = LookupKeyword(llvm::StringRef(start, m_src - start)); - if (kw != TOK_INVALID) - return kw; - return TOK_IDENTIFIER; -} - -GoLexer::TokenType GoLexer::DoNumber() { - if (m_src[0] == '0' && (m_src[1] == 'x' || m_src[1] == 'X')) { - m_src += 2; - while (IsHexChar(*m_src)) - ++m_src; - return LIT_INTEGER; - } - bool dot_ok = true; - bool e_ok = true; - while (true) { - while (IsDecimal(*m_src)) - ++m_src; - switch (*m_src) { - case 'i': - ++m_src; - return LIT_IMAGINARY; - case '.': - if (!dot_ok) - return LIT_FLOAT; - ++m_src; - dot_ok = false; - break; - case 'e': - case 'E': - if (!e_ok) - return LIT_FLOAT; - dot_ok = e_ok = false; - ++m_src; - if (*m_src == '+' || *m_src == '-') - ++m_src; - break; - default: - if (dot_ok) - return LIT_INTEGER; - return LIT_FLOAT; - } - } -} - -GoLexer::TokenType GoLexer::DoRune() { - while (++m_src < m_end) { - switch (*m_src) { - case '\'': - ++m_src; - return LIT_RUNE; - case '\n': - return TOK_INVALID; - case '\\': - if (m_src[1] == '\n') - return TOK_INVALID; - ++m_src; - } - } - return TOK_INVALID; -} - -GoLexer::TokenType GoLexer::DoString() { - if (*m_src == '`') { - while (++m_src < m_end) { - if (*m_src == '`') { - ++m_src; - return LIT_STRING; - } - } - return TOK_INVALID; - } - while (++m_src < m_end) { - switch (*m_src) { - case '"': - ++m_src; - return LIT_STRING; - case '\n': - return TOK_INVALID; - case '\\': - if (m_src[1] == '\n') - return TOK_INVALID; - ++m_src; - } - } - return TOK_INVALID; -} - -GoLexer::TokenType GoLexer::LookupKeyword(llvm::StringRef id) { - if (m_keywords == nullptr) - m_keywords = InitKeywords(); - const auto &it = m_keywords->find(id); - if (it == m_keywords->end()) - return TOK_INVALID; - return it->second; -} - -llvm::StringRef GoLexer::LookupToken(TokenType t) { - if (m_keywords == nullptr) - m_keywords = InitKeywords(); - for (const auto &e : *m_keywords) { - if (e.getValue() == t) - return e.getKey(); - } - return ""; -} - -llvm::StringMap *GoLexer::InitKeywords() { - auto &result = *new llvm::StringMap(128); - result["break"] = KEYWORD_BREAK; - result["default"] = KEYWORD_DEFAULT; - result["func"] = KEYWORD_FUNC; - result["interface"] = KEYWORD_INTERFACE; - result["select"] = KEYWORD_SELECT; - result["case"] = KEYWORD_CASE; - result["defer"] = KEYWORD_DEFER; - result["go"] = KEYWORD_GO; - result["map"] = KEYWORD_MAP; - result["struct"] = KEYWORD_STRUCT; - result["chan"] = KEYWORD_CHAN; - result["else"] = KEYWORD_ELSE; - result["goto"] = KEYWORD_GOTO; - result["package"] = KEYWORD_PACKAGE; - result["switch"] = KEYWORD_SWITCH; - result["const"] = KEYWORD_CONST; - result["fallthrough"] = KEYWORD_FALLTHROUGH; - result["if"] = KEYWORD_IF; - result["range"] = KEYWORD_RANGE; - result["type"] = KEYWORD_TYPE; - result["continue"] = KEYWORD_CONTINUE; - result["for"] = KEYWORD_FOR; - result["import"] = KEYWORD_IMPORT; - result["return"] = KEYWORD_RETURN; - result["var"] = KEYWORD_VAR; - result["+"] = OP_PLUS; - result["-"] = OP_MINUS; - result["*"] = OP_STAR; - result["/"] = OP_SLASH; - result["%"] = OP_PERCENT; - result["&"] = OP_AMP; - result["|"] = OP_PIPE; - result["^"] = OP_CARET; - result["<<"] = OP_LSHIFT; - result[">>"] = OP_RSHIFT; - result["&^"] = OP_AMP_CARET; - result["+="] = OP_PLUS_EQ; - result["-="] = OP_MINUS_EQ; - result["*="] = OP_STAR_EQ; - result["/="] = OP_SLASH_EQ; - result["%="] = OP_PERCENT_EQ; - result["&="] = OP_AMP_EQ; - result["|="] = OP_PIPE_EQ; - result["^="] = OP_CARET_EQ; - result["<<="] = OP_LSHIFT_EQ; - result[">>="] = OP_RSHIFT_EQ; - result["&^="] = OP_AMP_CARET_EQ; - result["&&"] = OP_AMP_AMP; - result["||"] = OP_PIPE_PIPE; - result["<-"] = OP_LT_MINUS; - result["++"] = OP_PLUS_PLUS; - result["--"] = OP_MINUS_MINUS; - result["=="] = OP_EQ_EQ; - result["<"] = OP_LT; - result[">"] = OP_GT; - result["="] = OP_EQ; - result["!"] = OP_BANG; - result["!="] = OP_BANG_EQ; - result["<="] = OP_LT_EQ; - result[">="] = OP_GT_EQ; - result[":="] = OP_COLON_EQ; - result["..."] = OP_DOTS; - result["("] = OP_LPAREN; - result["["] = OP_LBRACK; - result["{"] = OP_LBRACE; - result[","] = OP_COMMA; - result["."] = OP_DOT; - result[")"] = OP_RPAREN; - result["]"] = OP_RBRACK; - result["}"] = OP_RBRACE; - result[";"] = OP_SEMICOLON; - result[":"] = OP_COLON; - return &result; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoLexer.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoLexer.h deleted file mode 100644 index f0b5b336fbe9..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoLexer.h +++ /dev/null @@ -1,181 +0,0 @@ -//===-- GoLexer.h -----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_GoLexer_h -#define liblldb_GoLexer_h - -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" - -namespace lldb_private { - -class GoLexer { -public: - explicit GoLexer(const char *src); - - enum TokenType { - TOK_EOF, - TOK_INVALID, - TOK_IDENTIFIER, - LIT_INTEGER, - LIT_FLOAT, - LIT_IMAGINARY, - LIT_RUNE, - LIT_STRING, - KEYWORD_BREAK, - KEYWORD_DEFAULT, - KEYWORD_FUNC, - KEYWORD_INTERFACE, - KEYWORD_SELECT, - KEYWORD_CASE, - KEYWORD_DEFER, - KEYWORD_GO, - KEYWORD_MAP, - KEYWORD_STRUCT, - KEYWORD_CHAN, - KEYWORD_ELSE, - KEYWORD_GOTO, - KEYWORD_PACKAGE, - KEYWORD_SWITCH, - KEYWORD_CONST, - KEYWORD_FALLTHROUGH, - KEYWORD_IF, - KEYWORD_RANGE, - KEYWORD_TYPE, - KEYWORD_CONTINUE, - KEYWORD_FOR, - KEYWORD_IMPORT, - KEYWORD_RETURN, - KEYWORD_VAR, - OP_PLUS, - OP_MINUS, - OP_STAR, - OP_SLASH, - OP_PERCENT, - OP_AMP, - OP_PIPE, - OP_CARET, - OP_LSHIFT, - OP_RSHIFT, - OP_AMP_CARET, - OP_PLUS_EQ, - OP_MINUS_EQ, - OP_STAR_EQ, - OP_SLASH_EQ, - OP_PERCENT_EQ, - OP_AMP_EQ, - OP_PIPE_EQ, - OP_CARET_EQ, - OP_LSHIFT_EQ, - OP_RSHIFT_EQ, - OP_AMP_CARET_EQ, - OP_AMP_AMP, - OP_PIPE_PIPE, - OP_LT_MINUS, - OP_PLUS_PLUS, - OP_MINUS_MINUS, - OP_EQ_EQ, - OP_LT, - OP_GT, - OP_EQ, - OP_BANG, - OP_BANG_EQ, - OP_LT_EQ, - OP_GT_EQ, - OP_COLON_EQ, - OP_DOTS, - OP_LPAREN, - OP_LBRACK, - OP_LBRACE, - OP_COMMA, - OP_DOT, - OP_RPAREN, - OP_RBRACK, - OP_RBRACE, - OP_SEMICOLON, - OP_COLON, - }; - - struct Token { - explicit Token(TokenType t, llvm::StringRef text) - : m_type(t), m_value(text) {} - TokenType m_type; - llvm::StringRef m_value; - }; - - const Token &Lex(); - - size_t BytesRemaining() const { return m_end - m_src; } - llvm::StringRef GetString(int len) const { - return llvm::StringRef(m_src, len); - } - - static TokenType LookupKeyword(llvm::StringRef id); - static llvm::StringRef LookupToken(TokenType t); - -private: - bool IsDecimal(char c) { return c >= '0' && c <= '9'; } - bool IsHexChar(char c) { - if (c >= '0' && c <= '9') - return true; - if (c >= 'A' && c <= 'F') - return true; - if (c >= 'a' && c <= 'f') - return true; - return false; - } - bool IsLetterOrDigit(char c) { - if (c >= 'a' && c <= 'z') - return true; - if (c >= 'A' && c <= 'Z') - return true; - if (c == '_') - return true; - if (c >= '0' && c <= '9') - return true; - // Treat all non-ascii chars as letters for simplicity. - return 0 != (c & 0x80); - } - bool IsWhitespace(char c) { - switch (c) { - case ' ': - case '\t': - case '\r': - return true; - } - return false; - } - - bool SkipWhitespace(); - bool SkipComment(); - - TokenType InternalLex(bool newline); - - TokenType DoOperator(); - - TokenType DoIdent(); - - TokenType DoNumber(); - - TokenType DoRune(); - - TokenType DoString(); - - static llvm::StringMap *InitKeywords(); - - static llvm::StringMap *m_keywords; - - const char *m_src; - const char *m_end; - Token m_last_token; -}; - -} // namespace lldb_private - -#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp deleted file mode 100644 index 9c845d02bca0..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.cpp +++ /dev/null @@ -1,886 +0,0 @@ -//===-- GoParser.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include - -#include "GoParser.h" - -#include "Plugins/ExpressionParser/Go/GoAST.h" -#include "lldb/Utility/Status.h" -#include "llvm/ADT/SmallString.h" - -using namespace lldb_private; -using namespace lldb; - -namespace { -llvm::StringRef DescribeToken(GoLexer::TokenType t) { - switch (t) { - case GoLexer::TOK_EOF: - return ""; - case GoLexer::TOK_IDENTIFIER: - return "identifier"; - case GoLexer::LIT_FLOAT: - return "float"; - case GoLexer::LIT_IMAGINARY: - return "imaginary"; - case GoLexer::LIT_INTEGER: - return "integer"; - case GoLexer::LIT_RUNE: - return "rune"; - case GoLexer::LIT_STRING: - return "string"; - default: - return GoLexer::LookupToken(t); - } -} -} // namespace - -class GoParser::Rule { -public: - Rule(llvm::StringRef name, GoParser *p) - : m_name(name), m_parser(p), m_pos(p->m_pos) {} - - std::nullptr_t error() { - if (!m_parser->m_failed) { - // Set m_error in case this is the top level. - if (m_parser->m_last_tok == GoLexer::TOK_INVALID) - m_parser->m_error = m_parser->m_last; - else - m_parser->m_error = DescribeToken(m_parser->m_last_tok); - // And set m_last in case it isn't. - m_parser->m_last = m_name; - m_parser->m_last_tok = GoLexer::TOK_INVALID; - m_parser->m_pos = m_pos; - } - return nullptr; - } - -private: - llvm::StringRef m_name; - GoParser *m_parser; - size_t m_pos; -}; - -GoParser::GoParser(const char *src) - : m_lexer(src), m_pos(0), m_last_tok(GoLexer::TOK_INVALID), - m_failed(false) {} - -GoASTStmt *GoParser::Statement() { - Rule r("Statement", this); - GoLexer::TokenType t = peek(); - GoASTStmt *ret = nullptr; - switch (t) { - case GoLexer::TOK_EOF: - case GoLexer::OP_SEMICOLON: - case GoLexer::OP_RPAREN: - case GoLexer::OP_RBRACE: - case GoLexer::TOK_INVALID: - return EmptyStmt(); - case GoLexer::OP_LBRACE: - return Block(); - - /* TODO: -case GoLexer::KEYWORD_GO: - return GoStmt(); -case GoLexer::KEYWORD_RETURN: - return ReturnStmt(); -case GoLexer::KEYWORD_BREAK: -case GoLexer::KEYWORD_CONTINUE: -case GoLexer::KEYWORD_GOTO: -case GoLexer::KEYWORD_FALLTHROUGH: - return BranchStmt(); -case GoLexer::KEYWORD_IF: - return IfStmt(); -case GoLexer::KEYWORD_SWITCH: - return SwitchStmt(); -case GoLexer::KEYWORD_SELECT: - return SelectStmt(); -case GoLexer::KEYWORD_FOR: - return ForStmt(); -case GoLexer::KEYWORD_DEFER: - return DeferStmt(); -case GoLexer::KEYWORD_CONST: -case GoLexer::KEYWORD_TYPE: -case GoLexer::KEYWORD_VAR: - return DeclStmt(); -case GoLexer::TOK_IDENTIFIER: - if ((ret = LabeledStmt()) || - (ret = ShortVarDecl())) - { - return ret; - } -*/ - default: - break; - } - GoASTExpr *expr = Expression(); - if (expr == nullptr) - return r.error(); - if (/*(ret = SendStmt(expr)) ||*/ - (ret = IncDecStmt(expr)) || (ret = Assignment(expr)) || - (ret = ExpressionStmt(expr))) { - return ret; - } - delete expr; - return r.error(); -} - -GoASTStmt *GoParser::ExpressionStmt(GoASTExpr *e) { - if (Semicolon()) - return new GoASTExprStmt(e); - return nullptr; -} - -GoASTStmt *GoParser::IncDecStmt(GoASTExpr *e) { - Rule r("IncDecStmt", this); - if (match(GoLexer::OP_PLUS_PLUS)) - return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_PLUS_PLUS) - : r.error(); - if (match(GoLexer::OP_MINUS_MINUS)) - return Semicolon() ? new GoASTIncDecStmt(e, GoLexer::OP_MINUS_MINUS) - : r.error(); - return nullptr; -} - -GoASTStmt *GoParser::Assignment(lldb_private::GoASTExpr *e) { - Rule r("Assignment", this); - std::vector> lhs; - for (GoASTExpr *l = MoreExpressionList(); l; l = MoreExpressionList()) - lhs.push_back(std::unique_ptr(l)); - switch (peek()) { - case GoLexer::OP_EQ: - case GoLexer::OP_PLUS_EQ: - case GoLexer::OP_MINUS_EQ: - case GoLexer::OP_PIPE_EQ: - case GoLexer::OP_CARET_EQ: - case GoLexer::OP_STAR_EQ: - case GoLexer::OP_SLASH_EQ: - case GoLexer::OP_PERCENT_EQ: - case GoLexer::OP_LSHIFT_EQ: - case GoLexer::OP_RSHIFT_EQ: - case GoLexer::OP_AMP_EQ: - case GoLexer::OP_AMP_CARET_EQ: - break; - default: - return r.error(); - } - // We don't want to own e until we know this is an assignment. - std::unique_ptr stmt(new GoASTAssignStmt(false)); - stmt->AddLhs(e); - for (auto &l : lhs) - stmt->AddLhs(l.release()); - for (GoASTExpr *r = Expression(); r; r = MoreExpressionList()) - stmt->AddRhs(r); - if (!Semicolon() || stmt->NumRhs() == 0) - return new GoASTBadStmt; - return stmt.release(); -} - -GoASTStmt *GoParser::EmptyStmt() { - if (match(GoLexer::TOK_EOF)) - return nullptr; - if (Semicolon()) - return new GoASTEmptyStmt; - return nullptr; -} - -GoASTStmt *GoParser::GoStmt() { - if (match(GoLexer::KEYWORD_GO)) { - if (GoASTCallExpr *e = - llvm::dyn_cast_or_null(Expression())) { - return FinishStmt(new GoASTGoStmt(e)); - } - m_last = "call expression"; - m_failed = true; - return new GoASTBadStmt(); - } - return nullptr; -} - -GoASTStmt *GoParser::ReturnStmt() { - if (match(GoLexer::KEYWORD_RETURN)) { - std::unique_ptr r(new GoASTReturnStmt()); - for (GoASTExpr *e = Expression(); e; e = MoreExpressionList()) - r->AddResults(e); - return FinishStmt(r.release()); - } - return nullptr; -} - -GoASTStmt *GoParser::BranchStmt() { - GoLexer::Token *tok; - if ((tok = match(GoLexer::KEYWORD_BREAK)) || - (tok = match(GoLexer::KEYWORD_CONTINUE)) || - (tok = match(GoLexer::KEYWORD_GOTO))) { - auto *e = Identifier(); - if (tok->m_type == GoLexer::KEYWORD_GOTO && !e) - return syntaxerror(); - return FinishStmt(new GoASTBranchStmt(e, tok->m_type)); - } - if ((tok = match(GoLexer::KEYWORD_FALLTHROUGH))) - return FinishStmt(new GoASTBranchStmt(nullptr, tok->m_type)); - - return nullptr; -} - -GoASTIdent *GoParser::Identifier() { - if (auto *tok = match(GoLexer::TOK_IDENTIFIER)) - return new GoASTIdent(*tok); - return nullptr; -} - -GoASTExpr *GoParser::MoreExpressionList() { - if (match(GoLexer::OP_COMMA)) { - auto *e = Expression(); - if (!e) - return syntaxerror(); - return e; - } - return nullptr; -} - -GoASTIdent *GoParser::MoreIdentifierList() { - if (match(GoLexer::OP_COMMA)) { - auto *i = Identifier(); - if (!i) - return syntaxerror(); - return i; - } - return nullptr; -} - -GoASTExpr *GoParser::Expression() { - Rule r("Expression", this); - if (GoASTExpr *ret = OrExpr()) - return ret; - return r.error(); -} - -GoASTExpr *GoParser::UnaryExpr() { - switch (peek()) { - case GoLexer::OP_PLUS: - case GoLexer::OP_MINUS: - case GoLexer::OP_BANG: - case GoLexer::OP_CARET: - case GoLexer::OP_STAR: - case GoLexer::OP_AMP: - case GoLexer::OP_LT_MINUS: { - const GoLexer::Token t = next(); - if (GoASTExpr *e = UnaryExpr()) { - if (t.m_type == GoLexer::OP_STAR) - return new GoASTStarExpr(e); - else - return new GoASTUnaryExpr(t.m_type, e); - } - return syntaxerror(); - } - default: - return PrimaryExpr(); - } -} - -GoASTExpr *GoParser::OrExpr() { - std::unique_ptr l(AndExpr()); - if (l) { - while (match(GoLexer::OP_PIPE_PIPE)) { - GoASTExpr *r = AndExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_PIPE_PIPE)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::AndExpr() { - std::unique_ptr l(RelExpr()); - if (l) { - while (match(GoLexer::OP_AMP_AMP)) { - GoASTExpr *r = RelExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, GoLexer::OP_AMP_AMP)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::RelExpr() { - std::unique_ptr l(AddExpr()); - if (l) { - for (GoLexer::Token *t; - (t = match(GoLexer::OP_EQ_EQ)) || (t = match(GoLexer::OP_BANG_EQ)) || - (t = match(GoLexer::OP_LT)) || (t = match(GoLexer::OP_LT_EQ)) || - (t = match(GoLexer::OP_GT)) || (t = match(GoLexer::OP_GT_EQ));) { - GoLexer::TokenType op = t->m_type; - GoASTExpr *r = AddExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, op)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::AddExpr() { - std::unique_ptr l(MulExpr()); - if (l) { - for (GoLexer::Token *t; - (t = match(GoLexer::OP_PLUS)) || (t = match(GoLexer::OP_MINUS)) || - (t = match(GoLexer::OP_PIPE)) || (t = match(GoLexer::OP_CARET));) { - GoLexer::TokenType op = t->m_type; - GoASTExpr *r = MulExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, op)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::MulExpr() { - std::unique_ptr l(UnaryExpr()); - if (l) { - for (GoLexer::Token *t; - (t = match(GoLexer::OP_STAR)) || (t = match(GoLexer::OP_SLASH)) || - (t = match(GoLexer::OP_PERCENT)) || (t = match(GoLexer::OP_LSHIFT)) || - (t = match(GoLexer::OP_RSHIFT)) || (t = match(GoLexer::OP_AMP)) || - (t = match(GoLexer::OP_AMP_CARET));) { - GoLexer::TokenType op = t->m_type; - GoASTExpr *r = UnaryExpr(); - if (r) - l.reset(new GoASTBinaryExpr(l.release(), r, op)); - else - return syntaxerror(); - } - return l.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::PrimaryExpr() { - GoASTExpr *l; - GoASTExpr *r; - (l = Conversion()) || (l = Operand()); - if (!l) - return nullptr; - while ((r = Selector(l)) || (r = IndexOrSlice(l)) || (r = TypeAssertion(l)) || - (r = Arguments(l))) { - l = r; - } - return l; -} - -GoASTExpr *GoParser::Operand() { - GoLexer::Token *lit; - if ((lit = match(GoLexer::LIT_INTEGER)) || - (lit = match(GoLexer::LIT_FLOAT)) || - (lit = match(GoLexer::LIT_IMAGINARY)) || - (lit = match(GoLexer::LIT_RUNE)) || (lit = match(GoLexer::LIT_STRING))) - return new GoASTBasicLit(*lit); - if (match(GoLexer::OP_LPAREN)) { - GoASTExpr *e; - if (!((e = Expression()) && match(GoLexer::OP_RPAREN))) - return syntaxerror(); - return e; - } - // MethodExpr should be handled by Selector - if (GoASTExpr *e = CompositeLit()) - return e; - if (GoASTExpr *n = Name()) - return n; - return FunctionLit(); -} - -GoASTExpr *GoParser::FunctionLit() { - if (!match(GoLexer::KEYWORD_FUNC)) - return nullptr; - auto *sig = Signature(); - if (!sig) - return syntaxerror(); - auto *body = Block(); - if (!body) { - delete sig; - return syntaxerror(); - } - return new GoASTFuncLit(sig, body); -} - -GoASTBlockStmt *GoParser::Block() { - if (!match(GoLexer::OP_LBRACE)) - return nullptr; - std::unique_ptr block(new GoASTBlockStmt); - for (auto *s = Statement(); s; s = Statement()) - block->AddList(s); - if (!match(GoLexer::OP_RBRACE)) - return syntaxerror(); - return block.release(); -} - -GoASTExpr *GoParser::CompositeLit() { - Rule r("CompositeLit", this); - GoASTExpr *type; - (type = StructType()) || (type = ArrayOrSliceType(true)) || - (type = MapType()) || (type = Name()); - if (!type) - return r.error(); - GoASTCompositeLit *lit = LiteralValue(); - if (!lit) { - delete type; - return r.error(); - } - lit->SetType(type); - return lit; -} - -GoASTCompositeLit *GoParser::LiteralValue() { - if (!match(GoLexer::OP_LBRACE)) - return nullptr; - std::unique_ptr lit(new GoASTCompositeLit); - for (GoASTExpr *e = Element(); e; e = Element()) { - lit->AddElts(e); - if (!match(GoLexer::OP_COMMA)) - break; - } - if (!mustMatch(GoLexer::OP_RBRACE)) - return nullptr; - return lit.release(); -} - -GoASTExpr *GoParser::Element() { - GoASTExpr *key; - if (!((key = Expression()) || (key = LiteralValue()))) - return nullptr; - if (!match(GoLexer::OP_COLON)) - return key; - GoASTExpr *value; - if ((value = Expression()) || (value = LiteralValue())) - return new GoASTKeyValueExpr(key, value); - delete key; - return syntaxerror(); -} - -GoASTExpr *GoParser::Selector(GoASTExpr *e) { - Rule r("Selector", this); - if (match(GoLexer::OP_DOT)) { - if (auto *name = Identifier()) - return new GoASTSelectorExpr(e, name); - } - return r.error(); -} - -GoASTExpr *GoParser::IndexOrSlice(GoASTExpr *e) { - Rule r("IndexOrSlice", this); - if (match(GoLexer::OP_LBRACK)) { - std::unique_ptr i1(Expression()), i2, i3; - bool slice = false; - if (match(GoLexer::OP_COLON)) { - slice = true; - i2.reset(Expression()); - if (i2 && match(GoLexer::OP_COLON)) { - i3.reset(Expression()); - if (!i3) - return syntaxerror(); - } - } - if (!(slice || i1)) - return syntaxerror(); - if (!mustMatch(GoLexer::OP_RBRACK)) - return nullptr; - if (slice) { - bool slice3 = i3.get(); - return new GoASTSliceExpr(e, i1.release(), i2.release(), i3.release(), - slice3); - } - return new GoASTIndexExpr(e, i1.release()); - } - return r.error(); -} - -GoASTExpr *GoParser::TypeAssertion(GoASTExpr *e) { - Rule r("TypeAssertion", this); - if (match(GoLexer::OP_DOT) && match(GoLexer::OP_LPAREN)) { - if (auto *t = Type()) { - if (!mustMatch(GoLexer::OP_RPAREN)) - return nullptr; - return new GoASTTypeAssertExpr(e, t); - } - return syntaxerror(); - } - return r.error(); -} - -GoASTExpr *GoParser::Arguments(GoASTExpr *e) { - if (match(GoLexer::OP_LPAREN)) { - std::unique_ptr call(new GoASTCallExpr(false)); - GoASTExpr *arg; - // ( ExpressionList | Type [ "," ExpressionList ] ) - for ((arg = Expression()) || (arg = Type()); arg; - arg = MoreExpressionList()) { - call->AddArgs(arg); - } - if (match(GoLexer::OP_DOTS)) - call->SetEllipsis(true); - - // Eat trailing comma - match(GoLexer::OP_COMMA); - - if (!mustMatch(GoLexer::OP_RPAREN)) - return nullptr; - call->SetFun(e); - return call.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::Conversion() { - Rule r("Conversion", this); - if (GoASTExpr *t = Type2()) { - std::unique_ptr owner(t); - if (match(GoLexer::OP_LPAREN)) { - GoASTExpr *v = Expression(); - if (!v) - return syntaxerror(); - match(GoLexer::OP_COMMA); - if (!mustMatch(GoLexer::OP_RPAREN)) - return r.error(); - GoASTCallExpr *call = new GoASTCallExpr(false); - call->SetFun(t); - owner.release(); - call->AddArgs(v); - return call; - } - } - return r.error(); -} - -GoASTExpr *GoParser::Type2() { - switch (peek()) { - case GoLexer::OP_LBRACK: - return ArrayOrSliceType(false); - case GoLexer::KEYWORD_STRUCT: - return StructType(); - case GoLexer::KEYWORD_FUNC: - return FunctionType(); - case GoLexer::KEYWORD_INTERFACE: - return InterfaceType(); - case GoLexer::KEYWORD_MAP: - return MapType(); - case GoLexer::KEYWORD_CHAN: - return ChanType2(); - default: - return nullptr; - } -} - -GoASTExpr *GoParser::ArrayOrSliceType(bool allowEllipsis) { - Rule r("ArrayType", this); - if (match(GoLexer::OP_LBRACK)) { - std::unique_ptr len; - if (allowEllipsis && match(GoLexer::OP_DOTS)) { - len.reset(new GoASTEllipsis(nullptr)); - } else { - len.reset(Expression()); - } - - if (!match(GoLexer::OP_RBRACK)) - return r.error(); - GoASTExpr *elem = Type(); - if (!elem) - return syntaxerror(); - return new GoASTArrayType(len.release(), elem); - } - return r.error(); -} - -GoASTExpr *GoParser::StructType() { - if (!(match(GoLexer::KEYWORD_STRUCT) && mustMatch(GoLexer::OP_LBRACE))) - return nullptr; - std::unique_ptr fields(new GoASTFieldList); - while (auto *field = FieldDecl()) - fields->AddList(field); - if (!mustMatch(GoLexer::OP_RBRACE)) - return nullptr; - return new GoASTStructType(fields.release()); -} - -GoASTField *GoParser::FieldDecl() { - std::unique_ptr f(new GoASTField); - GoASTExpr *t = FieldNamesAndType(f.get()); - if (!t) - t = AnonymousFieldType(); - if (!t) - return nullptr; - - if (auto *tok = match(GoLexer::LIT_STRING)) - f->SetTag(new GoASTBasicLit(*tok)); - if (!Semicolon()) - return syntaxerror(); - return f.release(); -} - -GoASTExpr *GoParser::FieldNamesAndType(GoASTField *field) { - Rule r("FieldNames", this); - for (auto *id = Identifier(); id; id = MoreIdentifierList()) - field->AddNames(id); - if (m_failed) - return nullptr; - GoASTExpr *t = Type(); - if (t) - return t; - return r.error(); -} - -GoASTExpr *GoParser::AnonymousFieldType() { - bool pointer = match(GoLexer::OP_STAR); - GoASTExpr *t = Type(); - if (!t) - return nullptr; - if (pointer) - return new GoASTStarExpr(t); - return t; -} - -GoASTExpr *GoParser::FunctionType() { - if (!match(GoLexer::KEYWORD_FUNC)) - return nullptr; - return Signature(); -} - -GoASTFuncType *GoParser::Signature() { - auto *params = Params(); - if (!params) - return syntaxerror(); - auto *result = Params(); - if (!result) { - if (auto *t = Type()) { - result = new GoASTFieldList; - auto *f = new GoASTField; - f->SetType(t); - result->AddList(f); - } - } - return new GoASTFuncType(params, result); -} - -GoASTFieldList *GoParser::Params() { - if (!match(GoLexer::OP_LPAREN)) - return nullptr; - std::unique_ptr l(new GoASTFieldList); - while (GoASTField *p = ParamDecl()) { - l->AddList(p); - if (!match(GoLexer::OP_COMMA)) - break; - } - if (!mustMatch(GoLexer::OP_RPAREN)) - return nullptr; - return l.release(); -} - -GoASTField *GoParser::ParamDecl() { - std::unique_ptr field(new GoASTField); - GoASTIdent *id = Identifier(); - if (id) { - // Try `IdentifierList [ "..." ] Type`. - // If that fails, backtrack and try `[ "..." ] Type`. - Rule r("NamedParam", this); - for (; id; id = MoreIdentifierList()) - field->AddNames(id); - GoASTExpr *t = ParamType(); - if (t) { - field->SetType(t); - return field.release(); - } - field.reset(new GoASTField); - r.error(); - } - GoASTExpr *t = ParamType(); - if (t) { - field->SetType(t); - return field.release(); - } - return nullptr; -} - -GoASTExpr *GoParser::ParamType() { - bool dots = match(GoLexer::OP_DOTS); - GoASTExpr *t = Type(); - if (!dots) - return t; - if (!t) - return syntaxerror(); - return new GoASTEllipsis(t); -} - -GoASTExpr *GoParser::InterfaceType() { - if (!match(GoLexer::KEYWORD_INTERFACE) || !mustMatch(GoLexer::OP_LBRACE)) - return nullptr; - std::unique_ptr methods(new GoASTFieldList); - while (true) { - Rule r("MethodSpec", this); - // ( identifier Signature | TypeName ) ; - std::unique_ptr id(Identifier()); - if (!id) - break; - GoASTExpr *type = Signature(); - if (!type) { - r.error(); - id.reset(); - type = Name(); - } - if (!Semicolon()) - return syntaxerror(); - auto *f = new GoASTField; - if (id) - f->AddNames(id.release()); - f->SetType(type); - methods->AddList(f); - } - if (!mustMatch(GoLexer::OP_RBRACE)) - return nullptr; - return new GoASTInterfaceType(methods.release()); -} - -GoASTExpr *GoParser::MapType() { - if (!(match(GoLexer::KEYWORD_MAP) && mustMatch(GoLexer::OP_LBRACK))) - return nullptr; - std::unique_ptr key(Type()); - if (!key) - return syntaxerror(); - if (!mustMatch(GoLexer::OP_RBRACK)) - return nullptr; - auto *elem = Type(); - if (!elem) - return syntaxerror(); - return new GoASTMapType(key.release(), elem); -} - -GoASTExpr *GoParser::ChanType() { - Rule r("chan", this); - if (match(GoLexer::OP_LT_MINUS)) { - if (match(GoLexer::KEYWORD_CHAN)) { - auto *elem = Type(); - if (!elem) - return syntaxerror(); - return new GoASTChanType(GoASTNode::eChanRecv, elem); - } - return r.error(); - } - return ChanType2(); -} - -GoASTExpr *GoParser::ChanType2() { - if (!match(GoLexer::KEYWORD_CHAN)) - return nullptr; - auto dir = GoASTNode::eChanBidir; - if (match(GoLexer::OP_LT_MINUS)) - dir = GoASTNode::eChanSend; - auto *elem = Type(); - if (!elem) - return syntaxerror(); - return new GoASTChanType(dir, elem); -} - -GoASTExpr *GoParser::Type() { - if (GoASTExpr *t = Type2()) - return t; - if (GoASTExpr *t = Name()) - return t; - if (GoASTExpr *t = ChanType()) - return t; - if (match(GoLexer::OP_STAR)) { - GoASTExpr *t = Type(); - if (!t) - return syntaxerror(); - return new GoASTStarExpr(t); - } - if (match(GoLexer::OP_LPAREN)) { - std::unique_ptr t(Type()); - if (!t || !match(GoLexer::OP_RPAREN)) - return syntaxerror(); - return t.release(); - } - return nullptr; -} - -bool GoParser::Semicolon() { - if (match(GoLexer::OP_SEMICOLON)) - return true; - switch (peek()) { - case GoLexer::OP_RPAREN: - case GoLexer::OP_RBRACE: - case GoLexer::TOK_EOF: - return true; - default: - return false; - } -} - -GoASTExpr *GoParser::Name() { - if (auto *id = Identifier()) { - if (GoASTExpr *qual = QualifiedIdent(id)) - return qual; - return id; - } - return nullptr; -} - -GoASTExpr *GoParser::QualifiedIdent(lldb_private::GoASTIdent *p) { - Rule r("QualifiedIdent", this); - llvm::SmallString<32> path(p->GetName().m_value); - GoLexer::Token *next; - bool have_slashes = false; - // LLDB extension: support full/package/path.name - while (match(GoLexer::OP_SLASH) && (next = match(GoLexer::TOK_IDENTIFIER))) { - have_slashes = true; - path.append("/"); - path.append(next->m_value); - } - if (match(GoLexer::OP_DOT)) { - auto *name = Identifier(); - if (name) { - if (have_slashes) { - p->SetName(GoLexer::Token(GoLexer::TOK_IDENTIFIER, CopyString(path))); - } - return new GoASTSelectorExpr(p, name); - } - } - return r.error(); -} - -llvm::StringRef GoParser::CopyString(llvm::StringRef s) { - return m_strings.insert(std::make_pair(s, 'x')).first->getKey(); -} - -void GoParser::GetError(Status &error) { - llvm::StringRef want; - if (m_failed) - want = - m_last_tok == GoLexer::TOK_INVALID ? DescribeToken(m_last_tok) : m_last; - else - want = m_error; - size_t len = m_lexer.BytesRemaining(); - if (len > 10) - len = 10; - llvm::StringRef got; - if (len == 0) - got = ""; - else - got = m_lexer.GetString(len); - error.SetErrorStringWithFormat("Syntax error: expected %s before '%s'.", - want.str().c_str(), got.str().c_str()); -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.h deleted file mode 100644 index 9ed2ae2033bd..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoParser.h +++ /dev/null @@ -1,145 +0,0 @@ -//===-- GoParser.h -----------------------------------------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_GoParser_h -#define liblldb_GoParser_h - -#include "Plugins/ExpressionParser/Go/GoAST.h" -#include "Plugins/ExpressionParser/Go/GoLexer.h" -#include "lldb/lldb-private.h" - -namespace lldb_private { -class GoParser { -public: - explicit GoParser(const char *src); - - GoASTStmt *Statement(); - - GoASTStmt *GoStmt(); - GoASTStmt *ReturnStmt(); - GoASTStmt *BranchStmt(); - GoASTStmt *EmptyStmt(); - GoASTStmt *ExpressionStmt(GoASTExpr *e); - GoASTStmt *IncDecStmt(GoASTExpr *e); - GoASTStmt *Assignment(GoASTExpr *e); - GoASTBlockStmt *Block(); - - GoASTExpr *MoreExpressionList(); // ["," Expression] - GoASTIdent *MoreIdentifierList(); // ["," Identifier] - - GoASTExpr *Expression(); - GoASTExpr *UnaryExpr(); - GoASTExpr *OrExpr(); - GoASTExpr *AndExpr(); - GoASTExpr *RelExpr(); - GoASTExpr *AddExpr(); - GoASTExpr *MulExpr(); - GoASTExpr *PrimaryExpr(); - GoASTExpr *Operand(); - GoASTExpr *Conversion(); - - GoASTExpr *Selector(GoASTExpr *e); - GoASTExpr *IndexOrSlice(GoASTExpr *e); - GoASTExpr *TypeAssertion(GoASTExpr *e); - GoASTExpr *Arguments(GoASTExpr *e); - - GoASTExpr *Type(); - GoASTExpr *Type2(); - GoASTExpr *ArrayOrSliceType(bool allowEllipsis); - GoASTExpr *StructType(); - GoASTExpr *FunctionType(); - GoASTExpr *InterfaceType(); - GoASTExpr *MapType(); - GoASTExpr *ChanType(); - GoASTExpr *ChanType2(); - - GoASTExpr *Name(); - GoASTExpr *QualifiedIdent(GoASTIdent *p); - GoASTIdent *Identifier(); - - GoASTField *FieldDecl(); - GoASTExpr *AnonymousFieldType(); - GoASTExpr *FieldNamesAndType(GoASTField *f); - - GoASTFieldList *Params(); - GoASTField *ParamDecl(); - GoASTExpr *ParamType(); - GoASTFuncType *Signature(); - GoASTExpr *CompositeLit(); - GoASTExpr *FunctionLit(); - GoASTExpr *Element(); - GoASTCompositeLit *LiteralValue(); - - bool Failed() const { return m_failed; } - bool AtEOF() const { - return m_lexer.BytesRemaining() == 0 && m_pos == m_tokens.size(); - } - - void GetError(Status &error); - -private: - class Rule; - friend class Rule; - - std::nullptr_t syntaxerror() { - m_failed = true; - return nullptr; - } - GoLexer::Token &next() { - if (m_pos >= m_tokens.size()) { - if (m_pos != 0 && (m_tokens.back().m_type == GoLexer::TOK_EOF || - m_tokens.back().m_type == GoLexer::TOK_INVALID)) - return m_tokens.back(); - m_pos = m_tokens.size(); - m_tokens.push_back(m_lexer.Lex()); - } - return m_tokens[m_pos++]; - } - GoLexer::TokenType peek() { - GoLexer::Token &tok = next(); - --m_pos; - return tok.m_type; - } - GoLexer::Token *match(GoLexer::TokenType t) { - GoLexer::Token &tok = next(); - if (tok.m_type == t) - return &tok; - --m_pos; - m_last_tok = t; - return nullptr; - } - GoLexer::Token *mustMatch(GoLexer::TokenType t) { - GoLexer::Token *tok = match(t); - if (tok) - return tok; - return syntaxerror(); - } - bool Semicolon(); - - GoASTStmt *FinishStmt(GoASTStmt *s) { - if (!Semicolon()) - m_failed = true; - return s; - } - - llvm::StringRef CopyString(llvm::StringRef s); - - GoLexer m_lexer; - std::vector m_tokens; - size_t m_pos; - llvm::StringRef m_error; - llvm::StringRef m_last; - GoLexer::TokenType m_last_tok; - llvm::StringMap m_strings; - bool m_failed; -}; -} - -#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp deleted file mode 100644 index 3a10a1dc767a..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.cpp +++ /dev/null @@ -1,668 +0,0 @@ -//===-- GoUserExpression.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include -#if HAVE_SYS_TYPES_H -#include -#endif - -// C++ Includes -#include -#include -#include -#include - -// Other libraries and framework includes -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" - -// Project includes -#include "GoUserExpression.h" - -#include "lldb/Core/Module.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/ValueObjectConstResult.h" -#include "lldb/Core/ValueObjectRegister.h" -#include "lldb/Expression/DiagnosticManager.h" -#include "lldb/Expression/ExpressionVariable.h" -#include "lldb/Symbol/GoASTContext.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/TypeList.h" -#include "lldb/Symbol/VariableList.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/StackFrame.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/ThreadPlan.h" -#include "lldb/Target/ThreadPlanCallUserExpression.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataEncoder.h" -#include "lldb/Utility/DataExtractor.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/StreamString.h" -#include "lldb/lldb-private.h" - -#include "Plugins/ExpressionParser/Go/GoAST.h" -#include "Plugins/ExpressionParser/Go/GoParser.h" - -using namespace lldb_private; -using namespace lldb; - -class GoUserExpression::GoInterpreter { -public: - GoInterpreter(ExecutionContext &exe_ctx, const char *expr) - : m_exe_ctx(exe_ctx), m_frame(exe_ctx.GetFrameSP()), m_parser(expr) { - if (m_frame) { - const SymbolContext &ctx = - m_frame->GetSymbolContext(eSymbolContextFunction); - ConstString fname = ctx.GetFunctionName(); - if (fname.GetLength() > 0) { - size_t dot = fname.GetStringRef().find('.'); - if (dot != llvm::StringRef::npos) - m_package = llvm::StringRef(fname.AsCString(), dot); - } - } - } - - void set_use_dynamic(DynamicValueType use_dynamic) { - m_use_dynamic = use_dynamic; - } - - bool Parse(); - lldb::ValueObjectSP Evaluate(ExecutionContext &exe_ctx); - lldb::ValueObjectSP EvaluateStatement(const GoASTStmt *s); - lldb::ValueObjectSP EvaluateExpr(const GoASTExpr *e); - - ValueObjectSP VisitBadExpr(const GoASTBadExpr *e) { - m_parser.GetError(m_error); - return nullptr; - } - - ValueObjectSP VisitParenExpr(const GoASTParenExpr *e); - ValueObjectSP VisitIdent(const GoASTIdent *e); - ValueObjectSP VisitStarExpr(const GoASTStarExpr *e); - ValueObjectSP VisitSelectorExpr(const GoASTSelectorExpr *e); - ValueObjectSP VisitBasicLit(const GoASTBasicLit *e); - ValueObjectSP VisitIndexExpr(const GoASTIndexExpr *e); - ValueObjectSP VisitUnaryExpr(const GoASTUnaryExpr *e); - ValueObjectSP VisitCallExpr(const GoASTCallExpr *e); - - ValueObjectSP VisitTypeAssertExpr(const GoASTTypeAssertExpr *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitBinaryExpr(const GoASTBinaryExpr *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitArrayType(const GoASTArrayType *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitChanType(const GoASTChanType *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitCompositeLit(const GoASTCompositeLit *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitEllipsis(const GoASTEllipsis *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitFuncType(const GoASTFuncType *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitFuncLit(const GoASTFuncLit *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitInterfaceType(const GoASTInterfaceType *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitKeyValueExpr(const GoASTKeyValueExpr *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitMapType(const GoASTMapType *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitSliceExpr(const GoASTSliceExpr *e) { - return NotImplemented(e); - } - - ValueObjectSP VisitStructType(const GoASTStructType *e) { - return NotImplemented(e); - } - - CompilerType EvaluateType(const GoASTExpr *e); - - Status &error() { return m_error; } - -private: - std::nullptr_t NotImplemented(const GoASTExpr *e) { - m_error.SetErrorStringWithFormat("%s node not implemented", - e->GetKindName()); - return nullptr; - } - - ExecutionContext m_exe_ctx; - lldb::StackFrameSP m_frame; - GoParser m_parser; - DynamicValueType m_use_dynamic; - Status m_error; - llvm::StringRef m_package; - std::vector> m_statements; -}; - -VariableSP FindGlobalVariable(TargetSP target, llvm::Twine name) { - ConstString fullname(name.str()); - VariableList variable_list; - if (!target) { - return nullptr; - } - const uint32_t match_count = - target->GetImages().FindGlobalVariables(fullname, 1, variable_list); - if (match_count == 1) { - return variable_list.GetVariableAtIndex(0); - } - return nullptr; -} - -CompilerType LookupType(TargetSP target, ConstString name) { - if (!target) - return CompilerType(); - SymbolContext sc; - TypeList type_list; - llvm::DenseSet searched_symbol_files; - uint32_t num_matches = target->GetImages().FindTypes( - sc, name, false, 2, searched_symbol_files, type_list); - if (num_matches > 0) { - return type_list.GetTypeAtIndex(0)->GetFullCompilerType(); - } - return CompilerType(); -} - -GoUserExpression::GoUserExpression(ExecutionContextScope &exe_scope, - llvm::StringRef expr, llvm::StringRef prefix, - lldb::LanguageType language, - ResultType desired_type, - const EvaluateExpressionOptions &options) - : UserExpression(exe_scope, expr, prefix, language, desired_type, options) { -} - -bool GoUserExpression::Parse(DiagnosticManager &diagnostic_manager, - ExecutionContext &exe_ctx, - lldb_private::ExecutionPolicy execution_policy, - bool keep_result_in_memory, - bool generate_debug_info) { - InstallContext(exe_ctx); - m_interpreter.reset(new GoInterpreter(exe_ctx, GetUserText())); - if (m_interpreter->Parse()) - return true; - const char *error_cstr = m_interpreter->error().AsCString(); - if (error_cstr && error_cstr[0]) - diagnostic_manager.PutString(eDiagnosticSeverityError, error_cstr); - else - diagnostic_manager.Printf(eDiagnosticSeverityError, - "expression can't be interpreted or run"); - return false; -} - -lldb::ExpressionResults -GoUserExpression::DoExecute(DiagnosticManager &diagnostic_manager, - ExecutionContext &exe_ctx, - const EvaluateExpressionOptions &options, - lldb::UserExpressionSP &shared_ptr_to_me, - lldb::ExpressionVariableSP &result) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_EXPRESSIONS | - LIBLLDB_LOG_STEP)); - - lldb_private::ExecutionPolicy execution_policy = options.GetExecutionPolicy(); - lldb::ExpressionResults execution_results = lldb::eExpressionSetupError; - - Process *process = exe_ctx.GetProcessPtr(); - Target *target = exe_ctx.GetTargetPtr(); - - if (target == nullptr || process == nullptr || - process->GetState() != lldb::eStateStopped) { - if (execution_policy == eExecutionPolicyAlways) { - if (log) - log->Printf("== [GoUserExpression::Evaluate] Expression may not run, " - "but is not constant =="); - - diagnostic_manager.PutString(eDiagnosticSeverityError, - "expression needed to run but couldn't"); - - return execution_results; - } - } - - m_interpreter->set_use_dynamic(options.GetUseDynamic()); - ValueObjectSP result_val_sp = m_interpreter->Evaluate(exe_ctx); - Status err = m_interpreter->error(); - m_interpreter.reset(); - - if (!result_val_sp) { - const char *error_cstr = err.AsCString(); - if (error_cstr && error_cstr[0]) - diagnostic_manager.PutString(eDiagnosticSeverityError, error_cstr); - else - diagnostic_manager.PutString(eDiagnosticSeverityError, - "expression can't be interpreted or run"); - return lldb::eExpressionDiscarded; - } - result.reset(new ExpressionVariable(ExpressionVariable::eKindGo)); - result->m_live_sp = result->m_frozen_sp = result_val_sp; - result->m_flags |= ExpressionVariable::EVIsProgramReference; - PersistentExpressionState *pv = - target->GetPersistentExpressionStateForLanguage(eLanguageTypeGo); - if (pv != nullptr) { - result->SetName(pv->GetNextPersistentVariableName( - *target, pv->GetPersistentVariablePrefix())); - pv->AddVariable(result); - } - return lldb::eExpressionCompleted; -} - -bool GoUserExpression::GoInterpreter::Parse() { - for (std::unique_ptr stmt(m_parser.Statement()); stmt; - stmt.reset(m_parser.Statement())) { - if (m_parser.Failed()) - break; - m_statements.emplace_back(std::move(stmt)); - } - if (m_parser.Failed() || !m_parser.AtEOF()) - m_parser.GetError(m_error); - - return m_error.Success(); -} - -ValueObjectSP -GoUserExpression::GoInterpreter::Evaluate(ExecutionContext &exe_ctx) { - m_exe_ctx = exe_ctx; - ValueObjectSP result; - for (const std::unique_ptr &stmt : m_statements) { - result = EvaluateStatement(stmt.get()); - if (m_error.Fail()) - return nullptr; - } - return result; -} - -ValueObjectSP GoUserExpression::GoInterpreter::EvaluateStatement( - const lldb_private::GoASTStmt *stmt) { - ValueObjectSP result; - switch (stmt->GetKind()) { - case GoASTNode::eBlockStmt: { - const GoASTBlockStmt *block = llvm::cast(stmt); - for (size_t i = 0; i < block->NumList(); ++i) - result = EvaluateStatement(block->GetList(i)); - break; - } - case GoASTNode::eBadStmt: - m_parser.GetError(m_error); - break; - case GoASTNode::eExprStmt: { - const GoASTExprStmt *expr = llvm::cast(stmt); - return EvaluateExpr(expr->GetX()); - } - default: - m_error.SetErrorStringWithFormat("%s node not supported", - stmt->GetKindName()); - } - return result; -} - -ValueObjectSP GoUserExpression::GoInterpreter::EvaluateExpr( - const lldb_private::GoASTExpr *e) { - if (e) - return e->Visit(this); - return ValueObjectSP(); -} - -ValueObjectSP GoUserExpression::GoInterpreter::VisitParenExpr( - const lldb_private::GoASTParenExpr *e) { - return EvaluateExpr(e->GetX()); -} - -ValueObjectSP GoUserExpression::GoInterpreter::VisitIdent(const GoASTIdent *e) { - ValueObjectSP val; - if (m_frame) { - VariableSP var_sp; - std::string varname = e->GetName().m_value.str(); - if (varname.size() > 1 && varname[0] == '$') { - RegisterContextSP reg_ctx_sp = m_frame->GetRegisterContext(); - const RegisterInfo *reg = - reg_ctx_sp->GetRegisterInfoByName(varname.c_str() + 1); - if (reg) { - std::string type; - switch (reg->encoding) { - case lldb::eEncodingSint: - type.append("int"); - break; - case lldb::eEncodingUint: - type.append("uint"); - break; - case lldb::eEncodingIEEE754: - type.append("float"); - break; - default: - m_error.SetErrorString("Invalid register encoding"); - return nullptr; - } - switch (reg->byte_size) { - case 8: - type.append("64"); - break; - case 4: - type.append("32"); - break; - case 2: - type.append("16"); - break; - case 1: - type.append("8"); - break; - default: - m_error.SetErrorString("Invalid register size"); - return nullptr; - } - ValueObjectSP regVal = ValueObjectRegister::Create( - m_frame.get(), reg_ctx_sp, reg->kinds[eRegisterKindLLDB]); - CompilerType goType = - LookupType(m_frame->CalculateTarget(), ConstString(type)); - if (regVal) { - regVal = regVal->Cast(goType); - return regVal; - } - } - m_error.SetErrorString("Invalid register name"); - return nullptr; - } - VariableListSP var_list_sp(m_frame->GetInScopeVariableList(false)); - if (var_list_sp) { - var_sp = var_list_sp->FindVariable(ConstString(varname)); - if (var_sp) - val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic); - else { - // When a variable is on the heap instead of the stack, go records a - // variable '&x' instead of 'x'. - var_sp = var_list_sp->FindVariable(ConstString("&" + varname)); - if (var_sp) { - val = m_frame->GetValueObjectForFrameVariable(var_sp, m_use_dynamic); - if (val) - val = val->Dereference(m_error); - if (m_error.Fail()) - return nullptr; - } - } - } - if (!val) { - m_error.Clear(); - TargetSP target = m_frame->CalculateTarget(); - if (!target) { - m_error.SetErrorString("No target"); - return nullptr; - } - var_sp = - FindGlobalVariable(target, m_package + "." + e->GetName().m_value); - if (var_sp) - return m_frame->TrackGlobalVariable(var_sp, m_use_dynamic); - } - } - if (!val) - m_error.SetErrorStringWithFormat("Unknown variable %s", - e->GetName().m_value.str().c_str()); - return val; -} - -ValueObjectSP -GoUserExpression::GoInterpreter::VisitStarExpr(const GoASTStarExpr *e) { - ValueObjectSP target = EvaluateExpr(e->GetX()); - if (!target) - return nullptr; - return target->Dereference(m_error); -} - -ValueObjectSP GoUserExpression::GoInterpreter::VisitSelectorExpr( - const lldb_private::GoASTSelectorExpr *e) { - ValueObjectSP target = EvaluateExpr(e->GetX()); - if (target) { - if (target->GetCompilerType().IsPointerType()) { - target = target->Dereference(m_error); - if (m_error.Fail()) - return nullptr; - } - ConstString field(e->GetSel()->GetName().m_value); - ValueObjectSP result = target->GetChildMemberWithName(field, true); - if (!result) - m_error.SetErrorStringWithFormat("Unknown child %s", field.AsCString()); - return result; - } - if (const GoASTIdent *package = llvm::dyn_cast(e->GetX())) { - if (VariableSP global = FindGlobalVariable( - m_exe_ctx.GetTargetSP(), package->GetName().m_value + "." + - e->GetSel()->GetName().m_value)) { - if (m_frame) { - m_error.Clear(); - return m_frame->GetValueObjectForFrameVariable(global, m_use_dynamic); - } - } - } - if (const GoASTBasicLit *packageLit = - llvm::dyn_cast(e->GetX())) { - if (packageLit->GetValue().m_type == GoLexer::LIT_STRING) { - std::string value = packageLit->GetValue().m_value.str(); - value = value.substr(1, value.size() - 2); - if (VariableSP global = FindGlobalVariable( - m_exe_ctx.GetTargetSP(), - value + "." + e->GetSel()->GetName().m_value)) { - if (m_frame) { - m_error.Clear(); - return m_frame->TrackGlobalVariable(global, m_use_dynamic); - } - } - } - } - // EvaluateExpr should have already set m_error. - return target; -} - -ValueObjectSP GoUserExpression::GoInterpreter::VisitBasicLit( - const lldb_private::GoASTBasicLit *e) { - std::string value = e->GetValue().m_value.str(); - if (e->GetValue().m_type != GoLexer::LIT_INTEGER) { - m_error.SetErrorStringWithFormat("Unsupported literal %s", value.c_str()); - return nullptr; - } - errno = 0; - int64_t intvalue = strtol(value.c_str(), nullptr, 0); - if (errno != 0) { - m_error.SetErrorToErrno(); - return nullptr; - } - DataBufferSP buf(new DataBufferHeap(sizeof(intvalue), 0)); - TargetSP target = m_exe_ctx.GetTargetSP(); - if (!target) { - m_error.SetErrorString("No target"); - return nullptr; - } - ByteOrder order = target->GetArchitecture().GetByteOrder(); - uint8_t addr_size = target->GetArchitecture().GetAddressByteSize(); - DataEncoder enc(buf, order, addr_size); - enc.PutU64(0, static_cast(intvalue)); - DataExtractor data(buf, order, addr_size); - - CompilerType type = LookupType(target, ConstString("int64")); - return ValueObject::CreateValueObjectFromData(llvm::StringRef(), data, - m_exe_ctx, type); -} - -ValueObjectSP GoUserExpression::GoInterpreter::VisitIndexExpr( - const lldb_private::GoASTIndexExpr *e) { - ValueObjectSP target = EvaluateExpr(e->GetX()); - if (!target) - return nullptr; - ValueObjectSP index = EvaluateExpr(e->GetIndex()); - if (!index) - return nullptr; - bool is_signed; - if (!index->GetCompilerType().IsIntegerType(is_signed)) { - m_error.SetErrorString("Unsupported index"); - return nullptr; - } - size_t idx; - if (is_signed) - idx = index->GetValueAsSigned(0); - else - idx = index->GetValueAsUnsigned(0); - if (GoASTContext::IsGoSlice(target->GetCompilerType())) { - target = target->GetStaticValue(); - ValueObjectSP cap = - target->GetChildMemberWithName(ConstString("cap"), true); - if (cap) { - uint64_t capval = cap->GetValueAsUnsigned(0); - if (idx >= capval) { - m_error.SetErrorStringWithFormat("Invalid index %" PRIu64 - " , cap = %" PRIu64, - uint64_t(idx), capval); - return nullptr; - } - } - target = target->GetChildMemberWithName(ConstString("array"), true); - if (target && m_use_dynamic != eNoDynamicValues) { - ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic); - if (dynamic) - target = dynamic; - } - if (!target) - return nullptr; - return target->GetSyntheticArrayMember(idx, true); - } - return target->GetChildAtIndex(idx, true); -} - -ValueObjectSP -GoUserExpression::GoInterpreter::VisitUnaryExpr(const GoASTUnaryExpr *e) { - ValueObjectSP x = EvaluateExpr(e->GetX()); - if (!x) - return nullptr; - switch (e->GetOp()) { - case GoLexer::OP_AMP: { - CompilerType type = x->GetCompilerType().GetPointerType(); - uint64_t address = x->GetAddressOf(); - return ValueObject::CreateValueObjectFromAddress(llvm::StringRef(), address, - m_exe_ctx, type); - } - case GoLexer::OP_PLUS: - return x; - default: - m_error.SetErrorStringWithFormat( - "Operator %s not supported", - GoLexer::LookupToken(e->GetOp()).str().c_str()); - return nullptr; - } -} - -CompilerType GoUserExpression::GoInterpreter::EvaluateType(const GoASTExpr *e) { - TargetSP target = m_exe_ctx.GetTargetSP(); - if (auto *id = llvm::dyn_cast(e)) { - CompilerType result = - LookupType(target, ConstString(id->GetName().m_value)); - if (result.IsValid()) - return result; - std::string fullname = (m_package + "." + id->GetName().m_value).str(); - result = LookupType(target, ConstString(fullname)); - if (!result) - m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str()); - return result; - } - if (auto *sel = llvm::dyn_cast(e)) { - std::string package; - if (auto *pkg_node = llvm::dyn_cast(sel->GetX())) { - package = pkg_node->GetName().m_value.str(); - } else if (auto *str_node = llvm::dyn_cast(sel->GetX())) { - if (str_node->GetValue().m_type == GoLexer::LIT_STRING) { - package = str_node->GetValue().m_value.substr(1).str(); - package.resize(package.length() - 1); - } - } - if (package.empty()) { - m_error.SetErrorStringWithFormat("Invalid %s in type expression", - sel->GetX()->GetKindName()); - return CompilerType(); - } - std::string fullname = - (package + "." + sel->GetSel()->GetName().m_value).str(); - CompilerType result = LookupType(target, ConstString(fullname)); - if (!result) - m_error.SetErrorStringWithFormat("Unknown type %s", fullname.c_str()); - return result; - } - if (auto *star = llvm::dyn_cast(e)) { - CompilerType elem = EvaluateType(star->GetX()); - return elem.GetPointerType(); - } - if (auto *paren = llvm::dyn_cast(e)) - return EvaluateType(paren->GetX()); - if (auto *array = llvm::dyn_cast(e)) { - CompilerType elem = EvaluateType(array->GetElt()); - } - - m_error.SetErrorStringWithFormat("Invalid %s in type expression", - e->GetKindName()); - return CompilerType(); -} - -ValueObjectSP GoUserExpression::GoInterpreter::VisitCallExpr( - const lldb_private::GoASTCallExpr *e) { - ValueObjectSP x = EvaluateExpr(e->GetFun()); - if (x || e->NumArgs() != 1) { - m_error.SetErrorStringWithFormat("Code execution not supported"); - return nullptr; - } - m_error.Clear(); - CompilerType type = EvaluateType(e->GetFun()); - if (!type) { - return nullptr; - } - ValueObjectSP value = EvaluateExpr(e->GetArgs(0)); - if (!value) - return nullptr; - // TODO: Handle special conversions - return value->Cast(type); -} - -GoPersistentExpressionState::GoPersistentExpressionState() - : PersistentExpressionState(eKindGo) {} - -void GoPersistentExpressionState::RemovePersistentVariable( - lldb::ExpressionVariableSP variable) { - RemoveVariable(variable); - - const char *name = variable->GetName().AsCString(); - - if (*(name++) != '$') - return; - if (*(name++) != 'g') - return; - if (*(name++) != 'o') - return; - - if (strtoul(name, nullptr, 0) == m_next_persistent_variable_id - 1) - m_next_persistent_variable_id--; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h deleted file mode 100644 index e2839da9bfdd..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/GoUserExpression.h +++ /dev/null @@ -1,94 +0,0 @@ -//===-- GoUserExpression.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_GoUserExpression_h_ -#define liblldb_GoUserExpression_h_ - -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -// Project includes -#include "lldb/Expression/ExpressionVariable.h" -#include "lldb/Expression/UserExpression.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/lldb-forward.h" -#include "lldb/lldb-private.h" - -namespace lldb_private { -class GoParser; - -class GoPersistentExpressionState : public PersistentExpressionState { -public: - GoPersistentExpressionState(); - - llvm::StringRef - GetPersistentVariablePrefix(bool is_error) const override { - return "$go"; - } - void RemovePersistentVariable(lldb::ExpressionVariableSP variable) override; - - lldb::addr_t LookupSymbol(const ConstString &name) override { - return LLDB_INVALID_ADDRESS; - } - - static bool classof(const PersistentExpressionState *pv) { - return pv->getKind() == PersistentExpressionState::eKindGo; - } - -private: - uint32_t m_next_persistent_variable_id; ///< The counter used by - ///GetNextResultName(). -}; - -//---------------------------------------------------------------------- -/// @class GoUserExpression GoUserExpression.h -/// "lldb/Expression/GoUserExpression.h" Encapsulates a single expression for -/// use with Go -/// -/// LLDB uses expressions for various purposes, notably to call functions -/// and as a backend for the expr command. GoUserExpression encapsulates the -/// objects needed to parse and interpret an expression. -//---------------------------------------------------------------------- -class GoUserExpression : public UserExpression { -public: - GoUserExpression(ExecutionContextScope &exe_scope, llvm::StringRef expr, - llvm::StringRef prefix, lldb::LanguageType language, - ResultType desired_type, - const EvaluateExpressionOptions &options); - - bool Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, - lldb_private::ExecutionPolicy execution_policy, - bool keep_result_in_memory, bool generate_debug_info) override; - - bool CanInterpret() override { return true; } - bool FinalizeJITExecution( - DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, - lldb::ExpressionVariableSP &result, - lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS, - lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override { - return true; - } - -protected: - lldb::ExpressionResults - DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, - const EvaluateExpressionOptions &options, - lldb::UserExpressionSP &shared_ptr_to_me, - lldb::ExpressionVariableSP &result) override; - -private: - class GoInterpreter; - std::unique_ptr m_interpreter; -}; - -} // namespace lldb_private - -#endif // liblldb_GoUserExpression_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py b/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py deleted file mode 100644 index 3be0e5f506ee..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/ExpressionParser/Go/gen_go_ast.py +++ /dev/null @@ -1,464 +0,0 @@ -import StringIO - - -def addNodes(): - addNode("ArrayType", "Expr", "len", "Expr", "elt", "Expr") - addNode( - "AssignStmt", - "Stmt", - "lhs", - "[]Expr", - "rhs", - "[]Expr", - "define", - "bool") - addNode("BadDecl", "Decl") - addNode("BadExpr", "Expr") - addNode("BadStmt", "Stmt") - addNode("BasicLit", "Expr", "value", "Token") - addNode("BinaryExpr", "Expr", "x", "Expr", "y", "Expr", "op", "TokenType") - addNode("BlockStmt", "Stmt", "list", "[]Stmt") - addNode("Ident", "Expr", "name", "Token") - addNode("BranchStmt", "Stmt", "label", "Ident", "tok", "TokenType") - addNode( - "CallExpr", - "Expr", - "fun", - "Expr", - "args", - "[]Expr", - "ellipsis", - "bool") - addNode("CaseClause", "Stmt", "list", "[]Expr", "body", "[]Stmt") - addNode("ChanType", "Expr", "dir", "ChanDir", "value", "Expr") - addNode("CommClause", "Stmt", "comm", "Stmt", "body", "[]Stmt") - addNode("CompositeLit", "Expr", "type", "Expr", "elts", "[]Expr") - addNode("DeclStmt", "Stmt", "decl", "Decl") - addNode("DeferStmt", "Stmt", "call", "CallExpr") - addNode("Ellipsis", "Expr", "elt", "Expr") - addNode("EmptyStmt", "Stmt") - addNode("ExprStmt", "Stmt", "x", "Expr") - addNode( - "Field", - "Node", - "names", - "[]Ident", - "type", - "Expr", - "tag", - "BasicLit") - addNode("FieldList", "Node", "list", "[]Field") - addNode( - "ForStmt", - "Stmt", - "init", - "Stmt", - "cond", - "Expr", - "post", - "Stmt", - "body", - "BlockStmt") - addNode("FuncType", "Expr", "params", "FieldList", "results", "FieldList") - addNode( - "FuncDecl", - "Decl", - "recv", - "FieldList", - "name", - "Ident", - "type", - "FuncType", - "body", - "BlockStmt") - addNode("FuncLit", "Expr", "type", "FuncType", "body", "BlockStmt") - addNode("GenDecl", "Decl", "tok", "TokenType", "specs", "[]Spec") - addNode("GoStmt", "Stmt", "call", "CallExpr") - addNode( - "IfStmt", - "Stmt", - "init", - "Stmt", - "cond", - "Expr", - "body", - "BlockStmt", - "els", - "Stmt") - addNode("ImportSpec", "Spec", "name", "Ident", "path", "BasicLit") - addNode("IncDecStmt", "Stmt", "x", "Expr", "tok", "TokenType") - addNode("IndexExpr", "Expr", "x", "Expr", "index", "Expr") - addNode("InterfaceType", "Expr", "methods", "FieldList") - addNode("KeyValueExpr", "Expr", "key", "Expr", "value", "Expr") - addNode("LabeledStmt", "Stmt", "label", "Ident", "stmt", "Stmt") - addNode("MapType", "Expr", "key", "Expr", "value", "Expr") - addNode("ParenExpr", "Expr", "x", "Expr") - addNode( - "RangeStmt", - "Stmt", - "key", - "Expr", - "value", - "Expr", - "define", - "bool", - "x", - "Expr", - "body", - "BlockStmt") - addNode("ReturnStmt", "Stmt", "results", "[]Expr") - addNode("SelectStmt", "Stmt", "body", "BlockStmt") - addNode("SelectorExpr", "Expr", "x", "Expr", "sel", "Ident") - addNode("SendStmt", "Stmt", "chan", "Expr", "value", "Expr") - addNode( - "SliceExpr", - "Expr", - "x", - "Expr", - "low", - "Expr", - "high", - "Expr", - "max", - "Expr", - "slice3", - "bool") - addNode("StarExpr", "Expr", "x", "Expr") - addNode("StructType", "Expr", "fields", "FieldList") - addNode( - "SwitchStmt", - "Stmt", - "init", - "Stmt", - "tag", - "Expr", - "body", - "BlockStmt") - addNode("TypeAssertExpr", "Expr", "x", "Expr", "type", "Expr") - addNode("TypeSpec", "Spec", "name", "Ident", "type", "Expr") - addNode( - "TypeSwitchStmt", - "Stmt", - "init", - "Stmt", - "assign", - "Stmt", - "body", - "BlockStmt") - addNode("UnaryExpr", "Expr", "op", "TokenType", "x", "Expr") - addNode( - "ValueSpec", - "Spec", - "names", - "[]Ident", - "type", - "Expr", - "values", - "[]Expr") - addParent("Decl", "Node") - addParent("Expr", "Node") - addParent("Spec", "Node") - addParent("Stmt", "Node") - - -class Member(object): - - def __init__(self, name, typename): - self.title = name.title() - self.sname = name - self.mname = 'm_' + name - self.is_list = typename.startswith("[]") - self.is_value = isValueType(typename) - if self.is_value: - self.argtype = typename - self.mtype = typename - elif self.is_list: - self.argtype = 'GoAST' + typename[2:] - self.mtype = 'std::vector >' % self.argtype - else: - self.argtype = 'GoAST' + typename - self.mtype = 'std::unique_ptr<%s>' % self.argtype - self.mname = self.mname + '_up' - - -kinds = {} -parentClasses = StringIO.StringIO() -childClasses = StringIO.StringIO() -walker = StringIO.StringIO() - - -def startClass(name, parent, out): - out.write(""" -class GoAST%s : public GoAST%s -{ - public: -""" % (name, parent)) - - -def endClass(name, out): - out.write(""" - %(name)s(const %(name)s &) = delete; - const %(name)s &operator=(const %(name)s &) = delete; -}; -""" % {'name': 'GoAST' + name}) - - -def addNode(name, parent, *children): - startClass(name, parent, childClasses) - l = kinds.setdefault(parent, []) - l.append(name) - children = createMembers(name, children) - addConstructor(name, parent, children) - childClasses.write(""" - const char * - GetKindName() const override - { - return "%(name)s"; - } - - static bool - classof(const GoASTNode *n) - { - return n->GetKind() == e%(name)s; - } - """ % {'name': name}) - addChildren(name, children) - endClass(name, childClasses) - - -def isValueType(typename): - if typename[0].islower(): - return True - if typename[0].isupper(): - return typename.startswith('Token') or typename == 'ChanDir' - return False - - -def createMembers(name, children): - l = len(children) - if (l % 2) != 0: - raise Exception("Invalid children for %s: %s" % (name, children)) - return [Member(children[i], children[i + 1]) for i in xrange(0, l, 2)] - - -def addConstructor(name, parent, children): - for c in children: - if c.is_list: - children = [x for x in children if x.is_value] - break - childClasses.write(' ') - if len(children) == 1: - childClasses.write('explicit ') - childClasses.write('GoAST%s(' % name) - for i in xrange(len(children)): - if i > 0: - childClasses.write(', ') - - c = children[i] - if c.is_value: - childClasses.write(c.argtype) - childClasses.write(' ') - else: - childClasses.write('%s *' % c.argtype) - childClasses.write(c.sname) - childClasses.write(') : GoAST%s(e%s)' % (parent, name)) - for c in children: - childClasses.write(', ') - childClasses.write('%(mname)s(%(sname)s)' % c.__dict__) - childClasses.write(""" {} - ~GoAST%s() override = default; -""" % name) - - -def addChildren(name, children): - if len(children) == 0: - return - walker.write(""" - case e%(n)s: - { - GoAST%(n)s *n = llvm::cast(this); - (void)n;""" % {'n': name}) - for c in children: - if c.is_list: - childClasses.write(""" - size_t - Num%(title)s() const - { - return %(mname)s.size(); - } - const %(argtype)s * - Get%(title)s(int i) const - { - return %(mname)s[i].get(); - } - void - Add%(title)s(%(argtype)s *%(sname)s) - { - %(mname)s.push_back(std::unique_ptr<%(argtype)s>(%(sname)s)); - } -""" % c.__dict__) - walker.write(""" - for (auto& e : n->%s) { v(e.get()); }""" % c.mname) - else: - const = '' - get = '' - set = '' - t = c.argtype - if isValueType(t): - set = '%(mname)s = %(sname)s' % c.__dict__ - t = t + ' ' - else: - t = t + ' *' - const = 'const ' - get = '.get()' - set = '%(mname)s.reset(%(sname)s)' % c.__dict__ - walker.write(""" - v(n->%s.get());""" % c.mname) - childClasses.write(""" - %(const)s%(type)s - Get%(title)s() const - { - return %(mname)s%(get)s; - } - void - Set%(title)s(%(type)s%(sname)s) - { - %(set)s; - } -""" % {'const': const, 'title': c.title, 'sname': c.sname, 'get': get, 'set': set, 'type': t, 'mname': c.mname}) - childClasses.write('\n private:\n friend class GoASTNode;\n') - walker.write(""" - return; - }""") - for c in children: - childClasses.write(' %s %s;\n' % (c.mtype, c.mname)) - - -def addParent(name, parent): - startClass(name, parent, parentClasses) - l = kinds[name] - minName = l[0] - maxName = l[-1] - parentClasses.write(""" template R Visit(V *v) const; - - static bool - classof(const GoASTNode *n) - { - return n->GetKind() >= e%s && n->GetKind() <= e%s; - } - - protected: - explicit GoAST%s(NodeKind kind) : GoASTNode(kind) { } - private: -""" % (minName, maxName, name)) - endClass(name, parentClasses) - -addNodes() - -print """//===-- GoAST.h -------------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// DO NOT EDIT. -// Generated by gen_go_ast.py - -#ifndef liblldb_GoAST_h -#define liblldb_GoAST_h - -#include "lldb/lldb-forward.h" -#include "lldb/lldb-private.h" -#include "llvm/Support/Casting.h" -#include "Plugins/ExpressionParser/Go/GoLexer.h" - -namespace lldb_private -{ - -class GoASTNode -{ - public: - typedef GoLexer::TokenType TokenType; - typedef GoLexer::Token Token; - enum ChanDir - { - eChanBidir, - eChanSend, - eChanRecv, - }; - enum NodeKind - {""" -for l in kinds.itervalues(): - for x in l: - print " e%s," % x -print """ }; - - virtual ~GoASTNode() = default; - - NodeKind - GetKind() const - { - return m_kind; - } - - virtual const char *GetKindName() const = 0; - - template void WalkChildren(V &v); - - protected: - explicit GoASTNode(NodeKind kind) : m_kind(kind) { } - - private: - const NodeKind m_kind; - - GoASTNode(const GoASTNode &) = delete; - const GoASTNode &operator=(const GoASTNode &) = delete; -}; -""" - - -print parentClasses.getvalue() -print childClasses.getvalue() - -for k, l in kinds.iteritems(): - if k == 'Node': - continue - print """ -template -R GoAST%s::Visit(V* v) const -{ - switch(GetKind()) - {""" % k - for subtype in l: - print """ case e%(n)s: - return v->Visit%(n)s(llvm::cast(this));""" % {'n': subtype} - - print """ default: - assert(false && "Invalid kind"); - } -}""" - -print """ -template -void GoASTNode::WalkChildren(V &v) -{ - switch (m_kind) - { -""" -print walker.getvalue() -print""" - case eEmptyStmt: - case eBadDecl: - case eBadExpr: - case eBadStmt: - break; - } -} - -} // namespace lldb_private - -#endif -""" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp index 86744520ad63..85bc4a61c9d4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulateInstructionARM.cpp @@ -26,8 +26,7 @@ #include "Utility/ARM_DWARF_Registers.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Support/MathExtras.h" // for SignExtend32 template function - // and countTrailingZeros function +#include "llvm/Support/MathExtras.h" using namespace lldb; using namespace lldb_private; @@ -777,10 +776,7 @@ bool EmulateInstructionARM::WriteBits32UnknownToMemory(addr_t address) { uint32_t random_data = rand(); const uint32_t addr_byte_size = GetAddressByteSize(); - if (!MemAWrite(context, address, random_data, addr_byte_size)) - return false; - - return true; + return MemAWrite(context, address, random_data, addr_byte_size); } // Write "bits (32) UNKNOWN" to register n. Helper function for many ARM @@ -850,6 +846,7 @@ uint32_t EmulateInstructionARM::GetFramePointerRegisterNumber() const { case llvm::Triple::IOS: case llvm::Triple::TvOS: case llvm::Triple::WatchOS: + // NEED_BRIDGEOS_TRIPLE case llvm::Triple::BridgeOS: is_apple = true; break; default: @@ -3340,10 +3337,7 @@ bool EmulateInstructionARM::EmulateCMNImm(const uint32_t opcode, EmulateInstruction::Context context; context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) - return false; - - return true; + return WriteFlags(context, res.result, res.carry_out, res.overflow); } // Compare Negative (register) adds a register value and an optionally-shifted @@ -3410,10 +3404,7 @@ bool EmulateInstructionARM::EmulateCMNReg(const uint32_t opcode, EmulateInstruction::Context context; context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) - return false; - - return true; + return WriteFlags(context, res.result, res.carry_out, res.overflow); } // Compare (immediate) subtracts an immediate value from a register value. It @@ -3463,10 +3454,7 @@ bool EmulateInstructionARM::EmulateCMPImm(const uint32_t opcode, EmulateInstruction::Context context; context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) - return false; - - return true; + return WriteFlags(context, res.result, res.carry_out, res.overflow); } // Compare (register) subtracts an optionally-shifted register value from a @@ -3542,10 +3530,7 @@ bool EmulateInstructionARM::EmulateCMPReg(const uint32_t opcode, EmulateInstruction::Context context; context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteFlags(context, res.result, res.carry_out, res.overflow)) - return false; - - return true; + return WriteFlags(context, res.result, res.carry_out, res.overflow); } // Arithmetic Shift Right (immediate) shifts a register value right by an @@ -9245,11 +9230,8 @@ bool EmulateInstructionARM::EmulateRSBImm(const uint32_t opcode, context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, - res.carry_out, res.overflow)) - return false; - - return true; + return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow); } // Reverse Subtract (register) subtracts a register value from an optionally- @@ -9326,11 +9308,8 @@ bool EmulateInstructionARM::EmulateRSBReg(const uint32_t opcode, EmulateInstruction::Context context; context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, - res.carry_out, res.overflow)) - return false; - - return true; + return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow); } // Reverse Subtract with Carry (immediate) subtracts a register value and the @@ -9388,11 +9367,8 @@ bool EmulateInstructionARM::EmulateRSCImm(const uint32_t opcode, context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, - res.carry_out, res.overflow)) - return false; - - return true; + return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow); } // Reverse Subtract with Carry (register) subtracts a register value and the @@ -9460,11 +9436,8 @@ bool EmulateInstructionARM::EmulateRSCReg(const uint32_t opcode, EmulateInstruction::Context context; context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, - res.carry_out, res.overflow)) - return false; - - return true; + return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow); } // Subtract with Carry (immediate) subtracts an immediate value and the value @@ -9531,11 +9504,8 @@ bool EmulateInstructionARM::EmulateSBCImm(const uint32_t opcode, context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, - res.carry_out, res.overflow)) - return false; - - return true; + return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow); } // Subtract with Carry (register) subtracts an optionally-shifted register @@ -9620,11 +9590,8 @@ bool EmulateInstructionARM::EmulateSBCReg(const uint32_t opcode, EmulateInstruction::Context context; context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, - res.carry_out, res.overflow)) - return false; - - return true; + return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow); } // This instruction subtracts an immediate value from a register value, and @@ -9713,11 +9680,8 @@ bool EmulateInstructionARM::EmulateSUBImmThumb(const uint32_t opcode, context.type = EmulateInstruction::eContextImmediate; context.SetNoArgs(); - if (!WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, - res.carry_out, res.overflow)) - return false; - - return true; + return WriteCoreRegOptionalFlags(context, res.result, Rd, setflags, + res.carry_out, res.overflow); } // This instruction subtracts an immediate value from a register value, and @@ -14153,11 +14117,8 @@ bool EmulateInstructionARM::BranchWritePC(const Context &context, else target = addr & 0xfffffffe; - if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_PC, target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC, target); } // As a side effect, BXWritePC sets context.arg2 to eModeARM or eModeThumb by @@ -14191,11 +14152,8 @@ bool EmulateInstructionARM::BXWritePC(Context &context, uint32_t addr) { LLDB_REGNUM_GENERIC_FLAGS, m_new_inst_cpsr)) return false; } - if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_PC, target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC, target); } // Dispatches to either BXWritePC or BranchWritePC based on architecture @@ -14408,14 +14366,14 @@ bool EmulateInstructionARM::EvaluateInstruction(uint32_t evaluate_options) { evaluate_options & eEmulateInstructionOptionIgnoreConditions; bool success = false; - if (m_opcode_cpsr == 0 || m_ignore_conditions == false) { + if (m_opcode_cpsr == 0 || !m_ignore_conditions) { m_opcode_cpsr = ReadRegisterUnsigned(eRegisterKindDWARF, dwarf_cpsr, 0, &success); } // Only return false if we are unable to read the CPSR if we care about // conditions - if (success == false && m_ignore_conditions == false) + if (!success && !m_ignore_conditions) return false; uint32_t orig_pc_value = 0; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp index d1032f56f31c..d770b3bdc52e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM/EmulationStateARM.cpp @@ -9,12 +9,12 @@ #include "EmulationStateARM.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Interpreter/OptionValueArray.h" #include "lldb/Interpreter/OptionValueDictionary.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "Utility/ARM_DWARF_Registers.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp index 2f484ab5ea97..661a651c56c2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp @@ -13,10 +13,10 @@ #include "lldb/Core/Address.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Stream.h" #include "Plugins/Process/Utility/ARMDefines.h" @@ -41,8 +41,7 @@ #include "Plugins/Process/Utility/RegisterInfos_arm64.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Support/MathExtras.h" // for SignExtend32 template function - // and CountTrailingZeros_32 function +#include "llvm/Support/MathExtras.h" #include "Plugins/Process/Utility/InstructionUtils.h" @@ -437,7 +436,7 @@ bool EmulateInstructionARM64::EvaluateInstruction(uint32_t evaluate_options) { // Only return false if we are unable to read the CPSR if we care about // conditions - if (success == false && m_ignore_conditions == false) + if (!success && !m_ignore_conditions) return false; uint32_t orig_pc_value = 0; @@ -547,11 +546,8 @@ bool EmulateInstructionARM64::BranchTo(const Context &context, uint32_t N, } else return false; - if (!WriteRegisterUnsigned(context, eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_PC, addr)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindGeneric, + LLDB_REGNUM_GENERIC_PC, addr); } bool EmulateInstructionARM64::ConditionHolds(const uint32_t cond) { @@ -1097,9 +1093,7 @@ bool EmulateInstructionARM64::EmulateB(const uint32_t opcode) { return false; } - if (!BranchTo(context, 64, target)) - return false; - return true; + return BranchTo(context, 64, target); } bool EmulateInstructionARM64::EmulateBcond(const uint32_t opcode) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h index 253bb935bca7..1d1bd74d3f61 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.h @@ -10,10 +10,6 @@ #ifndef EmulateInstructionARM64_h_ #define EmulateInstructionARM64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/ARMDefines.h" #include "lldb/Core/EmulateInstruction.h" #include "lldb/Interpreter/OptionValue.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp b/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp index b65747e12890..7fccb2311026 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS/EmulateInstructionMIPS.cpp @@ -14,12 +14,12 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Opcode.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/Target.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Stream.h" #include "llvm-c/Disassembler.h" #include "llvm/MC/MCAsmInfo.h" @@ -35,7 +35,7 @@ #include "llvm/ADT/STLExtras.h" #include "Plugins/Process/Utility/InstructionUtils.h" -#include "Plugins/Process/Utility/RegisterContext_mips.h" //mips32 has same registers nos as mips64 +#include "Plugins/Process/Utility/RegisterContext_mips.h" using namespace lldb; using namespace lldb_private; @@ -220,10 +220,8 @@ EmulateInstructionMIPS::CreateInstance(const ArchSpec &arch, } bool EmulateInstructionMIPS::SetTargetTriple(const ArchSpec &arch) { - if (arch.GetTriple().getArch() == llvm::Triple::mips || - arch.GetTriple().getArch() == llvm::Triple::mipsel) - return true; - return false; + return arch.GetTriple().getArch() == llvm::Triple::mips || + arch.GetTriple().getArch() == llvm::Triple::mipsel; } const char *EmulateInstructionMIPS::GetRegisterName(unsigned reg_num, @@ -1350,10 +1348,7 @@ bool EmulateInstructionMIPS::Emulate_LW(llvm::MCInst &insn) { context.type = eContextPopRegisterOffStack; context.SetAddress(address); - if (!WriteRegister(context, ®_info_src, data_src)) - return false; - - return true; + return WriteRegister(context, ®_info_src, data_src); } return false; @@ -1450,11 +1445,8 @@ bool EmulateInstructionMIPS::Emulate_LUI(llvm::MCInst &insn) { context.SetImmediateSigned(imm); context.type = eContextImmediate; - if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips + rt, - imm)) - return true; - - return false; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, + dwarf_zero_mips + rt, imm); } bool EmulateInstructionMIPS::Emulate_ADDIUSP(llvm::MCInst &insn) { @@ -1697,10 +1689,7 @@ bool EmulateInstructionMIPS::Emulate_LWSP(llvm::MCInst &insn) { context.type = eContextPopRegisterOffStack; context.SetAddress(base_address); - if (!WriteRegister(context, ®_info_src, data_src)) - return false; - - return true; + return WriteRegister(context, ®_info_src, data_src); } return false; @@ -1807,11 +1796,8 @@ bool EmulateInstructionMIPS::Emulate_JRADDIUSP(llvm::MCInst &insn) { context.type = eContextAdjustStackPointer; // update SP - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, - result)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_sp_mips, + result); } static int IsAdd64bitOverflow(int32_t a, int32_t b) { @@ -1864,11 +1850,8 @@ bool EmulateInstructionMIPS::Emulate_BXX_3ops(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } /* @@ -1947,11 +1930,8 @@ bool EmulateInstructionMIPS::Emulate_BXX_3ops_C(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } /* @@ -2122,11 +2102,8 @@ bool EmulateInstructionMIPS::Emulate_BXX_2ops(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } /* @@ -2189,11 +2166,8 @@ bool EmulateInstructionMIPS::Emulate_BXX_2ops_C(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) { @@ -2214,11 +2188,8 @@ bool EmulateInstructionMIPS::Emulate_B16_MM(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } /* @@ -2529,11 +2500,8 @@ bool EmulateInstructionMIPS::Emulate_BC(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) { @@ -2556,10 +2524,7 @@ bool EmulateInstructionMIPS::Emulate_J(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, pc); } bool EmulateInstructionMIPS::Emulate_JAL(llvm::MCInst &insn) { @@ -2688,11 +2653,8 @@ bool EmulateInstructionMIPS::Emulate_JIC(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) { @@ -2713,11 +2675,8 @@ bool EmulateInstructionMIPS::Emulate_JR(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - rs_val)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + rs_val); } /* @@ -2758,11 +2717,8 @@ bool EmulateInstructionMIPS::Emulate_FP_branch(llvm::MCInst &insn) { } Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) { @@ -2797,11 +2753,8 @@ bool EmulateInstructionMIPS::Emulate_BC1EQZ(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) { @@ -2836,11 +2789,8 @@ bool EmulateInstructionMIPS::Emulate_BC1NEZ(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } /* @@ -2898,11 +2848,8 @@ bool EmulateInstructionMIPS::Emulate_3D_branch(llvm::MCInst &insn) { } Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } bool EmulateInstructionMIPS::Emulate_BNZB(llvm::MCInst &insn) { @@ -2993,11 +2940,8 @@ bool EmulateInstructionMIPS::Emulate_MSA_Branch_DF(llvm::MCInst &insn, Context context; context.type = eContextRelativeBranchImmediate; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } bool EmulateInstructionMIPS::Emulate_BNZV(llvm::MCInst &insn) { @@ -3039,11 +2983,8 @@ bool EmulateInstructionMIPS::Emulate_MSA_Branch_V(llvm::MCInst &insn, Context context; context.type = eContextRelativeBranchImmediate; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips, + target); } bool EmulateInstructionMIPS::Emulate_LDST_Imm(llvm::MCInst &insn) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp index 5af12ad141aa..9d178dd97ddf 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.cpp @@ -14,12 +14,12 @@ #include "lldb/Core/Address.h" #include "lldb/Core/Opcode.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/PosixApi.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Stream.h" #include "llvm-c/Disassembler.h" #include "llvm/MC/MCAsmInfo.h" @@ -207,10 +207,8 @@ EmulateInstructionMIPS64::CreateInstance(const ArchSpec &arch, } bool EmulateInstructionMIPS64::SetTargetTriple(const ArchSpec &arch) { - if (arch.GetTriple().getArch() == llvm::Triple::mips64 || - arch.GetTriple().getArch() == llvm::Triple::mips64el) - return true; - return false; + return arch.GetTriple().getArch() == llvm::Triple::mips64 || + arch.GetTriple().getArch() == llvm::Triple::mips64el; } const char *EmulateInstructionMIPS64::GetRegisterName(unsigned reg_num, @@ -1099,13 +1097,24 @@ bool EmulateInstructionMIPS64::Emulate_DADDiu(llvm::MCInst &insn) { Context context; /* read register */ - const int64_t src_opd_val = ReadRegisterUnsigned( + const uint64_t src_opd_val = ReadRegisterUnsigned( eRegisterKindDWARF, dwarf_zero_mips64 + src, 0, &success); if (!success) return false; /* Check if this is daddiu sp, sp, imm16 */ if (dst == dwarf_sp_mips64) { + /* + * From the MIPS IV spec: + * + * The term “unsigned” in the instruction name is a misnomer; this + * operation is 64-bit modulo arithmetic that does not trap on overflow. + * It is appropriate for arithmetic which is not signed, such as address + * arithmetic, or integer arithmetic environments that ignore overflow, + * such as “C” language arithmetic. + * + * Assume 2's complement and rely on unsigned overflow here. + */ uint64_t result = src_opd_val + imm; RegisterInfo reg_info_sp; @@ -1229,10 +1238,7 @@ bool EmulateInstructionMIPS64::Emulate_LD(llvm::MCInst &insn) { Context context; context.type = eContextRegisterLoad; - if (!WriteRegister(context, ®_info_src, data_src)) - return false; - - return true; + return WriteRegister(context, ®_info_src, data_src); } return false; @@ -1251,11 +1257,8 @@ bool EmulateInstructionMIPS64::Emulate_LUI(llvm::MCInst &insn) { context.SetImmediateSigned(imm); context.type = eContextImmediate; - if (WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_zero_mips64 + rt, - imm)) - return true; - - return false; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, + dwarf_zero_mips64 + rt, imm); } bool EmulateInstructionMIPS64::Emulate_DSUBU_DADDU(llvm::MCInst &insn) { @@ -1383,11 +1386,8 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } /* @@ -1622,11 +1622,8 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) { @@ -1648,11 +1645,8 @@ bool EmulateInstructionMIPS64::Emulate_BC(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } static int IsAdd64bitOverflow(int64_t a, int64_t b) { @@ -1736,11 +1730,8 @@ bool EmulateInstructionMIPS64::Emulate_BXX_3ops_C(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } /* @@ -1803,11 +1794,8 @@ bool EmulateInstructionMIPS64::Emulate_BXX_2ops_C(llvm::MCInst &insn) { context.type = eContextRelativeBranchImmediate; context.SetImmediate(current_inst_size + offset); - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) { @@ -1830,10 +1818,8 @@ bool EmulateInstructionMIPS64::Emulate_J(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, pc)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + pc); } bool EmulateInstructionMIPS64::Emulate_JAL(llvm::MCInst &insn) { @@ -1962,11 +1948,8 @@ bool EmulateInstructionMIPS64::Emulate_JIC(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) { @@ -1987,11 +1970,8 @@ bool EmulateInstructionMIPS64::Emulate_JR(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - rs_val)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + rs_val); } /* @@ -2041,11 +2021,8 @@ bool EmulateInstructionMIPS64::Emulate_FP_branch(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) { @@ -2080,11 +2057,8 @@ bool EmulateInstructionMIPS64::Emulate_BC1EQZ(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) { @@ -2119,11 +2093,8 @@ bool EmulateInstructionMIPS64::Emulate_BC1NEZ(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } /* @@ -2182,11 +2153,8 @@ bool EmulateInstructionMIPS64::Emulate_3D_branch(llvm::MCInst &insn) { Context context; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } bool EmulateInstructionMIPS64::Emulate_BNZB(llvm::MCInst &insn) { @@ -2277,11 +2245,8 @@ bool EmulateInstructionMIPS64::Emulate_MSA_Branch_DF(llvm::MCInst &insn, Context context; context.type = eContextRelativeBranchImmediate; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } bool EmulateInstructionMIPS64::Emulate_BNZV(llvm::MCInst &insn) { @@ -2323,11 +2288,8 @@ bool EmulateInstructionMIPS64::Emulate_MSA_Branch_V(llvm::MCInst &insn, Context context; context.type = eContextRelativeBranchImmediate; - if (!WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, - target)) - return false; - - return true; + return WriteRegisterUnsigned(context, eRegisterKindDWARF, dwarf_pc_mips64, + target); } bool EmulateInstructionMIPS64::Emulate_LDST_Imm(llvm::MCInst &insn) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h b/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h index c2433d59830e..e9783633ac7d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/MIPS64/EmulateInstructionMIPS64.h @@ -10,10 +10,6 @@ #ifndef EmulateInstructionMIPS64_h_ #define EmulateInstructionMIPS64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/EmulateInstruction.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/Status.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/PPC64/CMakeLists.txt b/contrib/llvm/tools/lldb/source/Plugins/Instruction/PPC64/CMakeLists.txt deleted file mode 100644 index 0926433fc77c..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/PPC64/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_lldb_library(lldbPluginInstructionPPC64 PLUGIN - EmulateInstructionPPC64.cpp - - LINK_LIBS - lldbCore - lldbInterpreter - lldbSymbol - lldbPluginProcessUtility - LINK_COMPONENTS - Support - ) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h b/contrib/llvm/tools/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h index be65de9a5063..e9a1da6dd394 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.h @@ -10,10 +10,6 @@ #ifndef EmulateInstructionPPC64_h_ #define EmulateInstructionPPC64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/EmulateInstruction.h" #include "lldb/Interpreter/OptionValue.h" #include "lldb/Utility/Log.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h b/contrib/llvm/tools/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h index e9af5a6cdc74..1439f86e586f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h +++ b/contrib/llvm/tools/lldb/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.h @@ -10,10 +10,6 @@ #ifndef liblldb_AddressSanitizerRuntime_h_ #define liblldb_AddressSanitizerRuntime_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/InstrumentationRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Utility/StructuredData.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h b/contrib/llvm/tools/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h index dc737d22a67a..e6482d394efa 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h +++ b/contrib/llvm/tools/lldb/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.h @@ -10,10 +10,6 @@ #ifndef liblldb_ThreadSanitizerRuntime_h_ #define liblldb_ThreadSanitizerRuntime_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/Target/InstrumentationRuntime.h" #include "lldb/Utility/StructuredData.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp index 7ef3aecdb89f..3040b8b39052 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include "llvm/Support/MathExtras.h" @@ -59,10 +58,9 @@ template struct jit_descriptor { namespace { -PropertyDefinition g_properties[] = { +static constexpr PropertyDefinition g_properties[] = { {"enable-jit-breakpoint", OptionValue::eTypeBoolean, true, true, nullptr, - nullptr, "Enable breakpoint on __jit_debug_register_code."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + {}, "Enable breakpoint on __jit_debug_register_code."}}; enum { ePropertyEnableJITBreakpoint }; @@ -316,7 +314,7 @@ bool JITLoaderGDB::ReadJITDescriptorImpl(bool all_entries) { char jit_name[64]; snprintf(jit_name, 64, "JIT(0x%" PRIx64 ")", symbolfile_addr); module_sp = m_process->ReadModuleFromMemory( - FileSpec(jit_name, false), symbolfile_addr, symbolfile_size); + FileSpec(jit_name), symbolfile_addr, symbolfile_size); if (module_sp && module_sp->GetObjectFile()) { // load the symbol table right away diff --git a/contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h b/contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h index 6269860825db..a22016601293 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.h @@ -10,12 +10,8 @@ #ifndef liblldb_JITLoaderGDB_h_ #define liblldb_JITLoaderGDB_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/JITLoader.h" #include "lldb/Target/Process.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp index 82b7ac1675fa..40200503a8a7 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "BlockPointer.h" #include "lldb/Core/ValueObject.h" @@ -89,7 +85,7 @@ public: size_t CalculateNumChildren() override { const bool omit_empty_base_classes = false; - return m_block_struct_type.GetNumChildren(omit_empty_base_classes); + return m_block_struct_type.GetNumChildren(omit_empty_base_classes, nullptr); } lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index 2c63e6467d4c..982b286d0f05 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -9,20 +9,17 @@ #include "CPlusPlusLanguage.h" -// C Includes #include #include -// C++ Includes #include #include #include #include -// Other libraries and framework includes #include "llvm/ADT/StringRef.h" +#include "llvm/Demangle/ItaniumDemangle.h" -// Project includes #include "lldb/Core/PluginManager.h" #include "lldb/Core/UniqueCStringMap.h" #include "lldb/DataFormatters/CXXFunctionPointer.h" @@ -30,7 +27,6 @@ #include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/DataFormatters/VectorType.h" #include "lldb/Utility/ConstString.h" -#include "lldb/Utility/FastDemangle.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" @@ -39,7 +35,9 @@ #include "CxxStringTypes.h" #include "LibCxx.h" #include "LibCxxAtomic.h" +#include "LibCxxVariant.h" #include "LibStdcpp.h" +#include "MSVCUndecoratedNameParser.h" using namespace lldb; using namespace lldb_private; @@ -143,10 +141,7 @@ static bool IsTrivialBasename(const llvm::StringRef &basename) { } // We processed all characters. It is a vaild basename. - if (idx == basename.size()) - return true; - - return false; + return idx == basename.size(); } bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() { @@ -251,19 +246,23 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() { bool CPlusPlusLanguage::IsCPPMangledName(const char *name) { // FIXME!! we should really run through all the known C++ Language plugins // and ask each one if this is a C++ mangled name - + if (name == nullptr) return false; - - // MSVC style mangling + + // MSVC style mangling if (name[0] == '?') return true; - + return (name[0] != '\0' && name[0] == '_' && name[1] == 'Z'); } bool CPlusPlusLanguage::ExtractContextAndIdentifier( const char *name, llvm::StringRef &context, llvm::StringRef &identifier) { + if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name)) + return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context, + identifier); + CPlusPlusNameParser parser(name); if (auto full_name = parser.ParseAsFullName()) { identifier = full_name.getValue().basename; @@ -273,53 +272,89 @@ bool CPlusPlusLanguage::ExtractContextAndIdentifier( return false; } -/// Given a mangled function `mangled`, replace all the primitive function type -/// arguments of `search` with type `replace`. -static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled, - llvm::StringRef search, - llvm::StringRef replace) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); +namespace { +class NodeAllocator { + llvm::BumpPtrAllocator Alloc; - const size_t max_len = - mangled.size() + mangled.count(search) * replace.size() + 1; +public: + void reset() { Alloc.Reset(); } - // Make a temporary buffer to fix up the mangled parameter types and copy the - // original there - std::string output_buf; - output_buf.reserve(max_len); - output_buf.insert(0, mangled.str()); - ptrdiff_t replaced_offset = 0; + template T *makeNode(Args &&... args) { + return new (Alloc.Allocate(sizeof(T), alignof(T))) + T(std::forward(args)...); + } - auto swap_parms_hook = [&](const char *parsee) { - if (!parsee || !*parsee) - return; + void *allocateNodeArray(size_t sz) { + return Alloc.Allocate(sizeof(llvm::itanium_demangle::Node *) * sz, + alignof(llvm::itanium_demangle::Node *)); + } +}; - // Check whether we've found a substitutee - llvm::StringRef s(parsee); - if (s.startswith(search)) { - // account for the case where a replacement is of a different length to - // the original - replaced_offset += replace.size() - search.size(); +/// Given a mangled function `Mangled`, replace all the primitive function type +/// arguments of `Search` with type `Replace`. +class TypeSubstitutor + : public llvm::itanium_demangle::AbstractManglingParser { + /// Input character until which we have constructed the respective output + /// already + const char *Written; - ptrdiff_t replace_idx = (mangled.size() - s.size()) + replaced_offset; - output_buf.erase(replace_idx, search.size()); - output_buf.insert(replace_idx, replace.str()); + llvm::StringRef Search; + llvm::StringRef Replace; + llvm::SmallString<128> Result; + + /// Whether we have performed any substitutions. + bool Substituted; + + void reset(llvm::StringRef Mangled, llvm::StringRef Search, + llvm::StringRef Replace) { + AbstractManglingParser::reset(Mangled.begin(), Mangled.end()); + Written = Mangled.begin(); + this->Search = Search; + this->Replace = Replace; + Result.clear(); + Substituted = false; + } + + void appendUnchangedInput() { + Result += llvm::StringRef(Written, First - Written); + Written = First; + } + +public: + TypeSubstitutor() : AbstractManglingParser(nullptr, nullptr) {} + + ConstString substitute(llvm::StringRef Mangled, llvm::StringRef From, + llvm::StringRef To) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE); + + reset(Mangled, From, To); + if (parse() == nullptr) { + LLDB_LOG(log, "Failed to substitute mangling in {0}", Mangled); + return ConstString(); } - }; + if (!Substituted) + return ConstString(); - // FastDemangle will call our hook for each instance of a primitive type, - // allowing us to perform substitution - char *const demangled = - FastDemangle(mangled.str().c_str(), mangled.size(), swap_parms_hook); + // Append any trailing unmodified input. + appendUnchangedInput(); + LLDB_LOG(log, "Substituted mangling {0} -> {1}", Mangled, Result); + return ConstString(Result); + } - if (log) - log->Printf("substituted mangling for %s:{%s} %s:{%s}\n", - mangled.str().c_str(), demangled, output_buf.c_str(), - FastDemangle(output_buf.c_str())); - // FastDemangle malloc'd this string. - free(demangled); + llvm::itanium_demangle::Node *parseType() { + if (llvm::StringRef(First, numLeft()).startswith(Search)) { + // We found a match. Append unmodified input up to this point. + appendUnchangedInput(); - return output_buf == mangled ? ConstString() : ConstString(output_buf); + // And then perform the replacement. + Result += Replace; + Written += Search.size(); + Substituted = true; + } + return AbstractManglingParser::parseType(); + } +}; } uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( @@ -348,23 +383,24 @@ uint32_t CPlusPlusLanguage::FindAlternateFunctionManglings( alternates.insert(ConstString(fixed_scratch)); } + TypeSubstitutor TS; // `char` is implementation defined as either `signed` or `unsigned`. As a // result a char parameter has 3 possible manglings: 'c'-char, 'a'-signed // char, 'h'-unsigned char. If we're looking for symbols with a signed char // parameter, try finding matches which have the general case 'c'. if (ConstString char_fixup = - SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "a", "c")) + TS.substitute(mangled_name.GetStringRef(), "a", "c")) alternates.insert(char_fixup); // long long parameter mangling 'x', may actually just be a long 'l' argument if (ConstString long_fixup = - SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "x", "l")) + TS.substitute(mangled_name.GetStringRef(), "x", "l")) alternates.insert(long_fixup); // unsigned long long parameter mangling 'y', may actually just be unsigned // long 'm' argument if (ConstString ulong_fixup = - SubsPrimitiveParmItanium(mangled_name.GetStringRef(), "y", "m")) + TS.substitute(mangled_name.GetStringRef(), "y", "m")) alternates.insert(ulong_fixup); return alternates.size() - start_size; @@ -385,8 +421,17 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { #ifndef LLDB_DISABLE_PYTHON lldb::TypeSummaryImplSP std_string_summary_sp(new CXXFunctionSummaryFormat( - stl_summary_flags, lldb_private::formatters::LibcxxStringSummaryProvider, + stl_summary_flags, + lldb_private::formatters::LibcxxStringSummaryProviderASCII, "std::string summary provider")); + lldb::TypeSummaryImplSP std_stringu16_summary_sp(new CXXFunctionSummaryFormat( + stl_summary_flags, + lldb_private::formatters::LibcxxStringSummaryProviderUTF16, + "std::u16string summary provider")); + lldb::TypeSummaryImplSP std_stringu32_summary_sp(new CXXFunctionSummaryFormat( + stl_summary_flags, + lldb_private::formatters::LibcxxStringSummaryProviderUTF32, + "std::u32string summary provider")); lldb::TypeSummaryImplSP std_wstring_summary_sp(new CXXFunctionSummaryFormat( stl_summary_flags, lldb_private::formatters::LibcxxWStringSummaryProvider, "std::wstring summary provider")); @@ -399,6 +444,16 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { ConstString("std::__1::basic_string, " "std::__1::allocator >"), std_string_summary_sp); + cpp_category_sp->GetTypeSummariesContainer()->Add( + ConstString( + "std::__1::basic_string, " + "std::__1::allocator >"), + std_stringu16_summary_sp); + cpp_category_sp->GetTypeSummariesContainer()->Add( + ConstString( + "std::__1::basic_string, " + "std::__1::allocator >"), + std_stringu32_summary_sp); cpp_category_sp->GetTypeSummariesContainer()->Add( ConstString("std::__ndk1::basic_string, " @@ -493,6 +548,14 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "libc++ std::tuple synthetic children", ConstString("^std::__(ndk)?1::tuple<.*>(( )?&)?$"), stl_synth_flags, true); + AddCXXSynthetic(cpp_category_sp, LibcxxOptionalFrontEndCreator, + "libc++ std::optional synthetic children", + ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"), + stl_synth_flags, true); + AddCXXSynthetic(cpp_category_sp, LibcxxVariantFrontEndCreator, + "libc++ std::variant synthetic children", + ConstString("^std::__(ndk)?1::variant<.+>(( )?&)?$"), + stl_synth_flags, true); AddCXXSynthetic( cpp_category_sp, lldb_private::formatters::LibcxxAtomicSyntheticFrontEndCreator, @@ -519,6 +582,11 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { ConstString("^(std::__(ndk)?1::)weak_ptr<.+>(( )?&)?$"), stl_synth_flags, true); + AddCXXSummary( + cpp_category_sp, lldb_private::formatters::LibcxxFunctionSummaryProvider, + "libc++ std::function summary provider", + ConstString("^std::__(ndk)?1::function<.+>$"), stl_summary_flags, true); + stl_summary_flags.SetDontShowChildren(false); stl_summary_flags.SetSkipPointers(false); AddCXXSummary(cpp_category_sp, @@ -584,6 +652,16 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { cpp_category_sp, lldb_private::formatters::LibCxxAtomicSummaryProvider, "libc++ std::atomic summary provider", ConstString("^std::__(ndk)?1::atomic<.+>$"), stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxOptionalSummaryProvider, + "libc++ std::optional summary provider", + ConstString("^std::__(ndk)?1::optional<.+>(( )?&)?$"), + stl_summary_flags, true); + AddCXXSummary(cpp_category_sp, + lldb_private::formatters::LibcxxVariantSummaryProvider, + "libc++ std::variant summary provider", + ConstString("^std::__(ndk)?1::variant<.+>(( )?&)?$"), + stl_summary_flags, true); stl_summary_flags.SetSkipPointers(true); @@ -610,11 +688,6 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) { "std::map iterator synthetic children", ConstString("^std::__(ndk)?1::__map_iterator<.+>$"), stl_synth_flags, true); - - AddCXXSynthetic( - cpp_category_sp, lldb_private::formatters::LibcxxFunctionFrontEndCreator, - "std::function synthetic value provider", - ConstString("^std::__(ndk)?1::function<.+>$"), stl_synth_flags, true); #endif } @@ -1002,3 +1075,16 @@ CPlusPlusLanguage::GetHardcodedSynthetics() { return g_formatters; } + +bool CPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { + const auto suffixes = {".cpp", ".cxx", ".c++", ".cc", ".c", + ".h", ".hh", ".hpp", ".hxx", ".h++"}; + for (auto suffix : suffixes) { + if (file_path.endswith_lower(suffix)) + return true; + } + + // Check if we're in a STL path (where the files usually have no extension + // that we could check for. + return file_path.contains("/usr/include/c++/"); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h index 7380ef321305..3c8ca96e81f6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.h @@ -10,15 +10,12 @@ #ifndef liblldb_CPlusPlusLanguage_h_ #define liblldb_CPlusPlusLanguage_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "llvm/ADT/StringRef.h" -// Project includes +#include "Plugins/Language/ClangCommon/ClangHighlighter.h" #include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" @@ -26,6 +23,8 @@ namespace lldb_private { class CPlusPlusLanguage : public Language { + ClangHighlighter m_highlighter; + public: class MethodName { public: @@ -90,6 +89,10 @@ public: HardcodedFormatters::HardcodedSyntheticFinder GetHardcodedSynthetics() override; + bool IsSourceFile(llvm::StringRef file_path) const override; + + const Highlighter *GetHighlighter() const override { return &m_highlighter; } + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h index fe1d46f32c17..d46a53a7a704 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.h @@ -10,16 +10,12 @@ #ifndef liblldb_CPlusPlusNameParser_h_ #define liblldb_CPlusPlusNameParser_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "clang/Lex/Lexer.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -// Project includes #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp index 0f6fb54e8384..24185b314466 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/CxxStringTypes.cpp @@ -100,8 +100,11 @@ bool lldb_private::formatters::WCharStringSummaryProvider( if (!wchar_compiler_type) return false; - const uint32_t wchar_size = wchar_compiler_type.GetBitSize( - nullptr); // Safe to pass NULL for exe_scope here + // Safe to pass nullptr for exe_scope here. + llvm::Optional size = wchar_compiler_type.GetBitSize(nullptr); + if (!size) + return false; + const uint32_t wchar_size = *size; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); @@ -194,8 +197,11 @@ bool lldb_private::formatters::WCharSummaryProvider( if (!wchar_compiler_type) return false; - const uint32_t wchar_size = wchar_compiler_type.GetBitSize( - nullptr); // Safe to pass NULL for exe_scope here + // Safe to pass nullptr for exe_scope here. + llvm::Optional size = wchar_compiler_type.GetBitSize(nullptr); + if (!size) + return false; + const uint32_t wchar_size = *size; StringPrinter::ReadBufferAndDumpToStreamOptions options(valobj); options.SetData(data); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp index 95e02a473cd7..7e8c06bd4c75 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp @@ -9,10 +9,7 @@ #include "LibCxx.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes +#include "llvm/ADT/ScopeExit.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/ValueObject.h" @@ -22,7 +19,9 @@ #include "lldb/DataFormatters/TypeSummary.h" #include "lldb/DataFormatters/VectorIterator.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Target/ProcessStructReader.h" +#include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Endian.h" @@ -33,6 +32,76 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; +bool lldb_private::formatters::LibcxxOptionalSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); + if (!valobj_sp) + return false; + + // An optional either contains a value or not, the member __engaged_ is + // a bool flag, it is true if the optional has a value and false otherwise. + ValueObjectSP engaged_sp( + valobj_sp->GetChildMemberWithName(ConstString("__engaged_"), true)); + + if (!engaged_sp) + return false; + + llvm::StringRef engaged_as_cstring( + engaged_sp->GetValueAsUnsigned(0) == 1 ? "true" : "false"); + + stream.Printf(" Has Value=%s ", engaged_as_cstring.data()); + + return true; +} + +bool lldb_private::formatters::LibcxxFunctionSummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + + ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); + + if (!valobj_sp) + return false; + + ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef()); + Process *process = exe_ctx.GetProcessPtr(); + + if (process == nullptr) + return false; + + CPPLanguageRuntime *cpp_runtime = process->GetCPPLanguageRuntime(); + + if (!cpp_runtime) + return false; + + CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info = + cpp_runtime->FindLibCppStdFunctionCallableInfo(valobj_sp); + + switch (callable_info.callable_case) { + case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Invalid: + stream.Printf(" __f_ = %" PRIu64, callable_info.member__f_pointer_value); + return false; + break; + case CPPLanguageRuntime::LibCppStdFunctionCallableCase::Lambda: + stream.Printf( + " Lambda in File %s at Line %u", + callable_info.callable_line_entry.file.GetFilename().GetCString(), + callable_info.callable_line_entry.line); + break; + case CPPLanguageRuntime::LibCppStdFunctionCallableCase::CallableObject: + stream.Printf( + " Function in File %s at Line %u", + callable_info.callable_line_entry.file.GetFilename().GetCString(), + callable_info.callable_line_entry.line); + break; + case CPPLanguageRuntime::LibCppStdFunctionCallableCase::FreeOrMemberFunction: + stream.Printf(" Function = %s ", + callable_info.callable_symbol.GetName().GetCString()); + break; + } + + return true; +} + bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); @@ -120,9 +189,9 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { if (!valobj_sp) return false; - + static ConstString g___i_("__i_"); - + // this must be a ValueObject* because it is a child of the ValueObject we // are producing children for it if were a ValueObjectSP, we would end up // with a loop (iterator -> synthetic -> child -> parent == iterator) and @@ -156,37 +225,53 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() { m_pair_ptr = nullptr; return false; } - CompilerType pair_type(__i_->GetCompilerType().GetTypeTemplateArgument(0)); - std::string name; uint64_t bit_offset_ptr; uint32_t bitfield_bit_size_ptr; bool is_bitfield_ptr; - pair_type = pair_type.GetFieldAtIndex(0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr); + CompilerType pair_type( + __i_->GetCompilerType().GetTypeTemplateArgument(0)); + std::string name; + uint64_t bit_offset_ptr; + uint32_t bitfield_bit_size_ptr; + bool is_bitfield_ptr; + pair_type = pair_type.GetFieldAtIndex( + 0, name, &bit_offset_ptr, &bitfield_bit_size_ptr, &is_bitfield_ptr); if (!pair_type) { m_pair_ptr = nullptr; return false; } - + auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS)); m_pair_ptr = nullptr; - if (addr && addr!=LLDB_INVALID_ADDRESS) { - ClangASTContext *ast_ctx = llvm::dyn_cast_or_null(pair_type.GetTypeSystem()); + if (addr && addr != LLDB_INVALID_ADDRESS) { + ClangASTContext *ast_ctx = + llvm::dyn_cast_or_null(pair_type.GetTypeSystem()); if (!ast_ctx) return false; - CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(ConstString(), { - {"ptr0",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr1",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"ptr2",ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, - {"cw",ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, - {"payload",pair_type} - }); - DataBufferSP buffer_sp(new DataBufferHeap(tree_node_type.GetByteSize(nullptr),0)); + CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier( + ConstString(), + {{"ptr0", + ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr1", + ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"ptr2", + ast_ctx->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()}, + {"cw", ast_ctx->GetBasicType(lldb::eBasicTypeBool)}, + {"payload", pair_type}}); + llvm::Optional size = tree_node_type.GetByteSize(nullptr); + if (!size) + return false; + DataBufferSP buffer_sp(new DataBufferHeap(*size, 0)); ProcessSP process_sp(target_sp->GetProcessSP()); Status error; - process_sp->ReadMemory(addr, buffer_sp->GetBytes(), buffer_sp->GetByteSize(), error); + process_sp->ReadMemory(addr, buffer_sp->GetBytes(), + buffer_sp->GetByteSize(), error); if (error.Fail()) return false; - DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), process_sp->GetAddressByteSize()); - auto pair_sp = CreateValueObjectFromData("pair", extractor, valobj_sp->GetExecutionContextRef(), tree_node_type); + DataExtractor extractor(buffer_sp, process_sp->GetByteOrder(), + process_sp->GetAddressByteSize()); + auto pair_sp = CreateValueObjectFromData( + "pair", extractor, valobj_sp->GetExecutionContextRef(), + tree_node_type); if (pair_sp) - m_pair_sp = pair_sp->GetChildAtIndex(4,true); + m_pair_sp = pair_sp->GetChildAtIndex(4, true); } } } @@ -491,6 +576,8 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( ->GetScratchClangASTContext() ->GetBasicType(lldb::eBasicTypeWChar) .GetByteSize(nullptr); + if (!wchar_t_size) + return false; options.SetData(extractor); options.SetStream(&stream); @@ -499,7 +586,7 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); - switch (wchar_t_size) { + switch (*wchar_t_size) { case 1: StringPrinter::ReadBufferAndDumpToStream< lldb_private::formatters::StringPrinter::StringElementType::UTF8>( @@ -526,9 +613,10 @@ bool lldb_private::formatters::LibcxxWStringSummaryProvider( return true; } -bool lldb_private::formatters::LibcxxStringSummaryProvider( - ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &summary_options) { +template +bool LibcxxStringSummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options, + std::string prefix_token = "") { uint64_t size = 0; ValueObjectSP location_sp; @@ -557,31 +645,37 @@ bool lldb_private::formatters::LibcxxStringSummaryProvider( options.SetData(extractor); options.SetStream(&stream); - options.SetPrefixToken(nullptr); + + if (prefix_token.empty()) + options.SetPrefixToken(nullptr); + else + options.SetPrefixToken(prefix_token); + options.SetQuote('"'); options.SetSourceSize(size); options.SetBinaryZeroIsTerminator(false); - StringPrinter::ReadBufferAndDumpToStream< - StringPrinter::StringElementType::ASCII>(options); + StringPrinter::ReadBufferAndDumpToStream(options); return true; } -class LibcxxFunctionFrontEnd : public SyntheticValueProviderFrontEnd { -public: - LibcxxFunctionFrontEnd(ValueObject &backend) - : SyntheticValueProviderFrontEnd(backend) {} - - lldb::ValueObjectSP GetSyntheticValue() override { - static ConstString g___f_("__f_"); - return m_backend.GetChildMemberWithName(g___f_, true); - } -}; - -SyntheticChildrenFrontEnd * -lldb_private::formatters::LibcxxFunctionFrontEndCreator( - CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - if (valobj_sp) - return new LibcxxFunctionFrontEnd(*valobj_sp); - return nullptr; +bool lldb_private::formatters::LibcxxStringSummaryProviderASCII( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options) { + return LibcxxStringSummaryProvider( + valobj, stream, summary_options); +} + +bool lldb_private::formatters::LibcxxStringSummaryProviderUTF16( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options) { + return LibcxxStringSummaryProvider( + valobj, stream, summary_options, "u"); +} + +bool lldb_private::formatters::LibcxxStringSummaryProviderUTF32( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options) { + return LibcxxStringSummaryProvider( + valobj, stream, summary_options, "U"); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h index 3f6e0d6e14d7..224a540eda04 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxx.h @@ -19,19 +19,35 @@ namespace lldb_private { namespace formatters { -bool LibcxxStringSummaryProvider( +bool LibcxxStringSummaryProviderASCII( ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &options); // libc++ std::string + const TypeSummaryOptions &summary_options); // libc++ std::string + +bool LibcxxStringSummaryProviderUTF16( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options); // libc++ std::u16string + +bool LibcxxStringSummaryProviderUTF32( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &summary_options); // libc++ std::u32string bool LibcxxWStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libc++ std::wstring +bool LibcxxOptionalSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libc++ std::optional<> + bool LibcxxSmartPointerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options); // libc++ std::shared_ptr<> and std::weak_ptr<> +bool LibcxxFunctionSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libc++ std::function<> + SyntheticChildrenFrontEnd * LibcxxVectorBoolSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); @@ -124,15 +140,20 @@ SyntheticChildrenFrontEnd * LibcxxInitializerListSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); -SyntheticChildrenFrontEnd *LibcxxFunctionFrontEndCreator(CXXSyntheticChildren *, - lldb::ValueObjectSP); - SyntheticChildrenFrontEnd *LibcxxQueueFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); SyntheticChildrenFrontEnd *LibcxxTupleFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); +SyntheticChildrenFrontEnd * +LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp); + +SyntheticChildrenFrontEnd * +LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp); + } // namespace formatters } // namespace lldb_private diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp index 0cdb0b26cf3b..489ac4d96072 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxBitset.cpp @@ -79,17 +79,24 @@ ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { CompilerType type; ValueObjectSP chunk; // For small bitsets __first_ is not an array, but a plain size_t. - if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) - chunk = m_first->GetChildAtIndex( - idx / type.GetBitSize(ctx.GetBestExecutionContextScope()), true); - else { + if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) { + llvm::Optional bit_size = + type.GetBitSize(ctx.GetBestExecutionContextScope()); + if (!bit_size || *bit_size == 0) + return {}; + chunk = m_first->GetChildAtIndex(idx / *bit_size, true); + } else { type = m_first->GetCompilerType(); chunk = m_first; } if (!type || !chunk) - return ValueObjectSP(); + return {}; - size_t chunk_idx = idx % type.GetBitSize(ctx.GetBestExecutionContextScope()); + llvm::Optional bit_size = + type.GetBitSize(ctx.GetBestExecutionContextScope()); + if (!bit_size || *bit_size == 0) + return {}; + size_t chunk_idx = idx % *bit_size; uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx)); DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp index 5823f6f3e038..390483d02668 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxInitializerList.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "LibCxx.h" #include "lldb/Core/ValueObject.h" @@ -98,12 +94,11 @@ bool lldb_private::formatters::LibcxxInitializerListSyntheticFrontEnd:: if (!m_element_type.IsValid()) return false; - m_element_size = m_element_type.GetByteSize(nullptr); - - if (m_element_size > 0) - m_start = - m_backend.GetChildMemberWithName(g___begin_, true) - .get(); // store raw pointers or end up with a circular dependency + if (llvm::Optional size = m_element_type.GetByteSize(nullptr)) { + m_element_size = *size; + // Store raw pointers or end up with a circular dependency. + m_start = m_backend.GetChildMemberWithName(g___begin_, true).get(); + } return false; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp index 6066f14b18cc..81606b573cea 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxList.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "LibCxx.h" #include "lldb/Core/ValueObject.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp index 8f82bdcbfd59..429569d57928 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "LibCxx.h" #include "lldb/Core/ValueObject.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp new file mode 100644 index 000000000000..762b824f262a --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxOptional.cpp @@ -0,0 +1,85 @@ +//===-- LibCxxOptional.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibCxx.h" +#include "lldb/DataFormatters/FormattersHelpers.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { + +class OptionalFrontEnd : public SyntheticChildrenFrontEnd { +public: + OptionalFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { + Update(); + } + + size_t GetIndexOfChildWithName(const ConstString &name) override { + return formatters::ExtractIndexFromString(name.GetCString()); + } + + bool MightHaveChildren() override { return true; } + bool Update() override; + size_t CalculateNumChildren() override { return m_size; } + ValueObjectSP GetChildAtIndex(size_t idx) override; + +private: + size_t m_size = 0; + ValueObjectSP m_base_sp; +}; +} // namespace + +bool OptionalFrontEnd::Update() { + ValueObjectSP engaged_sp( + m_backend.GetChildMemberWithName(ConstString("__engaged_"), true)); + + if (!engaged_sp) + return false; + + // __engaged_ is a bool flag and is true if the optional contains a value. + // Converting it to unsigned gives us a size of 1 if it contains a value + // and 0 if not. + m_size = engaged_sp->GetValueAsUnsigned(0); + + return false; +} + +ValueObjectSP OptionalFrontEnd::GetChildAtIndex(size_t idx) { + if (idx >= m_size) + return ValueObjectSP(); + + // __val_ contains the underlying value of an optional if it has one. + // Currently because it is part of an anonymous union GetChildMemberWithName() + // does not peer through and find it unless we are at the parent itself. + // We can obtain the parent through __engaged_. + ValueObjectSP val_sp( + m_backend.GetChildMemberWithName(ConstString("__engaged_"), true) + ->GetParent() + ->GetChildAtIndex(0, true) + ->GetChildMemberWithName(ConstString("__val_"), true)); + + if (!val_sp) + return ValueObjectSP(); + + CompilerType holder_type = val_sp->GetCompilerType(); + + if (!holder_type) + return ValueObjectSP(); + + return val_sp->Clone(ConstString(llvm::formatv("Value").str())); +} + +SyntheticChildrenFrontEnd * +formatters::LibcxxOptionalFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp) { + if (valobj_sp) + return new OptionalFrontEnd(*valobj_sp); + return nullptr; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp index 0f1c2537d651..51ae8cb3184c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxUnorderedMap.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "LibCxx.h" #include "lldb/Core/ValueObject.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp new file mode 100644 index 000000000000..e874616c3251 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.cpp @@ -0,0 +1,256 @@ +//===-- LibCxxVariant.cpp --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LibCxxVariant.h" +#include "lldb/DataFormatters/FormattersHelpers.h" + +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/ScopeExit.h" + +using namespace lldb; +using namespace lldb_private; + +// libc++ variant implementation contains two members that we care about both +// are contained in the __impl member. +// - __index which tells us which of the variadic template types is the active +// type for the variant +// - __data is a variadic union which recursively contains itself as member +// which refers to the tailing variadic types. +// - __head which refers to the leading non pack type +// - __value refers to the actual value contained +// - __tail which refers to the remaining pack types +// +// e.g. given std::variant v1 +// +// (lldb) frame var -R v1.__impl.__data +//(... __union<... 0, int, double, char>) v1.__impl.__data = { +// ... +// __head = { +// __value = ... +// } +// __tail = { +// ... +// __head = { +// __value = ... +// } +// __tail = { +// ... +// __head = { +// __value = ... +// ... +// +// So given +// - __index equal to 0 the active value is contained in +// +// __data.__head.__value +// +// - __index equal to 1 the active value is contained in +// +// __data.__tail.__head.__value +// +// - __index equal to 2 the active value is contained in +// +// __data.__tail.__tail.__head.__value +// + +namespace { +// libc++ std::variant index could have one of three states +// 1) VALID, we can obtain it and its not variant_npos +// 2) INVALID, we can't obtain it or it is not a type we expect +// 3) NPOS, its value is variant_npos which means the variant has no value +enum class LibcxxVariantIndexValidity { VALID, INVALID, NPOS }; + +LibcxxVariantIndexValidity +LibcxxVariantGetIndexValidity(ValueObjectSP &impl_sp) { + ValueObjectSP index_sp( + impl_sp->GetChildMemberWithName(ConstString("__index"), true)); + + if (!index_sp) + return LibcxxVariantIndexValidity::INVALID; + + int64_t index_value = index_sp->GetValueAsSigned(0); + + if (index_value == -1) + return LibcxxVariantIndexValidity::NPOS; + + return LibcxxVariantIndexValidity::VALID; +} + +llvm::Optional LibcxxVariantIndexValue(ValueObjectSP &impl_sp) { + ValueObjectSP index_sp( + impl_sp->GetChildMemberWithName(ConstString("__index"), true)); + + if (!index_sp) + return {}; + + return {index_sp->GetValueAsUnsigned(0)}; +} + +ValueObjectSP LibcxxVariantGetNthHead(ValueObjectSP &impl_sp, uint64_t index) { + ValueObjectSP data_sp( + impl_sp->GetChildMemberWithName(ConstString("__data"), true)); + + if (!data_sp) + return ValueObjectSP{}; + + ValueObjectSP current_level = data_sp; + for (uint64_t n = index; n != 0; --n) { + ValueObjectSP tail_sp( + current_level->GetChildMemberWithName(ConstString("__tail"), true)); + + if (!tail_sp) + return ValueObjectSP{}; + + current_level = tail_sp; + } + + return current_level->GetChildMemberWithName(ConstString("__head"), true); +} +} // namespace + +namespace lldb_private { +namespace formatters { +bool LibcxxVariantSummaryProvider(ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options) { + ValueObjectSP valobj_sp(valobj.GetNonSyntheticValue()); + if (!valobj_sp) + return false; + + ValueObjectSP impl_sp( + valobj_sp->GetChildMemberWithName(ConstString("__impl"), true)); + + if (!impl_sp) + return false; + + LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp); + + if (validity == LibcxxVariantIndexValidity::INVALID) + return false; + + if (validity == LibcxxVariantIndexValidity::NPOS) { + stream.Printf(" No Value"); + return true; + } + + auto optional_index_value = LibcxxVariantIndexValue(impl_sp); + + if (!optional_index_value) + return false; + + uint64_t index_value = *optional_index_value; + + ValueObjectSP nth_head = LibcxxVariantGetNthHead(impl_sp, index_value); + + if (!nth_head) + return false; + + CompilerType head_type = nth_head->GetCompilerType(); + + if (!head_type) + return false; + + CompilerType template_type = head_type.GetTypeTemplateArgument(1); + + if (!template_type) + return false; + + stream.Printf(" Active Type = %s ", template_type.GetTypeName().GetCString()); + + return true; +} +} // namespace formatters +} // namespace lldb_private + +namespace { +class VariantFrontEnd : public SyntheticChildrenFrontEnd { +public: + VariantFrontEnd(ValueObject &valobj) : SyntheticChildrenFrontEnd(valobj) { + Update(); + } + + size_t GetIndexOfChildWithName(const ConstString &name) override { + return formatters::ExtractIndexFromString(name.GetCString()); + } + + bool MightHaveChildren() override { return true; } + bool Update() override; + size_t CalculateNumChildren() override { return m_size; } + ValueObjectSP GetChildAtIndex(size_t idx) override; + +private: + size_t m_size = 0; + ValueObjectSP m_base_sp; +}; +} // namespace + +bool VariantFrontEnd::Update() { + m_size = 0; + ValueObjectSP impl_sp( + m_backend.GetChildMemberWithName(ConstString("__impl"), true)); + if (!impl_sp) + return false; + + LibcxxVariantIndexValidity validity = LibcxxVariantGetIndexValidity(impl_sp); + + if (validity == LibcxxVariantIndexValidity::INVALID) + return false; + + if (validity == LibcxxVariantIndexValidity::NPOS) + return true; + + m_size = 1; + + return false; +} + +ValueObjectSP VariantFrontEnd::GetChildAtIndex(size_t idx) { + if (idx >= m_size) + return ValueObjectSP(); + + ValueObjectSP impl_sp( + m_backend.GetChildMemberWithName(ConstString("__impl"), true)); + + auto optional_index_value = LibcxxVariantIndexValue(impl_sp); + + if (!optional_index_value) + return ValueObjectSP(); + + uint64_t index_value = *optional_index_value; + + ValueObjectSP nth_head = LibcxxVariantGetNthHead(impl_sp, index_value); + + if (!nth_head) + return ValueObjectSP(); + + CompilerType head_type = nth_head->GetCompilerType(); + + if (!head_type) + return ValueObjectSP(); + + CompilerType template_type = head_type.GetTypeTemplateArgument(1); + + if (!template_type) + return ValueObjectSP(); + + ValueObjectSP head_value( + nth_head->GetChildMemberWithName(ConstString("__value"), true)); + + if (!head_value) + return ValueObjectSP(); + + return head_value->Clone(ConstString(ConstString("Value").AsCString())); +} + +SyntheticChildrenFrontEnd * +formatters::LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP valobj_sp) { + if (valobj_sp) + return new VariantFrontEnd(*valobj_sp); + return nullptr; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h new file mode 100644 index 000000000000..04834581963f --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVariant.h @@ -0,0 +1,31 @@ +//===-- LibCxxVariant.h -------------------------------------------*- C++ +//-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_LibCxxVariant_h_ +#define liblldb_LibCxxVariant_h_ + +#include "lldb/Core/ValueObject.h" +#include "lldb/DataFormatters/TypeSummary.h" +#include "lldb/DataFormatters/TypeSynthetic.h" +#include "lldb/Utility/Stream.h" + +namespace lldb_private { +namespace formatters { +bool LibcxxVariantSummaryProvider( + ValueObject &valobj, Stream &stream, + const TypeSummaryOptions &options); // libc++ std::variant<> + +SyntheticChildrenFrontEnd *LibcxxVariantFrontEndCreator(CXXSyntheticChildren *, + lldb::ValueObjectSP); + +} // namespace formatters +} // namespace lldb_private + +#endif // liblldb_LibCxxVariant_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp index 711130639cd2..ed405c875174 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibCxxVector.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "LibCxx.h" #include "lldb/Core/ValueObject.h" @@ -149,14 +145,16 @@ bool lldb_private::formatters::LibcxxStdVectorSyntheticFrontEnd::Update() { if (!data_type_finder_sp) return false; m_element_type = data_type_finder_sp->GetCompilerType().GetPointeeType(); - m_element_size = m_element_type.GetByteSize(nullptr); + if (llvm::Optional size = m_element_type.GetByteSize(nullptr)) { + m_element_size = *size; - if (m_element_size > 0) { - // store raw pointers or end up with a circular dependency - m_start = - m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get(); - m_finish = - m_backend.GetChildMemberWithName(ConstString("__end_"), true).get(); + if (m_element_size > 0) { + // store raw pointers or end up with a circular dependency + m_start = + m_backend.GetChildMemberWithName(ConstString("__begin_"), true).get(); + m_finish = + m_backend.GetChildMemberWithName(ConstString("__end_"), true).get(); + } } return false; } @@ -196,27 +194,29 @@ lldb_private::formatters::LibcxxVectorBoolSyntheticFrontEnd::GetChildAtIndex( if (iter != end) return iter->second; if (idx >= m_count) - return ValueObjectSP(); + return {}; if (m_base_data_address == 0 || m_count == 0) - return ValueObjectSP(); + return {}; if (!m_bool_type) - return ValueObjectSP(); + return {}; size_t byte_idx = (idx >> 3); // divide by 8 to get byte index size_t bit_index = (idx & 7); // efficient idx % 8 for bit index lldb::addr_t byte_location = m_base_data_address + byte_idx; ProcessSP process_sp(m_exe_ctx_ref.GetProcessSP()); if (!process_sp) - return ValueObjectSP(); + return {}; uint8_t byte = 0; uint8_t mask = 0; Status err; size_t bytes_read = process_sp->ReadMemory(byte_location, &byte, 1, err); if (err.Fail() || bytes_read == 0) - return ValueObjectSP(); + return {}; mask = 1 << bit_index; bool bit_set = ((byte & mask) != 0); - DataBufferSP buffer_sp( - new DataBufferHeap(m_bool_type.GetByteSize(nullptr), 0)); + llvm::Optional size = m_bool_type.GetByteSize(nullptr); + if (!size) + return {}; + DataBufferSP buffer_sp(new DataBufferHeap(*size, 0)); if (bit_set && buffer_sp && buffer_sp->GetBytes()) { // regardless of endianness, anything non-zero is true *(buffer_sp->GetBytes()) = 1; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp index 3e2b7159f894..695371fc3992 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/LibStdcpp.cpp @@ -9,10 +9,6 @@ #include "LibStdcpp.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/DataFormatters/StringPrinter.h" @@ -301,8 +297,11 @@ bool lldb_private::formatters::LibStdcppWStringSummaryProvider( if (!wchar_compiler_type) return false; - const uint32_t wchar_size = wchar_compiler_type.GetBitSize( - nullptr); // Safe to pass NULL for exe_scope here + // Safe to pass nullptr for exe_scope here. + llvm::Optional size = wchar_compiler_type.GetBitSize(nullptr); + if (!size) + return false; + const uint32_t wchar_size = *size; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); Status error; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp new file mode 100644 index 000000000000..84f03e0e3016 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp @@ -0,0 +1,99 @@ +//===-- MSVCUndecoratedNameParser.cpp ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MSVCUndecoratedNameParser.h" + +#include + +MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) { + std::size_t last_base_start = 0; + + std::stack stack; + unsigned int open_angle_brackets = 0; + for (size_t i = 0; i < name.size(); i++) { + switch (name[i]) { + case '<': + // Do not treat `operator<' and `operator<<' as templates + // (sometimes they represented as `<' and `<<' in the name). + if (i == last_base_start || + (i == last_base_start + 1 && name[last_base_start] == '<')) + break; + + stack.push(i); + open_angle_brackets++; + + break; + case '>': + if (!stack.empty() && name[stack.top()] == '<') { + open_angle_brackets--; + stack.pop(); + } + + break; + case '`': + stack.push(i); + + break; + case '\'': + while (!stack.empty()) { + std::size_t top = stack.top(); + if (name[top] == '<') + open_angle_brackets--; + + stack.pop(); + + if (name[top] == '`') + break; + } + + break; + case ':': + if (open_angle_brackets) + break; + if (i == 0 || name[i - 1] != ':') + break; + + m_specifiers.emplace_back(name.take_front(i - 1), + name.slice(last_base_start, i - 1)); + + last_base_start = i + 1; + break; + default: + break; + } + } + + m_specifiers.emplace_back(name, name.drop_front(last_base_start)); +} + +bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) { + return name.find('`') != llvm::StringRef::npos; +} + +bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier( + llvm::StringRef name, llvm::StringRef &context, + llvm::StringRef &identifier) { + MSVCUndecoratedNameParser parser(name); + llvm::ArrayRef specs = parser.GetSpecifiers(); + + std::size_t count = specs.size(); + identifier = count > 0 ? specs[count - 1].GetBaseName() : ""; + context = count > 1 ? specs[count - 2].GetFullName() : ""; + + return count; +} + +llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) { + MSVCUndecoratedNameParser parser(name); + llvm::ArrayRef specs = parser.GetSpecifiers(); + if (specs.empty()) + return ""; + + return specs[specs.size() - 1].GetBaseName(); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h new file mode 100644 index 000000000000..0c49100d8d49 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h @@ -0,0 +1,51 @@ +//===-- MSVCUndecoratedNameParser.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_MSVCUndecoratedNameParser_h_ +#define liblldb_MSVCUndecoratedNameParser_h_ + +#include + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" + +class MSVCUndecoratedNameSpecifier { +public: + MSVCUndecoratedNameSpecifier(llvm::StringRef full_name, + llvm::StringRef base_name) + : m_full_name(full_name), m_base_name(base_name) {} + + llvm::StringRef GetFullName() const { return m_full_name; } + llvm::StringRef GetBaseName() const { return m_base_name; } + +private: + llvm::StringRef m_full_name; + llvm::StringRef m_base_name; +}; + +class MSVCUndecoratedNameParser { +public: + explicit MSVCUndecoratedNameParser(llvm::StringRef name); + + llvm::ArrayRef GetSpecifiers() const { + return m_specifiers; + } + + static bool IsMSVCUndecoratedName(llvm::StringRef name); + static bool ExtractContextAndIdentifier(llvm::StringRef name, + llvm::StringRef &context, + llvm::StringRef &identifier); + + static llvm::StringRef DropScope(llvm::StringRef name); + +private: + std::vector m_specifiers; +}; + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp new file mode 100644 index 000000000000..1fe8482263eb --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.cpp @@ -0,0 +1,237 @@ +//===-- ClangHighlighter.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ClangHighlighter.h" + +#include "lldb/Target/Language.h" +#include "lldb/Utility/AnsiTerminal.h" +#include "lldb/Utility/StreamString.h" + +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace lldb_private; + +bool ClangHighlighter::isKeyword(llvm::StringRef token) const { + return keywords.find(token) != keywords.end(); +} + +ClangHighlighter::ClangHighlighter() { +#define KEYWORD(X, N) keywords.insert(#X); +#include "clang/Basic/TokenKinds.def" +} + +/// Determines which style should be applied to the given token. +/// \param highlighter +/// The current highlighter that should use the style. +/// \param token +/// The current token. +/// \param tok_str +/// The string in the source code the token represents. +/// \param options +/// The style we use for coloring the source code. +/// \param in_pp_directive +/// If we are currently in a preprocessor directive. NOTE: This is +/// passed by reference and will be updated if the current token starts +/// or ends a preprocessor directive. +/// \return +/// The ColorStyle that should be applied to the token. +static HighlightStyle::ColorStyle +determineClangStyle(const ClangHighlighter &highlighter, + const clang::Token &token, llvm::StringRef tok_str, + const HighlightStyle &options, bool &in_pp_directive) { + using namespace clang; + + if (token.is(tok::comment)) { + // If we were in a preprocessor directive before, we now left it. + in_pp_directive = false; + return options.comment; + } else if (in_pp_directive || token.getKind() == tok::hash) { + // Let's assume that the rest of the line is a PP directive. + in_pp_directive = true; + // Preprocessor directives are hard to match, so we have to hack this in. + return options.pp_directive; + } else if (tok::isStringLiteral(token.getKind())) + return options.string_literal; + else if (tok::isLiteral(token.getKind())) + return options.scalar_literal; + else if (highlighter.isKeyword(tok_str)) + return options.keyword; + else + switch (token.getKind()) { + case tok::raw_identifier: + case tok::identifier: + return options.identifier; + case tok::l_brace: + case tok::r_brace: + return options.braces; + case tok::l_square: + case tok::r_square: + return options.square_brackets; + case tok::l_paren: + case tok::r_paren: + return options.parentheses; + case tok::comma: + return options.comma; + case tok::coloncolon: + case tok::colon: + return options.colon; + + case tok::amp: + case tok::ampamp: + case tok::ampequal: + case tok::star: + case tok::starequal: + case tok::plus: + case tok::plusplus: + case tok::plusequal: + case tok::minus: + case tok::arrow: + case tok::minusminus: + case tok::minusequal: + case tok::tilde: + case tok::exclaim: + case tok::exclaimequal: + case tok::slash: + case tok::slashequal: + case tok::percent: + case tok::percentequal: + case tok::less: + case tok::lessless: + case tok::lessequal: + case tok::lesslessequal: + case tok::spaceship: + case tok::greater: + case tok::greatergreater: + case tok::greaterequal: + case tok::greatergreaterequal: + case tok::caret: + case tok::caretequal: + case tok::pipe: + case tok::pipepipe: + case tok::pipeequal: + case tok::question: + case tok::equal: + case tok::equalequal: + return options.operators; + default: + break; + } + return HighlightStyle::ColorStyle(); +} + +void ClangHighlighter::Highlight(const HighlightStyle &options, + llvm::StringRef line, + llvm::Optional cursor_pos, + llvm::StringRef previous_lines, + Stream &result) const { + using namespace clang; + + FileSystemOptions file_opts; + FileManager file_mgr(file_opts); + + unsigned line_number = previous_lines.count('\n') + 1U; + + // Let's build the actual source code Clang needs and setup some utility + // objects. + std::string full_source = previous_lines.str() + line.str(); + llvm::IntrusiveRefCntPtr diag_ids(new DiagnosticIDs()); + llvm::IntrusiveRefCntPtr diags_opts( + new DiagnosticOptions()); + DiagnosticsEngine diags(diag_ids, diags_opts); + clang::SourceManager SM(diags, file_mgr); + auto buf = llvm::MemoryBuffer::getMemBuffer(full_source); + + FileID FID = SM.createFileID(clang::SourceManager::Unowned, buf.get()); + + // Let's just enable the latest ObjC and C++ which should get most tokens + // right. + LangOptions Opts; + Opts.ObjC = true; + // FIXME: This should probably set CPlusPlus, CPlusPlus11, ... too + Opts.CPlusPlus17 = true; + Opts.LineComment = true; + + Lexer lex(FID, buf.get(), SM, Opts); + // The lexer should keep whitespace around. + lex.SetKeepWhitespaceMode(true); + + // Keeps track if we have entered a PP directive. + bool in_pp_directive = false; + + // True once we actually lexed the user provided line. + bool found_user_line = false; + + // True if we already highlighted the token under the cursor, false otherwise. + bool highlighted_cursor = false; + Token token; + bool exit = false; + while (!exit) { + // Returns true if this is the last token we get from the lexer. + exit = lex.LexFromRawLexer(token); + + bool invalid = false; + unsigned current_line_number = + SM.getSpellingLineNumber(token.getLocation(), &invalid); + if (current_line_number != line_number) + continue; + found_user_line = true; + + // We don't need to print any tokens without a spelling line number. + if (invalid) + continue; + + // Same as above but with the column number. + invalid = false; + unsigned start = SM.getSpellingColumnNumber(token.getLocation(), &invalid); + if (invalid) + continue; + // Column numbers start at 1, but indexes in our string start at 0. + --start; + + // Annotations don't have a length, so let's skip them. + if (token.isAnnotation()) + continue; + + // Extract the token string from our source code. + llvm::StringRef tok_str = line.substr(start, token.getLength()); + + // If the token is just an empty string, we can skip all the work below. + if (tok_str.empty()) + continue; + + // If the cursor is inside this token, we have to apply the 'selected' + // highlight style before applying the actual token color. + llvm::StringRef to_print = tok_str; + StreamString storage; + auto end = start + token.getLength(); + if (cursor_pos && end > *cursor_pos && !highlighted_cursor) { + highlighted_cursor = true; + options.selected.Apply(storage, tok_str); + to_print = storage.GetString(); + } + + // See how we are supposed to highlight this token. + HighlightStyle::ColorStyle color = + determineClangStyle(*this, token, tok_str, options, in_pp_directive); + + color.Apply(result, to_print); + } + + // If we went over the whole file but couldn't find our own file, then + // somehow our setup was wrong. When we're in release mode we just give the + // user the normal line and pretend we don't know how to highlight it. In + // debug mode we bail out with an assert as this should never happen. + if (!found_user_line) { + result << line; + assert(false && "We couldn't find the user line in the input file?"); + } +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h b/contrib/llvm/tools/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h new file mode 100644 index 000000000000..579c4315228f --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ClangCommon/ClangHighlighter.h @@ -0,0 +1,38 @@ +//===-- ClangHighlighter.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangHighlighter_h_ +#define liblldb_ClangHighlighter_h_ + +#include "lldb/Utility/Stream.h" +#include "llvm/ADT/StringSet.h" + +#include "lldb/Core/Highlighter.h" + +namespace lldb_private { + +class ClangHighlighter : public Highlighter { + llvm::StringSet<> keywords; + +public: + ClangHighlighter(); + llvm::StringRef GetName() const override { return "clang"; } + + void Highlight(const HighlightStyle &options, llvm::StringRef line, + llvm::Optional cursor_pos, + llvm::StringRef previous_lines, Stream &s) const override; + + /// Returns true if the given string represents a keywords in any Clang + /// supported language. + bool isKeyword(llvm::StringRef token) const; +}; + +} // namespace lldb_private + +#endif // liblldb_ClangHighlighter_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoFormatterFunctions.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoFormatterFunctions.cpp deleted file mode 100644 index aac75205c6ef..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoFormatterFunctions.cpp +++ /dev/null @@ -1,152 +0,0 @@ -//===-- GoFormatterFunctions.cpp---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -// Project includes -#include "GoFormatterFunctions.h" -#include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/DataFormatters/StringPrinter.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::formatters; - -namespace { -class GoSliceSyntheticFrontEnd : public SyntheticChildrenFrontEnd { -public: - GoSliceSyntheticFrontEnd(ValueObject &valobj) - : SyntheticChildrenFrontEnd(valobj) { - Update(); - } - - ~GoSliceSyntheticFrontEnd() override = default; - - size_t CalculateNumChildren() override { return m_len; } - - lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { - if (idx < m_len) { - ValueObjectSP &cached = m_children[idx]; - if (!cached) { - StreamString idx_name; - idx_name.Printf("[%" PRIu64 "]", (uint64_t)idx); - lldb::addr_t object_at_idx = m_base_data_address; - object_at_idx += idx * m_type.GetByteSize(nullptr); - cached = CreateValueObjectFromAddress( - idx_name.GetString(), object_at_idx, - m_backend.GetExecutionContextRef(), m_type); - } - return cached; - } - return ValueObjectSP(); - } - - bool Update() override { - size_t old_count = m_len; - - ConstString array_const_str("array"); - ValueObjectSP array_sp = - m_backend.GetChildMemberWithName(array_const_str, true); - if (!array_sp) { - m_children.clear(); - return old_count == 0; - } - m_type = array_sp->GetCompilerType().GetPointeeType(); - m_base_data_address = array_sp->GetPointerValue(); - - ConstString len_const_str("len"); - ValueObjectSP len_sp = - m_backend.GetChildMemberWithName(len_const_str, true); - if (len_sp) { - m_len = len_sp->GetValueAsUnsigned(0); - m_children.clear(); - } - - return old_count == m_len; - } - - bool MightHaveChildren() override { return true; } - - size_t GetIndexOfChildWithName(const ConstString &name) override { - return ExtractIndexFromString(name.AsCString()); - } - -private: - CompilerType m_type; - lldb::addr_t m_base_data_address; - size_t m_len; - std::map m_children; -}; - -} // anonymous namespace - -bool lldb_private::formatters::GoStringSummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) { - ProcessSP process_sp = valobj.GetProcessSP(); - if (!process_sp) - return false; - - if (valobj.IsPointerType()) { - Status err; - ValueObjectSP deref = valobj.Dereference(err); - if (!err.Success()) - return false; - return GoStringSummaryProvider(*deref, stream, opts); - } - - ConstString str_name("str"); - ConstString len_name("len"); - - ValueObjectSP data_sp = valobj.GetChildMemberWithName(str_name, true); - ValueObjectSP len_sp = valobj.GetChildMemberWithName(len_name, true); - if (!data_sp || !len_sp) - return false; - bool success; - lldb::addr_t valobj_addr = data_sp->GetValueAsUnsigned(0, &success); - - if (!success) - return false; - - uint64_t length = len_sp->GetValueAsUnsigned(0); - if (length == 0) { - stream.Printf("\"\""); - return true; - } - - StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); - options.SetLocation(valobj_addr); - options.SetProcessSP(process_sp); - options.SetStream(&stream); - options.SetSourceSize(length); - options.SetNeedsZeroTermination(false); - options.SetLanguage(eLanguageTypeGo); - - if (!StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF8>(options)) { - stream.Printf("Summary Unavailable"); - return true; - } - - return true; -} - -SyntheticChildrenFrontEnd * -lldb_private::formatters::GoSliceSyntheticFrontEndCreator( - CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - if (!valobj_sp) - return nullptr; - - lldb::ProcessSP process_sp(valobj_sp->GetProcessSP()); - if (!process_sp) - return nullptr; - return new GoSliceSyntheticFrontEnd(*valobj_sp); -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoFormatterFunctions.h b/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoFormatterFunctions.h deleted file mode 100644 index 1bf1892d6669..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoFormatterFunctions.h +++ /dev/null @@ -1,43 +0,0 @@ -//===-- GoFormatterFunctions.h-----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_GoFormatterFunctions_h_ -#define liblldb_GoFormatterFunctions_h_ - -// C Includes -#include -#include - -// C++ Includes -// Other libraries and framework includes -#include "clang/AST/ASTContext.h" - -// Project includes -#include "lldb/lldb-forward.h" - -#include "lldb/DataFormatters/FormatClasses.h" -#include "lldb/DataFormatters/TypeSynthetic.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/ObjCLanguageRuntime.h" -#include "lldb/Target/Target.h" -#include "lldb/Utility/ConstString.h" - -namespace lldb_private { -namespace formatters { - -bool GoStringSummaryProvider(ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &options); - -SyntheticChildrenFrontEnd * -GoSliceSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP); - -} // namespace formatters -} // namespace lldb_private - -#endif // liblldb_GoFormatterFunctions_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoLanguage.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoLanguage.cpp deleted file mode 100644 index 66b4530abc76..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoLanguage.cpp +++ /dev/null @@ -1,127 +0,0 @@ -//===-- GoLanguage.cpp ------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include -// C++ Includes -#include -#include - -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Threading.h" - -// Project includes -#include "GoLanguage.h" -#include "Plugins/Language/Go/GoFormatterFunctions.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/GoASTContext.h" -#include "lldb/Utility/ConstString.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::formatters; - -void GoLanguage::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language", - CreateInstance); -} - -void GoLanguage::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -lldb_private::ConstString GoLanguage::GetPluginNameStatic() { - static ConstString g_name("Go"); - return g_name; -} - -//------------------------------------------------------------------ -// PluginInterface protocol -//------------------------------------------------------------------ -lldb_private::ConstString GoLanguage::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t GoLanguage::GetPluginVersion() { return 1; } - -//------------------------------------------------------------------ -// Static Functions -//------------------------------------------------------------------ -Language *GoLanguage::CreateInstance(lldb::LanguageType language) { - if (language == eLanguageTypeGo) - return new GoLanguage(); - return nullptr; -} - -HardcodedFormatters::HardcodedSummaryFinder -GoLanguage::GetHardcodedSummaries() { - static llvm::once_flag g_initialize; - static HardcodedFormatters::HardcodedSummaryFinder g_formatters; - - llvm::call_once(g_initialize, []() -> void { - g_formatters.push_back( - [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, - FormatManager &) -> TypeSummaryImpl::SharedPointer { - static CXXFunctionSummaryFormat::SharedPointer formatter_sp( - new CXXFunctionSummaryFormat( - TypeSummaryImpl::Flags().SetDontShowChildren(true), - lldb_private::formatters::GoStringSummaryProvider, - "Go string summary provider")); - if (GoASTContext::IsGoString(valobj.GetCompilerType())) { - return formatter_sp; - } - if (GoASTContext::IsGoString( - valobj.GetCompilerType().GetPointeeType())) { - return formatter_sp; - } - return nullptr; - }); - g_formatters.push_back( - [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, - FormatManager &) -> TypeSummaryImpl::SharedPointer { - static lldb::TypeSummaryImplSP formatter_sp(new StringSummaryFormat( - TypeSummaryImpl::Flags().SetHideItemNames(true), - "(len ${var.len}, cap ${var.cap})")); - if (GoASTContext::IsGoSlice(valobj.GetCompilerType())) { - return formatter_sp; - } - if (GoASTContext::IsGoSlice( - valobj.GetCompilerType().GetPointeeType())) { - return formatter_sp; - } - return nullptr; - }); - }); - return g_formatters; -} - -HardcodedFormatters::HardcodedSyntheticFinder -GoLanguage::GetHardcodedSynthetics() { - static llvm::once_flag g_initialize; - static HardcodedFormatters::HardcodedSyntheticFinder g_formatters; - - llvm::call_once(g_initialize, []() -> void { - g_formatters.push_back( - [](lldb_private::ValueObject &valobj, lldb::DynamicValueType, - FormatManager &fmt_mgr) -> SyntheticChildren::SharedPointer { - static CXXSyntheticChildren::SharedPointer formatter_sp( - new CXXSyntheticChildren( - SyntheticChildren::Flags(), "slice synthetic children", - lldb_private::formatters::GoSliceSyntheticFrontEndCreator)); - if (GoASTContext::IsGoSlice(valobj.GetCompilerType())) { - return formatter_sp; - } - return nullptr; - }); - }); - - return g_formatters; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoLanguage.h b/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoLanguage.h deleted file mode 100644 index ebec1d7205fa..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/Go/GoLanguage.h +++ /dev/null @@ -1,63 +0,0 @@ -//===-- GoLanguage.h --------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_GoLanguage_h_ -#define liblldb_GoLanguage_h_ - -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" - -// Project includes -#include "lldb/Target/Language.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/lldb-private.h" - -namespace lldb_private { - -class GoLanguage : public Language { -public: - GoLanguage() = default; - - ~GoLanguage() override = default; - - lldb::LanguageType GetLanguageType() const override { - return lldb::eLanguageTypeGo; - } - - HardcodedFormatters::HardcodedSummaryFinder GetHardcodedSummaries() override; - - HardcodedFormatters::HardcodedSyntheticFinder - GetHardcodedSynthetics() override; - - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static void Initialize(); - - static void Terminate(); - - static lldb_private::Language *CreateInstance(lldb::LanguageType language); - - static lldb_private::ConstString GetPluginNameStatic(); - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; -}; - -} // namespace lldb_private - -#endif // liblldb_GoLanguage_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp deleted file mode 100644 index 498795c90be8..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.cpp +++ /dev/null @@ -1,167 +0,0 @@ -//===-- JavaFormatterFunctions.cpp-------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "JavaFormatterFunctions.h" -#include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/DataFormatters/StringPrinter.h" -#include "lldb/Symbol/JavaASTContext.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::formatters; - -namespace { - -class JavaArraySyntheticFrontEnd : public SyntheticChildrenFrontEnd { -public: - JavaArraySyntheticFrontEnd(lldb::ValueObjectSP valobj_sp) - : SyntheticChildrenFrontEnd(*valobj_sp) { - if (valobj_sp) - Update(); - } - - size_t CalculateNumChildren() override { - ValueObjectSP valobj = GetDereferencedValueObject(); - if (!valobj) - return 0; - - CompilerType type = valobj->GetCompilerType(); - uint32_t size = JavaASTContext::CalculateArraySize(type, *valobj); - if (size == UINT32_MAX) - return 0; - return size; - } - - lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { - ValueObjectSP valobj = GetDereferencedValueObject(); - if (!valobj) - return nullptr; - - ProcessSP process_sp = valobj->GetProcessSP(); - if (!process_sp) - return nullptr; - - CompilerType type = valobj->GetCompilerType(); - CompilerType element_type = type.GetArrayElementType(); - lldb::addr_t address = - valobj->GetAddressOf() + - JavaASTContext::CalculateArrayElementOffset(type, idx); - - Status error; - size_t byte_size = element_type.GetByteSize(nullptr); - DataBufferSP buffer_sp(new DataBufferHeap(byte_size, 0)); - size_t bytes_read = process_sp->ReadMemory(address, buffer_sp->GetBytes(), - byte_size, error); - if (error.Fail() || byte_size != bytes_read) - return nullptr; - - StreamString name; - name.Printf("[%" PRIu64 "]", (uint64_t)idx); - DataExtractor data(buffer_sp, process_sp->GetByteOrder(), - process_sp->GetAddressByteSize()); - return CreateValueObjectFromData( - name.GetString(), data, valobj->GetExecutionContextRef(), element_type); - } - - bool Update() override { return false; } - - bool MightHaveChildren() override { return true; } - - size_t GetIndexOfChildWithName(const ConstString &name) override { - return ExtractIndexFromString(name.GetCString()); - } - -private: - ValueObjectSP GetDereferencedValueObject() { - if (!m_backend.IsPointerOrReferenceType()) - return m_backend.GetSP(); - - Status error; - return m_backend.Dereference(error); - } -}; - -} // end of anonymous namespace - -bool lldb_private::formatters::JavaStringSummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) { - if (valobj.IsPointerOrReferenceType()) { - Status error; - ValueObjectSP deref = valobj.Dereference(error); - if (error.Fail()) - return false; - return JavaStringSummaryProvider(*deref, stream, opts); - } - - ProcessSP process_sp = valobj.GetProcessSP(); - if (!process_sp) - return false; - - ConstString data_name("value"); - ConstString length_name("count"); - - ValueObjectSP length_sp = valobj.GetChildMemberWithName(length_name, true); - ValueObjectSP data_sp = valobj.GetChildMemberWithName(data_name, true); - if (!data_sp || !length_sp) - return false; - - bool success = false; - uint64_t length = length_sp->GetValueAsUnsigned(0, &success); - if (!success) - return false; - - if (length == 0) { - stream.Printf("\"\""); - return true; - } - lldb::addr_t valobj_addr = data_sp->GetAddressOf(); - - StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); - options.SetLocation(valobj_addr); - options.SetProcessSP(process_sp); - options.SetStream(&stream); - options.SetSourceSize(length); - options.SetNeedsZeroTermination(false); - options.SetLanguage(eLanguageTypeJava); - - if (StringPrinter::ReadStringAndDumpToStream< - StringPrinter::StringElementType::UTF16>(options)) - return true; - - stream.Printf("Summary Unavailable"); - return true; -} - -bool lldb_private::formatters::JavaArraySummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { - if (valobj.IsPointerOrReferenceType()) { - Status error; - ValueObjectSP deref = valobj.Dereference(error); - if (error.Fail()) - return false; - return JavaArraySummaryProvider(*deref, stream, options); - } - - CompilerType type = valobj.GetCompilerType(); - uint32_t size = JavaASTContext::CalculateArraySize(type, valobj); - if (size == UINT32_MAX) - return false; - stream.Printf("[%u]{...}", size); - return true; -} - -SyntheticChildrenFrontEnd * -lldb_private::formatters::JavaArraySyntheticFrontEndCreator( - CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) { - return valobj_sp ? new JavaArraySyntheticFrontEnd(valobj_sp) : nullptr; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.h b/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.h deleted file mode 100644 index d1983429529c..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaFormatterFunctions.h +++ /dev/null @@ -1,35 +0,0 @@ -//===-- JavaFormatterFunctions.h---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_JavaFormatterFunctions_h_ -#define liblldb_JavaFormatterFunctions_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-forward.h" - -namespace lldb_private { -namespace formatters { - -bool JavaStringSummaryProvider(ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &options); - -bool JavaArraySummaryProvider(ValueObject &valobj, Stream &stream, - const TypeSummaryOptions &options); - -SyntheticChildrenFrontEnd * -JavaArraySyntheticFrontEndCreator(CXXSyntheticChildren *, - lldb::ValueObjectSP valobj_sp); - -} // namespace formatters -} // namespace lldb_private - -#endif // liblldb_JavaFormatterFunctions_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaLanguage.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaLanguage.cpp deleted file mode 100644 index b17862f0b6a2..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaLanguage.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//===-- JavaLanguage.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include -// C++ Includes -#include -#include - -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Threading.h" - -// Project includes -#include "JavaFormatterFunctions.h" -#include "JavaLanguage.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/DataFormatters/DataVisualization.h" -#include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/JavaASTContext.h" -#include "lldb/Utility/ConstString.h" - -using namespace lldb; -using namespace lldb_private; -using namespace lldb_private::formatters; - -void JavaLanguage::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java Language", - CreateInstance); -} - -void JavaLanguage::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -lldb_private::ConstString JavaLanguage::GetPluginNameStatic() { - static ConstString g_name("Java"); - return g_name; -} - -lldb_private::ConstString JavaLanguage::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t JavaLanguage::GetPluginVersion() { return 1; } - -Language *JavaLanguage::CreateInstance(lldb::LanguageType language) { - if (language == eLanguageTypeJava) - return new JavaLanguage(); - return nullptr; -} - -bool JavaLanguage::IsNilReference(ValueObject &valobj) { - if (!valobj.GetCompilerType().IsReferenceType()) - return false; - - // If we failed to read the value then it is not a nil reference. - return valobj.GetValueAsUnsigned(UINT64_MAX) == 0; -} - -lldb::TypeCategoryImplSP JavaLanguage::GetFormatters() { - static llvm::once_flag g_initialize; - static TypeCategoryImplSP g_category; - - llvm::call_once(g_initialize, [this]() -> void { - DataVisualization::Categories::GetCategory(GetPluginName(), g_category); - if (g_category) { - llvm::StringRef array_regexp("^.*\\[\\]&?$"); - - lldb::TypeSummaryImplSP string_summary_sp(new CXXFunctionSummaryFormat( - TypeSummaryImpl::Flags().SetDontShowChildren(true), - lldb_private::formatters::JavaStringSummaryProvider, - "java.lang.String summary provider")); - g_category->GetTypeSummariesContainer()->Add( - ConstString("java::lang::String"), string_summary_sp); - - lldb::TypeSummaryImplSP array_summary_sp(new CXXFunctionSummaryFormat( - TypeSummaryImpl::Flags().SetDontShowChildren(true), - lldb_private::formatters::JavaArraySummaryProvider, - "Java array summary provider")); - g_category->GetRegexTypeSummariesContainer()->Add( - RegularExpressionSP(new RegularExpression(array_regexp)), - array_summary_sp); - -#ifndef LLDB_DISABLE_PYTHON - AddCXXSynthetic( - g_category, - lldb_private::formatters::JavaArraySyntheticFrontEndCreator, - "Java array synthetic children", ConstString(array_regexp), - SyntheticChildren::Flags().SetCascades(true), true); -#endif - } - }); - return g_category; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaLanguage.h b/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaLanguage.h deleted file mode 100644 index 5b652502a3d1..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/Java/JavaLanguage.h +++ /dev/null @@ -1,52 +0,0 @@ -//===-- JavaLanguage.h ------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_JavaLanguage_h_ -#define liblldb_JavaLanguage_h_ - -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" - -// Project includes -#include "lldb/Target/Language.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/lldb-private.h" - -namespace lldb_private { - -class JavaLanguage : public Language { -public: - lldb::LanguageType GetLanguageType() const override { - return lldb::eLanguageTypeJava; - } - - static void Initialize(); - - static void Terminate(); - - static lldb_private::Language *CreateInstance(lldb::LanguageType language); - - static lldb_private::ConstString GetPluginNameStatic(); - - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - bool IsNilReference(ValueObject &valobj) override; - - lldb::TypeCategoryImplSP GetFormatters() override; -}; - -} // namespace lldb_private - -#endif // liblldb_JavaLanguage_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/OCaml/OCamlLanguage.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/OCaml/OCamlLanguage.cpp deleted file mode 100644 index ec24a36fe8f3..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/OCaml/OCamlLanguage.cpp +++ /dev/null @@ -1,63 +0,0 @@ -//===-- OCamlLanguage.cpp ----------------------------------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -#include -// C++ Includes -#include -#include - -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" - -// Project includes -#include "OCamlLanguage.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/DataFormatters/DataVisualization.h" -#include "lldb/DataFormatters/FormattersHelpers.h" -#include "lldb/Symbol/OCamlASTContext.h" -#include "lldb/Utility/ConstString.h" - -using namespace lldb; -using namespace lldb_private; - -void OCamlLanguage::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), "OCaml Language", - CreateInstance); -} - -void OCamlLanguage::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -lldb_private::ConstString OCamlLanguage::GetPluginNameStatic() { - static ConstString g_name("OCaml"); - return g_name; -} - -lldb_private::ConstString OCamlLanguage::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t OCamlLanguage::GetPluginVersion() { return 1; } - -Language *OCamlLanguage::CreateInstance(lldb::LanguageType language) { - if (language == eLanguageTypeOCaml) - return new OCamlLanguage(); - return nullptr; -} - -bool OCamlLanguage::IsNilReference(ValueObject &valobj) { - if (!valobj.GetCompilerType().IsReferenceType()) - return false; - - // If we failed to read the value then it is not a nil reference. - return valobj.GetValueAsUnsigned(UINT64_MAX) == 0; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/OCaml/OCamlLanguage.h b/contrib/llvm/tools/lldb/source/Plugins/Language/OCaml/OCamlLanguage.h deleted file mode 100644 index 21837fe5add4..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/OCaml/OCamlLanguage.h +++ /dev/null @@ -1,51 +0,0 @@ -//===-- OCamlLanguage.h ------------------------------------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_OCamlLanguage_h_ -#define liblldb_OCamlLanguage_h_ - -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -#include "llvm/ADT/StringRef.h" - -// Project includes -#include "lldb/Target/Language.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/lldb-private.h" - -namespace lldb_private { - -class OCamlLanguage : public Language { -public: - lldb::LanguageType GetLanguageType() const override { - return lldb::eLanguageTypeOCaml; - } - - static void Initialize(); - - static void Terminate(); - - static lldb_private::Language *CreateInstance(lldb::LanguageType language); - - static lldb_private::ConstString GetPluginNameStatic(); - - ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - bool IsNilReference(ValueObject &valobj) override; -}; - -} // namespace lldb_private - -#endif // liblldb_OCamlLanguage_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/CF.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/CF.cpp index 9bb8eeab1d2e..e3dab5a1442d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/CF.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/CF.cpp @@ -149,7 +149,7 @@ bool lldb_private::formatters::CFBitVectorSummaryProvider( } } - if (is_type_ok == false) + if (!is_type_ok) return false; Status error; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/Cocoa.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/Cocoa.cpp index 8f278fc2d513..48085378939e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/Cocoa.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/Cocoa.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Cocoa.h" #include "lldb/Core/Mangled.h" @@ -746,6 +742,59 @@ bool lldb_private::formatters::NSURLSummaryProvider( return false; } +/// Bias value for tagged pointer exponents. +/// Recommended values: +/// 0x3e3: encodes all dates between distantPast and distantFuture +/// except for the range within about 1e-28 second of the reference date. +/// 0x3ef: encodes all dates for a few million years beyond distantPast and +/// distantFuture, except within about 1e-25 second of the reference date. +const int TAGGED_DATE_EXPONENT_BIAS = 0x3ef; + +typedef union { + struct { + uint64_t fraction:52; // unsigned + uint64_t exponent:11; // signed + uint64_t sign:1; + }; + uint64_t i; + double d; +} DoubleBits; +typedef union { + struct { + uint64_t fraction:52; // unsigned + uint64_t exponent:7; // signed + uint64_t sign:1; + uint64_t unused:4; // placeholder for pointer tag bits + }; + uint64_t i; +} TaggedDoubleBits; + +static uint64_t decodeExponent(uint64_t exp) { + // Tagged exponent field is 7-bit signed. Sign-extend the value to 64 bits + // before performing arithmetic. + return llvm::SignExtend64<7>(exp) + TAGGED_DATE_EXPONENT_BIAS; +} + +static uint64_t decodeTaggedTimeInterval(uint64_t encodedTimeInterval) { + if (encodedTimeInterval == 0) + return 0.0; + if (encodedTimeInterval == std::numeric_limits::max()) + return (uint64_t)-0.0; + + TaggedDoubleBits encodedBits = {}; + encodedBits.i = encodedTimeInterval; + DoubleBits decodedBits; + + // Sign and fraction are represented exactly. + // Exponent is encoded. + assert(encodedBits.unused == 0); + decodedBits.sign = encodedBits.sign; + decodedBits.fraction = encodedBits.fraction; + decodedBits.exponent = decodeExponent(encodedBits.exponent); + + return decodedBits.d; +} + bool lldb_private::formatters::NSDateSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { ProcessSP process_sp = valobj.GetProcessSP(); @@ -785,9 +834,9 @@ bool lldb_private::formatters::NSDateSummaryProvider( if (class_name.IsEmpty()) return false; + uint64_t info_bits = 0, value_bits = 0; if ((class_name == g_NSDate) || (class_name == g___NSDate) || (class_name == g___NSTaggedDate)) { - uint64_t info_bits = 0, value_bits = 0; if (descriptor->GetTaggedPointerInfo(&info_bits, &value_bits)) { date_value_bits = ((value_bits << 8) | (info_bits << 4)); memcpy(&date_value, &date_value_bits, sizeof(date_value_bits)); @@ -817,6 +866,14 @@ bool lldb_private::formatters::NSDateSummaryProvider( stream.Printf("0001-12-30 00:00:00 +0000"); return true; } + + // Accomodate for the __NSTaggedDate format introduced in Foundation 1600. + if (class_name == g___NSTaggedDate) { + auto *runtime = llvm::dyn_cast_or_null(process_sp->GetObjCLanguageRuntime()); + if (runtime && runtime->GetFoundationVersion() >= 1600) + date_value = decodeTaggedTimeInterval(value_bits << 4); + } + // this snippet of code assumes that time_t == seconds since Jan-1-1970 this // is generally true and POSIXly happy, but might break if a library vendor // decides to get creative diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSArray.cpp index f6d159201951..6c110da9ecc2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSArray.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSArray.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "clang/AST/ASTContext.h" -// Project includes #include "Cocoa.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" @@ -218,6 +214,25 @@ namespace Foundation1437 { } +namespace CallStackArray { +struct DataDescriptor_32 { + uint32_t _data; + uint32_t _used; + uint32_t _offset; + const uint32_t _size = 0; +}; + +struct DataDescriptor_64 { + uint64_t _data; + uint64_t _used; + uint64_t _offset; + const uint64_t _size = 0; +}; + +using NSCallStackArraySyntheticFrontEnd = + GenericNSArrayMSyntheticFrontEnd; +} // namespace CallStackArray + template class GenericNSArrayISyntheticFrontEnd : public SyntheticChildrenFrontEnd { public: @@ -368,6 +383,7 @@ bool lldb_private::formatters::NSArraySummaryProvider( static const ConstString g_NSArrayCF("__NSCFArray"); static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy"); static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable"); + static const ConstString g_NSCallStackArray("_NSCallStackArray"); if (class_name.IsEmpty()) return false; @@ -417,7 +433,9 @@ bool lldb_private::formatters::NSArraySummaryProvider( value = 0; } else if (class_name == g_NSArray1) { value = 1; - } else if (class_name == g_NSArrayCF) { + } else if (class_name == g_NSArrayCF || class_name == g_NSCallStackArray) { + // __NSCFArray and _NSCallStackArray store the number of elements as a + // pointer-sized value at offset `2 * ptr_size`. Status error; value = process_sp->ReadUnsignedIntegerFromMemory( valobj_addr + 2 * ptr_size, ptr_size, 0, error); @@ -817,6 +835,7 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator( static const ConstString g_NSArray1("__NSSingleObjectArrayI"); static const ConstString g_NSArrayMLegacy("__NSArrayM_Legacy"); static const ConstString g_NSArrayMImmutable("__NSArrayM_Immutable"); + static const ConstString g_NSCallStackArray("_NSCallStackArray"); if (class_name.IsEmpty()) return nullptr; @@ -846,6 +865,8 @@ lldb_private::formatters::NSArraySyntheticFrontEndCreator( return (new Foundation1010::NSArrayMSyntheticFrontEnd(valobj_sp)); else return (new Foundation109::NSArrayMSyntheticFrontEnd(valobj_sp)); + } else if (class_name == g_NSCallStackArray) { + return (new CallStackArray::NSCallStackArraySyntheticFrontEnd(valobj_sp)); } else { auto &map(NSArray_Additionals::GetAdditionalSynthetics()); auto iter = map.find(class_name), end = map.end(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp index 5be051b46bd6..9a7fc2bd97cb 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSDictionary.cpp @@ -7,14 +7,10 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "clang/AST/DeclCXX.h" -// Project includes #include "NSDictionary.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSError.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSError.cpp index 77721e2db326..975bda5179f2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSError.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSError.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "clang/AST/DeclCXX.h" -// Project includes #include "Cocoa.h" #include "lldb/Core/ValueObject.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSException.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSException.cpp index c6970efae4d3..2404ef9d1003 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSException.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSException.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "clang/AST/DeclCXX.h" -// Project includes #include "Cocoa.h" #include "lldb/Core/ValueObject.h" @@ -33,52 +29,78 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::formatters; -bool lldb_private::formatters::NSException_SummaryProvider( - ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { +static bool ExtractFields(ValueObject &valobj, ValueObjectSP *name_sp, + ValueObjectSP *reason_sp, ValueObjectSP *userinfo_sp, + ValueObjectSP *reserved_sp) { ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return false; - lldb::addr_t ptr_value = LLDB_INVALID_ADDRESS; + lldb::addr_t ptr = LLDB_INVALID_ADDRESS; CompilerType valobj_type(valobj.GetCompilerType()); Flags type_flags(valobj_type.GetTypeInfo()); if (type_flags.AllClear(eTypeHasValue)) { if (valobj.IsBaseClass() && valobj.GetParent()) - ptr_value = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - } else - ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + ptr = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + } else { + ptr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + } - if (ptr_value == LLDB_INVALID_ADDRESS) + if (ptr == LLDB_INVALID_ADDRESS) return false; size_t ptr_size = process_sp->GetAddressByteSize(); - lldb::addr_t name_location = ptr_value + 1 * ptr_size; - lldb::addr_t reason_location = ptr_value + 2 * ptr_size; Status error; - lldb::addr_t name = process_sp->ReadPointerFromMemory(name_location, error); + auto name = process_sp->ReadPointerFromMemory(ptr + 1 * ptr_size, error); if (error.Fail() || name == LLDB_INVALID_ADDRESS) return false; - - lldb::addr_t reason = - process_sp->ReadPointerFromMemory(reason_location, error); + auto reason = process_sp->ReadPointerFromMemory(ptr + 2 * ptr_size, error); if (error.Fail() || reason == LLDB_INVALID_ADDRESS) return false; + auto userinfo = process_sp->ReadPointerFromMemory(ptr + 3 * ptr_size, error); + if (error.Fail() || userinfo == LLDB_INVALID_ADDRESS) + return false; + auto reserved = process_sp->ReadPointerFromMemory(ptr + 4 * ptr_size, error); + if (error.Fail() || reserved == LLDB_INVALID_ADDRESS) + return false; InferiorSizedWord name_isw(name, *process_sp); InferiorSizedWord reason_isw(reason, *process_sp); + InferiorSizedWord userinfo_isw(userinfo, *process_sp); + InferiorSizedWord reserved_isw(reserved, *process_sp); CompilerType voidstar = process_sp->GetTarget() .GetScratchClangASTContext() ->GetBasicType(lldb::eBasicTypeVoid) .GetPointerType(); - ValueObjectSP name_sp = ValueObject::CreateValueObjectFromData( - "name_str", name_isw.GetAsData(process_sp->GetByteOrder()), - valobj.GetExecutionContextRef(), voidstar); - ValueObjectSP reason_sp = ValueObject::CreateValueObjectFromData( - "reason_str", reason_isw.GetAsData(process_sp->GetByteOrder()), - valobj.GetExecutionContextRef(), voidstar); + if (name_sp) + *name_sp = ValueObject::CreateValueObjectFromData( + "name", name_isw.GetAsData(process_sp->GetByteOrder()), + valobj.GetExecutionContextRef(), voidstar); + if (reason_sp) + *reason_sp = ValueObject::CreateValueObjectFromData( + "reason", reason_isw.GetAsData(process_sp->GetByteOrder()), + valobj.GetExecutionContextRef(), voidstar); + if (userinfo_sp) + *userinfo_sp = ValueObject::CreateValueObjectFromData( + "userInfo", userinfo_isw.GetAsData(process_sp->GetByteOrder()), + valobj.GetExecutionContextRef(), voidstar); + if (reserved_sp) + *reserved_sp = ValueObject::CreateValueObjectFromData( + "reserved", reserved_isw.GetAsData(process_sp->GetByteOrder()), + valobj.GetExecutionContextRef(), voidstar); + + return true; +} + +bool lldb_private::formatters::NSException_SummaryProvider( + ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { + lldb::ValueObjectSP name_sp; + lldb::ValueObjectSP reason_sp; + if (!ExtractFields(valobj, &name_sp, &reason_sp, nullptr, nullptr)) + return false; if (!name_sp || !reason_sp) return false; @@ -101,83 +123,55 @@ public: : SyntheticChildrenFrontEnd(*valobj_sp) {} ~NSExceptionSyntheticFrontEnd() override = default; - // no need to delete m_child_ptr - it's kept alive by the cluster manager on - // our behalf size_t CalculateNumChildren() override { - if (m_child_ptr) - return 1; - if (m_child_sp) - return 1; - return 0; + return 4; } lldb::ValueObjectSP GetChildAtIndex(size_t idx) override { - if (idx != 0) - return lldb::ValueObjectSP(); - - if (m_child_ptr) - return m_child_ptr->GetSP(); - return m_child_sp; + switch (idx) { + case 0: return m_name_sp; + case 1: return m_reason_sp; + case 2: return m_userinfo_sp; + case 3: return m_reserved_sp; + } + return lldb::ValueObjectSP(); } bool Update() override { - m_child_ptr = nullptr; - m_child_sp.reset(); + m_name_sp.reset(); + m_reason_sp.reset(); + m_userinfo_sp.reset(); + m_reserved_sp.reset(); - ProcessSP process_sp(m_backend.GetProcessSP()); - if (!process_sp) - return false; - - lldb::addr_t userinfo_location = LLDB_INVALID_ADDRESS; - - CompilerType valobj_type(m_backend.GetCompilerType()); - Flags type_flags(valobj_type.GetTypeInfo()); - if (type_flags.AllClear(eTypeHasValue)) { - if (m_backend.IsBaseClass() && m_backend.GetParent()) - userinfo_location = - m_backend.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - } else - userinfo_location = m_backend.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); - - if (userinfo_location == LLDB_INVALID_ADDRESS) - return false; - - size_t ptr_size = process_sp->GetAddressByteSize(); - - userinfo_location += 3 * ptr_size; - Status error; - lldb::addr_t userinfo = - process_sp->ReadPointerFromMemory(userinfo_location, error); - if (userinfo == LLDB_INVALID_ADDRESS || error.Fail()) - return false; - InferiorSizedWord isw(userinfo, *process_sp); - m_child_sp = CreateValueObjectFromData( - "userInfo", isw.GetAsData(process_sp->GetByteOrder()), - m_backend.GetExecutionContextRef(), - process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType( - lldb::eBasicTypeObjCID)); - return false; + return ExtractFields(m_backend, &m_name_sp, &m_reason_sp, &m_userinfo_sp, + &m_reserved_sp); } bool MightHaveChildren() override { return true; } size_t GetIndexOfChildWithName(const ConstString &name) override { + // NSException has 4 members: + // NSString *name; + // NSString *reason; + // NSDictionary *userInfo; + // id reserved; + static ConstString g___name("name"); + static ConstString g___reason("reason"); static ConstString g___userInfo("userInfo"); - if (name == g___userInfo) - return 0; + static ConstString g___reserved("reserved"); + if (name == g___name) return 0; + if (name == g___reason) return 1; + if (name == g___userInfo) return 2; + if (name == g___reserved) return 3; return UINT32_MAX; } private: - // the child here can be "real" (i.e. an actual child of the root) or - // synthetized from raw memory if the former, I need to store a plain pointer - // to it - or else a loop of references will cause this entire hierarchy of - // values to leak if the latter, then I need to store a SharedPointer to it - - // so that it only goes away when everyone else in the cluster goes away oh - // joy! - ValueObject *m_child_ptr; - ValueObjectSP m_child_sp; + ValueObjectSP m_name_sp; + ValueObjectSP m_reason_sp; + ValueObjectSP m_userinfo_sp; + ValueObjectSP m_reserved_sp; }; SyntheticChildrenFrontEnd * diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp index 9533e96004a5..41df9abb3eb2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Cocoa.h" #include "lldb/Core/ValueObject.h" @@ -130,11 +126,7 @@ public: return false; } - bool MightHaveChildren() override { - if (m_impl.m_mode == Mode::Invalid) - return false; - return true; - } + bool MightHaveChildren() override { return m_impl.m_mode != Mode::Invalid; } size_t GetIndexOfChildWithName(const ConstString &name) override { const char *item_name = name.GetCString(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSSet.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSSet.cpp index 2da4bc034f32..7e03d7574af0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSSet.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSSet.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "NSSet.h" #include "Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSString.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSString.cpp index 0b12edb53d7a..f882b2adc260 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSString.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/NSString.cpp @@ -225,10 +225,10 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); - options.SetNeedsZeroTermination(has_explicit_length == false); + options.SetNeedsZeroTermination(!has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - options.SetBinaryZeroIsTerminator(has_explicit_length == false); + options.SetBinaryZeroIsTerminator(!has_explicit_length); options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); @@ -245,10 +245,10 @@ bool lldb_private::formatters::NSStringSummaryProvider( options.SetStream(&stream); options.SetQuote('"'); options.SetSourceSize(explicit_length); - options.SetNeedsZeroTermination(has_explicit_length == false); + options.SetNeedsZeroTermination(!has_explicit_length); options.SetIgnoreMaxLength(summary_options.GetCapping() == TypeSummaryCapping::eTypeSummaryUncapped); - options.SetBinaryZeroIsTerminator(has_explicit_length == false); + options.SetBinaryZeroIsTerminator(!has_explicit_length); options.SetLanguage(summary_options.GetLanguage()); return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); @@ -260,10 +260,7 @@ bool lldb_private::formatters::NSStringSummaryProvider( Status error; explicit_length = process_sp->ReadUnsignedIntegerFromMemory(location, 1, 0, error); - if (error.Fail() || explicit_length == 0) - has_explicit_length = false; - else - has_explicit_length = true; + has_explicit_length = !(error.Fail() || explicit_length == 0); location++; } options.SetLocation(location); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp index 47874b3be8fd..0598d69f6ebb 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "ObjCLanguage.h" #include "lldb/Core/PluginManager.h" @@ -411,6 +407,9 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { AddCXXSummary( objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("__NSCFArray"), appkit_flags); + AddCXXSummary( + objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, + "NSArray summary provider", ConstString("_NSCallStackArray"), appkit_flags); AddCXXSummary( objc_category_sp, lldb_private::formatters::NSArraySummaryProvider, "NSArray summary provider", ConstString("CFArrayRef"), appkit_flags); @@ -530,6 +529,10 @@ static void LoadObjCFormatters(TypeCategoryImplSP objc_category_sp) { lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", ConstString("__NSCFArray"), ScriptedSyntheticChildren::Flags()); + AddCXXSynthetic(objc_category_sp, + lldb_private::formatters::NSArraySyntheticFrontEndCreator, + "NSArray synthetic children", ConstString("_NSCallStackArray"), + ScriptedSyntheticChildren::Flags()); AddCXXSynthetic(objc_category_sp, lldb_private::formatters::NSArraySyntheticFrontEndCreator, "NSArray synthetic children", @@ -1102,3 +1105,12 @@ bool ObjCLanguage::IsNilReference(ValueObject &valobj) { bool isZero = valobj.GetValueAsUnsigned(0, &canReadValue) == 0; return canReadValue && isZero; } + +bool ObjCLanguage::IsSourceFile(llvm::StringRef file_path) const { + const auto suffixes = {".h", ".m", ".M"}; + for (auto suffix : suffixes) { + if (file_path.endswith_lower(suffix)) + return true; + } + return false; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h index 9782c5da0d67..114f9323de02 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjC/ObjCLanguage.h @@ -10,13 +10,10 @@ #ifndef liblldb_ObjCLanguage_h_ #define liblldb_ObjCLanguage_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes +#include "Plugins/Language/ClangCommon/ClangHighlighter.h" #include "lldb/Target/Language.h" #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" @@ -24,6 +21,8 @@ namespace lldb_private { class ObjCLanguage : public Language { + ClangHighlighter m_highlighter; + public: class MethodName { public: @@ -121,6 +120,10 @@ public: bool IsNilReference(ValueObject &valobj) override; + bool IsSourceFile(llvm::StringRef file_path) const override; + + const Highlighter *GetHighlighter() const override { return &m_highlighter; } + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp index bfc22c9ee650..5e6d86e05318 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.cpp @@ -16,6 +16,15 @@ using namespace lldb; using namespace lldb_private; +bool ObjCPlusPlusLanguage::IsSourceFile(llvm::StringRef file_path) const { + const auto suffixes = {".h", ".mm"}; + for (auto suffix : suffixes) { + if (file_path.endswith_lower(suffix)) + return true; + } + return false; +} + void ObjCPlusPlusLanguage::Initialize() { PluginManager::RegisterPlugin(GetPluginNameStatic(), "Objective-C++ Language", CreateInstance); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h index 588b52215c10..b64f0f81e001 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Language/ObjCPlusPlus/ObjCPlusPlusLanguage.h @@ -10,16 +10,15 @@ #ifndef liblldb_ObjCPlusPlusLanguage_h_ #define liblldb_ObjCPlusPlusLanguage_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes +#include "Plugins/Language/ClangCommon/ClangHighlighter.h" #include "lldb/Target/Language.h" #include "lldb/lldb-private.h" namespace lldb_private { class ObjCPlusPlusLanguage : public Language { + ClangHighlighter m_highlighter; + public: ObjCPlusPlusLanguage() = default; @@ -29,6 +28,10 @@ public: return lldb::eLanguageTypeObjC_plus_plus; } + bool IsSourceFile(llvm::StringRef file_path) const override; + + const Highlighter *GetHighlighter() const override { return &m_highlighter; } + //------------------------------------------------------------------ // Static Functions //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp index fc661bbbf2c9..49a3d40d7b37 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp @@ -14,9 +14,11 @@ #include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/ValueObject.h" #include "lldb/Core/ValueObjectMemory.h" +#include "lldb/DataFormatters/FormattersHelpers.h" +#include "lldb/Expression/DiagnosticManager.h" +#include "lldb/Expression/FunctionCaller.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/CommandObjectMultiword.h" #include "lldb/Interpreter/CommandReturnObject.h" @@ -32,6 +34,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include @@ -98,7 +101,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( llvm::DenseSet searched_symbol_files; if (sc.module_sp) { num_matches = sc.module_sp->FindTypes( - sc, ConstString(lookup_name), exact_match, 1, + ConstString(lookup_name), exact_match, 1, searched_symbol_files, class_types); } @@ -106,7 +109,7 @@ TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( // list in the target and get as many unique matches as possible if (num_matches == 0) { num_matches = target.GetImages().FindTypes( - sc, ConstString(lookup_name), exact_match, UINT32_MAX, + nullptr, ConstString(lookup_name), exact_match, UINT32_MAX, searched_symbol_files, class_types); } @@ -204,71 +207,71 @@ bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress( // Only a pointer or reference type can have a different dynamic and static // type: - if (CouldHaveDynamicValue(in_value)) { - // First job, pull out the address at 0 offset from the object. - AddressType address_type; - lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); - if (original_ptr == LLDB_INVALID_ADDRESS) - return false; + if (!CouldHaveDynamicValue(in_value)) + return false; - ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); + // First job, pull out the address at 0 offset from the object. + AddressType address_type; + lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); + if (original_ptr == LLDB_INVALID_ADDRESS) + return false; - Process *process = exe_ctx.GetProcessPtr(); + ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); - if (process == nullptr) - return false; + Process *process = exe_ctx.GetProcessPtr(); - Status error; - const lldb::addr_t vtable_address_point = - process->ReadPointerFromMemory(original_ptr, error); + if (process == nullptr) + return false; - if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) { - return false; - } + Status error; + const lldb::addr_t vtable_address_point = + process->ReadPointerFromMemory(original_ptr, error); - class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr, - vtable_address_point); + if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) + return false; - if (class_type_or_name) { - TypeSP type_sp = class_type_or_name.GetTypeSP(); - // There can only be one type with a given name, so we've just found - // duplicate definitions, and this one will do as well as any other. We - // don't consider something to have a dynamic type if it is the same as - // the static type. So compare against the value we were handed. - if (type_sp) { - if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), - type_sp->GetForwardCompilerType())) { - // The dynamic type we found was the same type, so we don't have a - // dynamic type here... - return false; - } + class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr, + vtable_address_point); - // The offset_to_top is two pointers above the vtable pointer. - const uint32_t addr_byte_size = process->GetAddressByteSize(); - const lldb::addr_t offset_to_top_location = - vtable_address_point - 2 * addr_byte_size; - // Watch for underflow, offset_to_top_location should be less than - // vtable_address_point - if (offset_to_top_location >= vtable_address_point) - return false; - const int64_t offset_to_top = process->ReadSignedIntegerFromMemory( - offset_to_top_location, addr_byte_size, INT64_MIN, error); + if (!class_type_or_name) + return false; - if (offset_to_top == INT64_MIN) - return false; - // So the dynamic type is a value that starts at offset_to_top above - // the original address. - lldb::addr_t dynamic_addr = original_ptr + offset_to_top; - if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress( - dynamic_addr, dynamic_address)) { - dynamic_address.SetRawAddress(dynamic_addr); - } - return true; - } - } + TypeSP type_sp = class_type_or_name.GetTypeSP(); + // There can only be one type with a given name, so we've just found + // duplicate definitions, and this one will do as well as any other. We + // don't consider something to have a dynamic type if it is the same as + // the static type. So compare against the value we were handed. + if (!type_sp) + return true; + + if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), + type_sp->GetForwardCompilerType())) { + // The dynamic type we found was the same type, so we don't have a + // dynamic type here... + return false; } - return class_type_or_name.IsEmpty() == false; + // The offset_to_top is two pointers above the vtable pointer. + const uint32_t addr_byte_size = process->GetAddressByteSize(); + const lldb::addr_t offset_to_top_location = + vtable_address_point - 2 * addr_byte_size; + // Watch for underflow, offset_to_top_location should be less than + // vtable_address_point + if (offset_to_top_location >= vtable_address_point) + return false; + const int64_t offset_to_top = process->ReadSignedIntegerFromMemory( + offset_to_top_location, addr_byte_size, INT64_MIN, error); + + if (offset_to_top == INT64_MIN) + return false; + // So the dynamic type is a value that starts at offset_to_top above + // the original address. + lldb::addr_t dynamic_addr = original_ptr + offset_to_top; + if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress( + dynamic_addr, dynamic_address)) { + dynamic_address.SetRawAddress(dynamic_addr); + } + return true; } TypeAndOrName ItaniumABILanguageRuntime::FixUpDynamicType( @@ -309,10 +312,7 @@ bool ItaniumABILanguageRuntime::IsVTableName(const char *name) { return false; // Can we maybe ask Clang about this? - if (strstr(name, "_vptr$") == name) - return true; - else - return false; + return strstr(name, "_vptr$") == name; } //------------------------------------------------------------------ @@ -483,8 +483,8 @@ lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() { // Limit the number of modules that are searched for these breakpoints for // Apple binaries. FileSpecList filter_modules; - filter_modules.Append(FileSpec("libc++abi.dylib", false)); - filter_modules.Append(FileSpec("libSystem.B.dylib", false)); + filter_modules.Append(FileSpec("libc++abi.dylib")); + filter_modules.Append(FileSpec("libSystem.B.dylib")); return target.GetSearchFilterForModuleList(&filter_modules); } else { return LanguageRuntime::CreateExceptionSearchFilter(); @@ -552,6 +552,64 @@ bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop( break_site_id, m_cxx_exception_bp_sp->GetID()); } +ValueObjectSP ItaniumABILanguageRuntime::GetExceptionObjectForThread( + ThreadSP thread_sp) { + if (!thread_sp->SafeToCallFunctions()) + return {}; + + ClangASTContext *clang_ast_context = + m_process->GetTarget().GetScratchClangASTContext(); + CompilerType voidstar = + clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType(); + + DiagnosticManager diagnostics; + ExecutionContext exe_ctx; + EvaluateExpressionOptions options; + + options.SetUnwindOnError(true); + options.SetIgnoreBreakpoints(true); + options.SetStopOthers(true); + options.SetTimeout(std::chrono::milliseconds(500)); + options.SetTryAllThreads(false); + thread_sp->CalculateExecutionContext(exe_ctx); + + const ModuleList &modules = m_process->GetTarget().GetImages(); + SymbolContextList contexts; + SymbolContext context; + + modules.FindSymbolsWithNameAndType( + ConstString("__cxa_current_exception_type"), eSymbolTypeCode, contexts); + contexts.GetContextAtIndex(0, context); + Address addr = context.symbol->GetAddress(); + + Status error; + FunctionCaller *function_caller = + m_process->GetTarget().GetFunctionCallerForLanguage( + eLanguageTypeC, voidstar, addr, ValueList(), "caller", error); + + ExpressionResults func_call_ret; + Value results; + func_call_ret = function_caller->ExecuteFunction(exe_ctx, nullptr, options, + diagnostics, results); + if (func_call_ret != eExpressionCompleted || !error.Success()) { + return ValueObjectSP(); + } + + size_t ptr_size = m_process->GetAddressByteSize(); + addr_t result_ptr = results.GetScalar().ULongLong(LLDB_INVALID_ADDRESS); + addr_t exception_addr = + m_process->ReadPointerFromMemory(result_ptr - ptr_size, error); + + lldb_private::formatters::InferiorSizedWord exception_isw(exception_addr, + *m_process); + ValueObjectSP exception = ValueObject::CreateValueObjectFromData( + "exception", exception_isw.GetAsData(m_process->GetByteOrder()), exe_ctx, + voidstar); + exception = exception->GetDynamicValue(eDynamicDontRunTarget); + + return exception; +} + TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo( const lldb_private::Address &vtable_addr) { std::lock_guard locker(m_dynamic_type_map_mutex); diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h index 480c32691c8b..abed3706c6b8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h @@ -10,14 +10,10 @@ #ifndef liblldb_ItaniumABILanguageRuntime_h_ #define liblldb_ItaniumABILanguageRuntime_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointResolver.h" #include "lldb/Core/Value.h" #include "lldb/Symbol/Type.h" @@ -69,6 +65,9 @@ public: bool throw_bp) override; lldb::SearchFilterSP CreateExceptionSearchFilter() override; + + lldb::ValueObjectSP GetExceptionObjectForThread( + lldb::ThreadSP thread_sp) override; //------------------------------------------------------------------ // PluginInterface protocol diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp deleted file mode 100644 index 6670f89dde5f..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.cpp +++ /dev/null @@ -1,215 +0,0 @@ -//===-- GoLanguageRuntime.cpp --------------------------------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "GoLanguageRuntime.h" - -#include "lldb/Breakpoint/BreakpointLocation.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Core/ValueObjectMemory.h" -#include "lldb/Symbol/GoASTContext.h" -#include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/TypeList.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/RegisterContext.h" -#include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" -#include "lldb/Utility/ConstString.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Status.h" -#include "llvm/ADT/Twine.h" - -#include - -using namespace lldb; -using namespace lldb_private; - -namespace { -ValueObjectSP GetChild(ValueObject &obj, const char *name, - bool dereference = true) { - ConstString name_const_str(name); - ValueObjectSP result = obj.GetChildMemberWithName(name_const_str, true); - if (dereference && result && result->IsPointerType()) { - Status err; - result = result->Dereference(err); - if (err.Fail()) - result.reset(); - } - return result; -} - -ConstString ReadString(ValueObject &str, Process *process) { - ConstString result; - ValueObjectSP data = GetChild(str, "str", false); - ValueObjectSP len = GetChild(str, "len"); - if (len && data) { - Status err; - lldb::addr_t addr = data->GetPointerValue(); - if (addr == LLDB_INVALID_ADDRESS) - return result; - uint64_t byte_size = len->GetValueAsUnsigned(0); - char *buf = new char[byte_size + 1]; - buf[byte_size] = 0; - size_t bytes_read = process->ReadMemory(addr, buf, byte_size, err); - if (!(err.Fail() || bytes_read != byte_size)) - result = ConstString(buf, bytes_read); - delete[] buf; - } - return result; -} - -ConstString ReadTypeName(ValueObjectSP type, Process *process) { - if (ValueObjectSP uncommon = GetChild(*type, "x")) { - ValueObjectSP name = GetChild(*uncommon, "name"); - ValueObjectSP package = GetChild(*uncommon, "pkgpath"); - if (name && name->GetPointerValue() != 0 && package && - package->GetPointerValue() != 0) { - ConstString package_const_str = ReadString(*package, process); - ConstString name_const_str = ReadString(*name, process); - if (package_const_str.GetLength() == 0) - return name_const_str; - return ConstString((package_const_str.GetStringRef() + "." + - name_const_str.GetStringRef()) - .str()); - } - } - ValueObjectSP name = GetChild(*type, "_string"); - if (name) - return ReadString(*name, process); - return ConstString(""); -} - -CompilerType LookupRuntimeType(ValueObjectSP type, ExecutionContext *exe_ctx, - bool *is_direct) { - uint8_t kind = GetChild(*type, "kind")->GetValueAsUnsigned(0); - *is_direct = GoASTContext::IsDirectIface(kind); - if (GoASTContext::IsPointerKind(kind)) { - CompilerType type_ptr = type->GetCompilerType().GetPointerType(); - Status err; - ValueObjectSP elem = - type->CreateValueObjectFromAddress("elem", type->GetAddressOf() + - type->GetByteSize(), - *exe_ctx, type_ptr) - ->Dereference(err); - if (err.Fail()) - return CompilerType(); - bool tmp_direct; - return LookupRuntimeType(elem, exe_ctx, &tmp_direct).GetPointerType(); - } - Target *target = exe_ctx->GetTargetPtr(); - Process *process = exe_ctx->GetProcessPtr(); - - ConstString const_typename = ReadTypeName(type, process); - if (const_typename.GetLength() == 0) - return CompilerType(); - - SymbolContext sc; - TypeList type_list; - llvm::DenseSet searched_symbol_files; - uint32_t num_matches = target->GetImages().FindTypes( - sc, const_typename, false, 2, searched_symbol_files, type_list); - if (num_matches > 0) { - return type_list.GetTypeAtIndex(0)->GetFullCompilerType(); - } - return CompilerType(); -} -} - -bool GoLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) { - return GoASTContext::IsGoInterface(in_value.GetCompilerType()); -} - -bool GoLanguageRuntime::GetDynamicTypeAndAddress( - ValueObject &in_value, lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, Address &dynamic_address, - Value::ValueType &value_type) { - value_type = Value::eValueTypeScalar; - class_type_or_name.Clear(); - if (CouldHaveDynamicValue(in_value)) { - Status err; - ValueObjectSP iface = in_value.GetStaticValue(); - ValueObjectSP data_sp = GetChild(*iface, "data", false); - if (!data_sp) - return false; - - if (ValueObjectSP tab = GetChild(*iface, "tab")) - iface = tab; - ValueObjectSP type = GetChild(*iface, "_type"); - if (!type) { - return false; - } - - bool direct; - ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); - CompilerType final_type = LookupRuntimeType(type, &exe_ctx, &direct); - if (!final_type) - return false; - if (direct) { - class_type_or_name.SetCompilerType(final_type); - } else { - // TODO: implement reference types or fix caller to support dynamic types - // that aren't pointers - // so we don't have to introduce this extra pointer. - class_type_or_name.SetCompilerType(final_type.GetPointerType()); - } - - dynamic_address.SetLoadAddress(data_sp->GetPointerValue(), - exe_ctx.GetTargetPtr()); - - return true; - } - return false; -} - -TypeAndOrName -GoLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, - ValueObject &static_value) { - return type_and_or_name; -} - -//------------------------------------------------------------------ -// Static Functions -//------------------------------------------------------------------ -LanguageRuntime * -GoLanguageRuntime::CreateInstance(Process *process, - lldb::LanguageType language) { - if (language == eLanguageTypeGo) - return new GoLanguageRuntime(process); - else - return NULL; -} - -void GoLanguageRuntime::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), "Go Language Runtime", - CreateInstance); -} - -void GoLanguageRuntime::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -lldb_private::ConstString GoLanguageRuntime::GetPluginNameStatic() { - static ConstString g_name("golang"); - return g_name; -} - -//------------------------------------------------------------------ -// PluginInterface protocol -//------------------------------------------------------------------ -lldb_private::ConstString GoLanguageRuntime::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t GoLanguageRuntime::GetPluginVersion() { return 1; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h deleted file mode 100644 index 9c2ee15cff65..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Go/GoLanguageRuntime.h +++ /dev/null @@ -1,86 +0,0 @@ -//===-- GoLanguageRuntime.h -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_GoLanguageRuntime_h_ -#define liblldb_GoLanguageRuntime_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes -#include "lldb/Breakpoint/BreakpointResolver.h" -#include "lldb/Core/Value.h" -#include "lldb/Target/LanguageRuntime.h" -#include "lldb/lldb-private.h" - -namespace lldb_private { - -class GoLanguageRuntime : public lldb_private::LanguageRuntime { -public: - ~GoLanguageRuntime() override = default; - - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static void Initialize(); - - static void Terminate(); - - static lldb_private::LanguageRuntime * - CreateInstance(Process *process, lldb::LanguageType language); - - static lldb_private::ConstString GetPluginNameStatic(); - - lldb::LanguageType GetLanguageType() const override { - return lldb::eLanguageTypeGo; - } - - bool GetObjectDescription(Stream &str, ValueObject &object) override { - // TODO(ribrdb): Maybe call String() method? - return false; - } - - bool GetObjectDescription(Stream &str, Value &value, - ExecutionContextScope *exe_scope) override { - return false; - } - - bool GetDynamicTypeAndAddress(ValueObject &in_value, - lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, - Address &address, - Value::ValueType &value_type) override; - - bool CouldHaveDynamicValue(ValueObject &in_value) override; - - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp) override { - return lldb::BreakpointResolverSP(); - } - - TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, - ValueObject &static_value) override; - - //------------------------------------------------------------------ - // PluginInterface protocol - //------------------------------------------------------------------ - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - -private: - GoLanguageRuntime(Process *process) - : lldb_private::LanguageRuntime(process) { - } // Call CreateInstance instead. -}; - -} // namespace lldb_private - -#endif // liblldb_GoLanguageRuntime_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp deleted file mode 100644 index 36c30a99ff87..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.cpp +++ /dev/null @@ -1,157 +0,0 @@ -//===-- JavaLanguageRuntime.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "JavaLanguageRuntime.h" - -#include "lldb/Core/PluginManager.h" -#include "lldb/Symbol/JavaASTContext.h" -#include "lldb/Symbol/Symbol.h" -#include "lldb/Symbol/SymbolContext.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Symbol/TypeList.h" -#include "lldb/Target/SectionLoadList.h" -#include "lldb/Target/Target.h" -#include "llvm/ADT/StringRef.h" - -using namespace lldb; -using namespace lldb_private; - -JavaLanguageRuntime::JavaLanguageRuntime(Process *process) - : LanguageRuntime(process) {} - -LanguageRuntime * -JavaLanguageRuntime::CreateInstance(Process *process, - lldb::LanguageType language) { - if (language == eLanguageTypeJava) - return new JavaLanguageRuntime(process); - return nullptr; -} - -void JavaLanguageRuntime::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), "Java language runtime", - CreateInstance); -} - -void JavaLanguageRuntime::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -lldb_private::ConstString JavaLanguageRuntime::GetPluginNameStatic() { - static ConstString g_name("java"); - return g_name; -} - -lldb_private::ConstString JavaLanguageRuntime::GetPluginName() { - return GetPluginNameStatic(); -} - -uint32_t JavaLanguageRuntime::GetPluginVersion() { return 1; } - -bool JavaLanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) { - return true; -} - -static ConstString GetDynamicTypeId(ExecutionContext *exe_ctx, Target *target, - ValueObject &in_value) { - SymbolContext sc; - TypeList class_types; - llvm::DenseSet searched_symbol_files; - size_t num_matches = target->GetImages().FindTypes( - sc, ConstString("Object"), - true, // name_is_fully_qualified - UINT32_MAX, searched_symbol_files, class_types); - for (size_t i = 0; i < num_matches; ++i) { - TypeSP type_sp = class_types.GetTypeAtIndex(i); - CompilerType compiler_type = type_sp->GetFullCompilerType(); - - if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava || - compiler_type.GetTypeName() != ConstString("java::lang::Object")) - continue; - - if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType()) { - uint64_t type_id = JavaASTContext::CalculateDynamicTypeId( - exe_ctx, compiler_type, in_value); - if (type_id != UINT64_MAX) { - char id[32]; - snprintf(id, sizeof(id), "0x%" PRIX64, type_id); - return ConstString(id); - } - } - } - return ConstString(); -} - -bool JavaLanguageRuntime::GetDynamicTypeAndAddress( - ValueObject &in_value, lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, Address &dynamic_address, - Value::ValueType &value_type) { - class_type_or_name.Clear(); - - // null references don't have a dynamic type - if (in_value.IsNilReference()) - return false; - - ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); - Target *target = exe_ctx.GetTargetPtr(); - if (!target) - return false; - - ConstString linkage_name; - CompilerType in_type = in_value.GetCompilerType(); - if (in_type.IsPossibleDynamicType(nullptr, false, false)) - linkage_name = GetDynamicTypeId(&exe_ctx, target, in_value); - else - linkage_name = JavaASTContext::GetLinkageName(in_type); - - if (!linkage_name) - return false; - - class_type_or_name.SetName(in_type.GetNonReferenceType().GetTypeName()); - - SymbolContext sc; - TypeList class_types; - llvm::DenseSet searched_symbol_files; - size_t num_matches = target->GetImages().FindTypes( - sc, linkage_name, - true, // name_is_fully_qualified - UINT32_MAX, searched_symbol_files, class_types); - - for (size_t i = 0; i < num_matches; ++i) { - TypeSP type_sp = class_types.GetTypeAtIndex(i); - CompilerType compiler_type = type_sp->GetFullCompilerType(); - - if (compiler_type.GetMinimumLanguage() != eLanguageTypeJava) - continue; - - if (compiler_type.GetCompleteType() && compiler_type.IsCompleteType()) { - class_type_or_name.SetTypeSP(type_sp); - - Value &value = in_value.GetValue(); - value_type = value.GetValueType(); - dynamic_address.SetRawAddress(value.GetScalar().ULongLong(0)); - return true; - } - } - return false; -} - -TypeAndOrName -JavaLanguageRuntime::FixUpDynamicType(const TypeAndOrName &type_and_or_name, - ValueObject &static_value) { - CompilerType static_type(static_value.GetCompilerType()); - - TypeAndOrName ret(type_and_or_name); - if (type_and_or_name.HasType()) { - CompilerType orig_type = type_and_or_name.GetCompilerType(); - if (static_type.IsReferenceType()) - ret.SetCompilerType(orig_type.GetLValueReferenceType()); - } - return ret; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h deleted file mode 100644 index 6eeb4041572a..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/Java/JavaLanguageRuntime.h +++ /dev/null @@ -1,78 +0,0 @@ -//===-- JavaLanguageRuntime.h -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_JavaLanguageRuntime_h_ -#define liblldb_JavaLanguageRuntime_h_ - -// C Includes -// C++ Includes -#include -// Other libraries and framework includes -// Project includes -#include "lldb/Core/PluginInterface.h" -#include "lldb/Target/LanguageRuntime.h" -#include "lldb/lldb-private.h" - -namespace lldb_private { - -class JavaLanguageRuntime : public LanguageRuntime { -public: - static void Initialize(); - - static void Terminate(); - - static lldb_private::LanguageRuntime * - CreateInstance(Process *process, lldb::LanguageType language); - - static lldb_private::ConstString GetPluginNameStatic(); - - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - lldb::LanguageType GetLanguageType() const override { - return lldb::eLanguageTypeJava; - } - - bool GetObjectDescription(Stream &str, ValueObject &object) override { - return false; - } - - bool GetObjectDescription(Stream &str, Value &value, - ExecutionContextScope *exe_scope) override { - return false; - } - - lldb::BreakpointResolverSP CreateExceptionResolver(Breakpoint *bkpt, - bool catch_bp, - bool throw_bp) override { - return nullptr; - } - - TypeAndOrName FixUpDynamicType(const TypeAndOrName &type_and_or_name, - ValueObject &static_value) override; - - bool CouldHaveDynamicValue(ValueObject &in_value) override; - - bool GetDynamicTypeAndAddress(ValueObject &in_value, - lldb::DynamicValueType use_dynamic, - TypeAndOrName &class_type_or_name, - Address &address, - Value::ValueType &value_type) override; - -protected: - JavaLanguageRuntime(Process *process); - -private: - DISALLOW_COPY_AND_ASSIGN(JavaLanguageRuntime); -}; - -} // namespace lldb_private - -#endif // liblldb_JavaLanguageRuntime_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp index edb29e735ca9..679c3c850e5b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.cpp @@ -264,11 +264,7 @@ bool ClassDescriptorV2::method_t::Read(Process *process, lldb::addr_t addr) { } process->ReadCStringFromMemory(m_types_ptr, m_types, error); - if (error.Fail()) { - return false; - } - - return true; + return !error.Fail(); } bool ClassDescriptorV2::ivar_list_t::Read(Process *process, lldb::addr_t addr) { @@ -323,11 +319,7 @@ bool ClassDescriptorV2::ivar_t::Read(Process *process, lldb::addr_t addr) { } process->ReadCStringFromMemory(m_type_ptr, m_type, error); - if (error.Fail()) { - return false; - } - - return true; + return !error.Fail(); } bool ClassDescriptorV2::Describe( @@ -524,7 +516,8 @@ void ClassDescriptorV2::iVarsStorage::fill(AppleObjCRuntimeV2 &runtime, LLDB_LOGV(log, "name = {0}, encoding = {1}, offset_ptr = {2:x}, size = " "{3}, type_size = {4}", - name, type, offset_ptr, size, ivar_type.GetByteSize(nullptr)); + name, type, offset_ptr, size, + ivar_type.GetByteSize(nullptr).getValueOr(0)); Scalar offset_scalar; Status error; const int offset_ptr_size = 4; diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h index 787423b54766..308ff1426fb2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCClassDescriptorV2.h @@ -10,12 +10,8 @@ #ifndef liblldb_AppleObjCClassDescriptorV2_h_ #define liblldb_AppleObjCClassDescriptorV2_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "AppleObjCRuntimeV2.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp index 105c088b9e91..4fc340b23c2c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp @@ -558,7 +558,7 @@ AppleObjCDeclVendor::FindDecls(const ConstString &name, bool append, LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel? if (log) - log->Printf("AppleObjCDeclVendor::FindTypes [%u] ('%s', %s, %u, )", + log->Printf("AppleObjCDeclVendor::FindDecls [%u] ('%s', %s, %u, )", current_id, (const char *)name.AsCString(), append ? "true" : "false", max_matches); diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h index 2f087da16bc1..7f5c0bf3eb63 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h @@ -10,10 +10,6 @@ #ifndef liblldb_AppleObjCDeclVendor_h_ #define liblldb_AppleObjCDeclVendor_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/DeclVendor.h" #include "lldb/Target/ObjCLanguageRuntime.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp index fef42c78b24f..ed47b481a810 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp @@ -17,13 +17,15 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/ValueObject.h" +#include "lldb/Core/ValueObjectConstResult.h" +#include "lldb/DataFormatters/FormattersHelpers.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -32,9 +34,13 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" +#include "Plugins/Process/Utility/HistoryThread.h" +#include "Plugins/Language/ObjC/NSString.h" + #include using namespace lldb; @@ -167,6 +173,7 @@ bool AppleObjCRuntime::GetObjectDescription(Stream &strm, Value &value, options.SetStopOthers(true); options.SetIgnoreBreakpoints(true); options.SetTimeout(g_po_function_timeout); + options.SetIsForUtilityExpr(true); ExpressionResults results = m_print_object_caller_up->ExecuteFunction( exe_ctx, &wrapper_struct_addr, options, diagnostics, ret); @@ -440,13 +447,10 @@ bool AppleObjCRuntime::CalculateHasNewLiteralsAndIndexing() { SymbolContextList sc_list; - if (target.GetImages().FindSymbolsWithNameAndType(s_method_signature, - eSymbolTypeCode, sc_list) || - target.GetImages().FindSymbolsWithNameAndType(s_arclite_method_signature, - eSymbolTypeCode, sc_list)) - return true; - else - return false; + return target.GetImages().FindSymbolsWithNameAndType( + s_method_signature, eSymbolTypeCode, sc_list) || + target.GetImages().FindSymbolsWithNameAndType( + s_arclite_method_signature, eSymbolTypeCode, sc_list); } lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() { @@ -454,13 +458,115 @@ lldb::SearchFilterSP AppleObjCRuntime::CreateExceptionSearchFilter() { if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) { FileSpecList filter_modules; - filter_modules.Append(FileSpec("libobjc.A.dylib", false)); + filter_modules.Append(std::get<0>(GetExceptionThrowLocation())); return target.GetSearchFilterForModuleList(&filter_modules); } else { return LanguageRuntime::CreateExceptionSearchFilter(); } } +ValueObjectSP AppleObjCRuntime::GetExceptionObjectForThread( + ThreadSP thread_sp) { + auto cpp_runtime = m_process->GetCPPLanguageRuntime(); + if (!cpp_runtime) return ValueObjectSP(); + auto cpp_exception = cpp_runtime->GetExceptionObjectForThread(thread_sp); + if (!cpp_exception) return ValueObjectSP(); + + auto descriptor = GetClassDescriptor(*cpp_exception.get()); + if (!descriptor || !descriptor->IsValid()) return ValueObjectSP(); + + while (descriptor) { + ConstString class_name(descriptor->GetClassName()); + if (class_name == ConstString("NSException")) return cpp_exception; + descriptor = descriptor->GetSuperclass(); + } + + return ValueObjectSP(); +} + +ThreadSP AppleObjCRuntime::GetBacktraceThreadFromException( + lldb::ValueObjectSP exception_sp) { + ValueObjectSP reserved_dict = + exception_sp->GetChildMemberWithName(ConstString("reserved"), true); + if (!reserved_dict) return ThreadSP(); + + reserved_dict = reserved_dict->GetSyntheticValue(); + if (!reserved_dict) return ThreadSP(); + + CompilerType objc_id = + exception_sp->GetTargetSP()->GetScratchClangASTContext()->GetBasicType( + lldb::eBasicTypeObjCID); + ValueObjectSP return_addresses; + + auto objc_object_from_address = [&exception_sp, &objc_id](uint64_t addr, + const char *name) { + Value value(addr); + value.SetCompilerType(objc_id); + auto object = ValueObjectConstResult::Create( + exception_sp->GetTargetSP().get(), value, ConstString(name)); + object = object->GetDynamicValue(eDynamicDontRunTarget); + return object; + }; + + for (size_t idx = 0; idx < reserved_dict->GetNumChildren(); idx++) { + ValueObjectSP dict_entry = reserved_dict->GetChildAtIndex(idx, true); + + DataExtractor data; + data.SetAddressByteSize(dict_entry->GetProcessSP()->GetAddressByteSize()); + Status error; + dict_entry->GetData(data, error); + if (error.Fail()) return ThreadSP(); + + lldb::offset_t data_offset = 0; + auto dict_entry_key = data.GetPointer(&data_offset); + auto dict_entry_value = data.GetPointer(&data_offset); + + auto key_nsstring = objc_object_from_address(dict_entry_key, "key"); + StreamString key_summary; + if (lldb_private::formatters::NSStringSummaryProvider( + *key_nsstring, key_summary, TypeSummaryOptions()) && + !key_summary.Empty()) { + if (key_summary.GetString() == "\"callStackReturnAddresses\"") { + return_addresses = objc_object_from_address(dict_entry_value, + "callStackReturnAddresses"); + break; + } + } + } + + if (!return_addresses) return ThreadSP(); + auto frames_value = + return_addresses->GetChildMemberWithName(ConstString("_frames"), true); + addr_t frames_addr = frames_value->GetValueAsUnsigned(0); + auto count_value = + return_addresses->GetChildMemberWithName(ConstString("_cnt"), true); + size_t count = count_value->GetValueAsUnsigned(0); + auto ignore_value = + return_addresses->GetChildMemberWithName(ConstString("_ignore"), true); + size_t ignore = ignore_value->GetValueAsUnsigned(0); + + size_t ptr_size = m_process->GetAddressByteSize(); + std::vector pcs; + for (size_t idx = 0; idx < count; idx++) { + Status error; + addr_t pc = m_process->ReadPointerFromMemory( + frames_addr + (ignore + idx) * ptr_size, error); + pcs.push_back(pc); + } + + if (pcs.empty()) return ThreadSP(); + + ThreadSP new_thread_sp(new HistoryThread(*m_process, 0, pcs, 0, false)); + m_process->GetExtendedThreadList().AddThread(new_thread_sp); + return new_thread_sp; +} + +std::tuple +AppleObjCRuntime::GetExceptionThrowLocation() { + return std::make_tuple( + FileSpec("libobjc.A.dylib"), ConstString("objc_exception_throw")); +} + void AppleObjCRuntime::ReadObjCLibraryIfNeeded(const ModuleList &module_list) { if (!HasReadObjCLibrary()) { std::lock_guard guard(module_list.GetMutex()); diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h index 1b22ee4c3be1..866064600149 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h @@ -10,12 +10,8 @@ #ifndef liblldb_AppleObjCRuntime_h_ #define liblldb_AppleObjCRuntime_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/Optional.h" -// Project includes #include "AppleObjCTrampolineHandler.h" #include "AppleThreadPlanStepThroughObjCTrampoline.h" #include "lldb/Target/LanguageRuntime.h" @@ -90,6 +86,14 @@ public: bool ExceptionBreakpointsExplainStop(lldb::StopInfoSP stop_reason) override; lldb::SearchFilterSP CreateExceptionSearchFilter() override; + + static std::tuple GetExceptionThrowLocation(); + + lldb::ValueObjectSP GetExceptionObjectForThread( + lldb::ThreadSP thread_sp) override; + + lldb::ThreadSP GetBacktraceThreadFromException( + lldb::ValueObjectSP thread_sp) override; uint32_t GetFoundationVersion(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp index 5001c0461b3b..1cfc7a1a022b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp @@ -17,7 +17,6 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Expression/FunctionCaller.h" #include "lldb/Expression/UtilityFunction.h" #include "lldb/Symbol/ClangASTContext.h" @@ -29,6 +28,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" @@ -58,7 +58,7 @@ bool AppleObjCRuntimeV1::GetDynamicTypeAndAddress( class_type_or_name.SetName(class_descriptor->GetClassName()); } } - return class_type_or_name.IsEmpty() == false; + return !class_type_or_name.IsEmpty(); } //------------------------------------------------------------------ @@ -113,8 +113,9 @@ AppleObjCRuntimeV1::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, if (throw_bp) resolver_sp.reset(new BreakpointResolverName( - bkpt, "objc_exception_throw", eFunctionNameTypeBase, - eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo)); + bkpt, std::get<1>(GetExceptionThrowLocation()).AsCString(), + eFunctionNameTypeBase, eLanguageTypeUnknown, Breakpoint::Exact, 0, + eLazyBoolNo)); // FIXME: don't do catch yet. return resolver_sp; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h index 52eec0f692fb..442a3a1fb5e1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h @@ -10,10 +10,6 @@ #ifndef liblldb_AppleObjCRuntimeV1_h_ #define liblldb_AppleObjCRuntimeV1_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "AppleObjCRuntime.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp index d217ed3ff325..b6ed2fe376d3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp @@ -7,18 +7,14 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes #include #include -// Other libraries and framework includes #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" -// Project includes #include "lldb/Core/ClangForward.h" #include "lldb/Host/OptionParser.h" #include "lldb/Symbol/CompilerType.h" @@ -28,8 +24,8 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" +#include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/FunctionCaller.h" @@ -44,14 +40,17 @@ #include "lldb/Symbol/Symbol.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -377,6 +376,8 @@ ExtractRuntimeGlobalSymbol(Process *process, ConstString name, } } +static void RegisterObjCExceptionRecognizer(); + AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, const ModuleSP &objc_module_sp) : AppleObjCRuntime(process), m_get_class_info_code(), @@ -397,6 +398,7 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2(Process *process, static const ConstString g_gdb_object_getClass("gdb_object_getClass"); m_has_object_getClass = (objc_module_sp->FindFirstSymbolWithNameAndType( g_gdb_object_getClass, eSymbolTypeCode) != NULL); + RegisterObjCExceptionRecognizer(); } bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress( @@ -452,7 +454,7 @@ bool AppleObjCRuntimeV2::GetDynamicTypeAndAddress( } } } - return class_type_or_name.IsEmpty() == false; + return !class_type_or_name.IsEmpty(); } //------------------------------------------------------------------ @@ -475,9 +477,9 @@ LanguageRuntime *AppleObjCRuntimeV2::CreateInstance(Process *process, return NULL; } -static OptionDefinition g_objc_classtable_dump_options[] = { +static constexpr OptionDefinition g_objc_classtable_dump_options[] = { {LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Print ivar and method information in detail"}}; class CommandObjectObjC_ClassTable_Dump : public CommandObjectParsed { @@ -803,8 +805,9 @@ AppleObjCRuntimeV2::CreateExceptionResolver(Breakpoint *bkpt, bool catch_bp, if (throw_bp) resolver_sp.reset(new BreakpointResolverName( - bkpt, "objc_exception_throw", eFunctionNameTypeBase, - eLanguageTypeUnknown, Breakpoint::Exact, 0, eLazyBoolNo)); + bkpt, std::get<1>(GetExceptionThrowLocation()).AsCString(), + eFunctionNameTypeBase, eLanguageTypeUnknown, Breakpoint::Exact, 0, + eLazyBoolNo)); // FIXME: We don't do catch breakpoints for ObjC yet. // Should there be some way for the runtime to specify what it can do in this // regard? @@ -1409,6 +1412,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic( options.SetStopOthers(true); options.SetIgnoreBreakpoints(true); options.SetTimeout(g_utility_function_timeout); + options.SetIsForUtilityExpr(true); Value return_value; return_value.SetValueType(Value::eValueTypeScalar); @@ -1659,6 +1663,7 @@ AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache() { options.SetStopOthers(true); options.SetIgnoreBreakpoints(true); options.SetTimeout(g_utility_function_timeout); + options.SetIsForUtilityExpr(true); Value return_value; return_value.SetValueType(Value::eValueTypeScalar); @@ -1847,8 +1852,8 @@ void AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded() { // warn if: // - we could not run either expression // - we found fewer than num_classes_to_warn_at classes total - if ((false == shared_cache_update_result.m_update_ran) || - (false == dynamic_update_result.m_update_ran)) + if ((!shared_cache_update_result.m_update_ran) || + (!dynamic_update_result.m_update_ran)) WarnIfNoClassesCached( SharedCacheWarningReason::eExpressionExecutionFailure); else if (dynamic_update_result.m_num_found + @@ -2423,7 +2428,7 @@ AppleObjCRuntimeV2::NonPointerISACache::NonPointerISACache( ObjCLanguageRuntime::ClassDescriptorSP AppleObjCRuntimeV2::NonPointerISACache::GetClassDescriptor(ObjCISA isa) { ObjCISA real_isa = 0; - if (EvaluateNonPointerISA(isa, real_isa) == false) + if (!EvaluateNonPointerISA(isa, real_isa)) return ObjCLanguageRuntime::ClassDescriptorSP(); auto cache_iter = m_cache.find(real_isa); if (cache_iter != m_cache.end()) @@ -2447,7 +2452,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( // If all of the indexed ISA variables are set, then its possible that this // ISA is indexed, and we should first try to get its value using the index. - // Note, we check these varaibles first as the ObjC runtime will set at least + // Note, we check these variables first as the ObjC runtime will set at least // one of their values to 0 if they aren't needed. if (m_objc_debug_indexed_isa_magic_mask && m_objc_debug_indexed_isa_magic_value && @@ -2534,7 +2539,7 @@ bool AppleObjCRuntimeV2::NonPointerISACache::EvaluateNonPointerISA( return false; } - // Definately not an indexed ISA, so try to use a mask to extract the pointer + // Definitely not an indexed ISA, so try to use a mask to extract the pointer // from the ISA. if ((isa & m_objc_debug_isa_magic_mask) == m_objc_debug_isa_magic_value) { ret_isa = isa & m_objc_debug_isa_class_mask; @@ -2594,3 +2599,62 @@ void AppleObjCRuntimeV2::GetValuesForGlobalCFBooleans(lldb::addr_t &cf_true, } else this->AppleObjCRuntime::GetValuesForGlobalCFBooleans(cf_true, cf_false); } + +#pragma mark Frame recognizers + +class ObjCExceptionRecognizedStackFrame : public RecognizedStackFrame { + public: + ObjCExceptionRecognizedStackFrame(StackFrameSP frame_sp) { + ThreadSP thread_sp = frame_sp->GetThread(); + ProcessSP process_sp = thread_sp->GetProcess(); + + const lldb::ABISP &abi = process_sp->GetABI(); + if (!abi) return; + + CompilerType voidstar = process_sp->GetTarget() + .GetScratchClangASTContext() + ->GetBasicType(lldb::eBasicTypeVoid) + .GetPointerType(); + + ValueList args; + Value input_value; + input_value.SetCompilerType(voidstar); + args.PushValue(input_value); + + if (!abi->GetArgumentValues(*thread_sp, args)) return; + + addr_t exception_addr = args.GetValueAtIndex(0)->GetScalar().ULongLong(); + + Value value(exception_addr); + value.SetCompilerType(voidstar); + exception = ValueObjectConstResult::Create(frame_sp.get(), value, + ConstString("exception")); + exception = exception->GetDynamicValue(eDynamicDontRunTarget); + + m_arguments = ValueObjectListSP(new ValueObjectList()); + m_arguments->Append(exception); + } + + ValueObjectSP exception; + + lldb::ValueObjectSP GetExceptionObject() override { return exception; } +}; + +class ObjCExceptionThrowFrameRecognizer : public StackFrameRecognizer { + lldb::RecognizedStackFrameSP RecognizeFrame(lldb::StackFrameSP frame) { + return lldb::RecognizedStackFrameSP( + new ObjCExceptionRecognizedStackFrame(frame)); + }; +}; + +static void RegisterObjCExceptionRecognizer() { + static llvm::once_flag g_once_flag; + llvm::call_once(g_once_flag, []() { + FileSpec module; + ConstString function; + std::tie(module, function) = AppleObjCRuntime::GetExceptionThrowLocation(); + StackFrameRecognizerManager::AddRecognizer( + StackFrameRecognizerSP(new ObjCExceptionThrowFrameRecognizer()), + module.GetFilename(), function, /*first_instruction_only*/ true); + }); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h index 487b67ca6271..aa91f857219b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h @@ -10,14 +10,10 @@ #ifndef liblldb_AppleObjCRuntimeV2_h_ #define liblldb_AppleObjCRuntimeV2_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "AppleObjCRuntime.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp index c75fa71ba131..e9182c590977 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp @@ -10,10 +10,6 @@ #include "AppleObjCTrampolineHandler.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "AppleThreadPlanStepThroughObjCTrampoline.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" @@ -80,7 +76,7 @@ extern \"C\" void * __lldb_objc_find_implementation_for_selector ( \n\ void *super_ptr; \n\ }; \n\ struct __lldb_objc_super { \n\ - void *reciever; \n\ + void *receiver; \n\ struct __lldb_objc_class *class_ptr; \n\ }; \n\ struct __lldb_msg_ref { \n\ @@ -202,7 +198,7 @@ extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, void *super_ptr; \n\ }; \n\ struct __lldb_objc_super { \n\ - void *reciever; \n\ + void *receiver; \n\ struct __lldb_objc_class *class_ptr; \n\ }; \n\ struct __lldb_msg_ref { \n\ diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h index dc58a8bc1eb6..fe3390757d08 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h @@ -10,14 +10,10 @@ #ifndef lldb_AppleObjCTrampolineHandler_h_ #define lldb_AppleObjCTrampolineHandler_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Expression/UtilityFunction.h" #include "lldb/lldb-public.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h index 4da84dd92c3f..fac564e33165 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.h @@ -10,12 +10,8 @@ #ifndef liblldb_AppleObjCTypeEncodingParser_h_ #define liblldb_AppleObjCTypeEncodingParser_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "clang/AST/ASTContext.h" -// Project includes #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp index 75b670739427..2b54d0a542d9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp @@ -8,10 +8,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "AppleThreadPlanStepThroughObjCTrampoline.h" #include "AppleObjCTrampolineHandler.h" #include "lldb/Expression/DiagnosticManager.h" @@ -161,13 +157,15 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { SymbolContext sc = m_thread.GetStackFrameAtIndex(0)->GetSymbolContext( eSymbolContextEverything); + Status status; const bool abort_other_plans = false; const bool first_insn = true; const uint32_t frame_idx = 0; m_run_to_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop( abort_other_plans, &sc, first_insn, m_stop_others, eVoteNoOpinion, - eVoteNoOpinion, frame_idx); - m_run_to_sp->SetPrivate(true); + eVoteNoOpinion, frame_idx, status); + if (m_run_to_sp && status.Success()) + m_run_to_sp->SetPrivate(true); return false; } @@ -202,10 +200,7 @@ bool AppleThreadPlanStepThroughObjCTrampoline::ShouldStop(Event *event_ptr) { // The base class MischiefManaged does some cleanup - so you have to call it in // your MischiefManaged derived class. bool AppleThreadPlanStepThroughObjCTrampoline::MischiefManaged() { - if (IsPlanComplete()) - return true; - else - return false; + return IsPlanComplete(); } bool AppleThreadPlanStepThroughObjCTrampoline::WillStop() { return true; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h index 60c8b92d9cc7..5758e19f83ca 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h @@ -10,10 +10,6 @@ #ifndef lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ #define lldb_AppleThreadPlanStepThroughObjCTrampoline_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "AppleObjCTrampolineHandler.h" #include "lldb/Core/Value.h" #include "lldb/Target/ThreadPlan.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp index cbbc35f1c08a..2c12cf9af637 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.cpp @@ -7,11 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/None.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/Instruction.h" @@ -24,7 +21,6 @@ #include "clang/Basic/TargetOptions.h" -// Project includes #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h index f45ff83c5a2b..647558171d1c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptExpressionOpts.h @@ -10,15 +10,11 @@ #ifndef LLDB_RENDERSCRIPT_EXPROPTS_H #define LLDB_RENDERSCRIPT_EXPROPTS_H -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/IR/Module.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" -// Project includes #include "lldb/Target/LanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp index 4eb15369aa1e..fa775d9bfa94 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes #include "llvm/ADT/StringSwitch.h" -// Project includes #include "RenderScriptRuntime.h" #include "RenderScriptScriptGroup.h" @@ -20,7 +16,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/DataFormatters/DumpValueObjectOptions.h" #include "lldb/Expression/UserExpression.h" @@ -41,8 +36,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/ConstString.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Status.h" @@ -2079,10 +2074,8 @@ bool RenderScriptRuntime::JITElementPacked(Element &elem, // If this Element has subelements then JIT rsaElementGetSubElements() for // details about its fields - if (*elem.field_count.get() > 0 && !JITSubelements(elem, context, frame_ptr)) - return false; - - return true; + return !(*elem.field_count.get() > 0 && + !JITSubelements(elem, context, frame_ptr)); } // JITs the RS runtime for information about the subelements/fields of a struct @@ -2305,10 +2298,7 @@ bool RenderScriptRuntime::RefreshAllocation(AllocationDetails *alloc, SetElementSize(alloc->element); // Use GetOffsetPointer() to infer size of the allocation - if (!JITAllocationSize(alloc, frame_ptr)) - return false; - - return true; + return JITAllocationSize(alloc, frame_ptr); } // Function attempts to set the type_name member of the paramaterised Element @@ -2529,21 +2519,22 @@ bool RenderScriptRuntime::LoadAllocation(Stream &strm, const uint32_t alloc_id, "Allocation information not available"); // Check we can read from file - FileSpec file(path, true); - if (!file.Exists()) { + FileSpec file(path); + FileSystem::Instance().Resolve(file); + if (!FileSystem::Instance().Exists(file)) { strm.Printf("Error: File %s does not exist", path); strm.EOL(); return false; } - if (!file.Readable()) { + if (!FileSystem::Instance().Readable(file)) { strm.Printf("Error: File %s does not have readable permissions", path); strm.EOL(); return false; } // Read file into data buffer - auto data_sp = DataBufferLLVM::CreateFromPath(file.GetPath()); + auto data_sp = FileSystem::Instance().CreateDataBuffer(file.GetPath()); // Cast start of buffer to FileHeader and use pointer to read metadata void *file_buf = data_sp->GetBytes(); @@ -2753,9 +2744,14 @@ bool RenderScriptRuntime::SaveAllocation(Stream &strm, const uint32_t alloc_id, "Allocation information not available"); // Check we can create writable file - FileSpec file_spec(path, true); - File file(file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | - File::eOpenOptionTruncate); + FileSpec file_spec(path); + FileSystem::Instance().Resolve(file_spec); + File file; + FileSystem::Instance().Open(file, file_spec, + File::eOpenOptionWrite | + File::eOpenOptionCanCreate | + File::eOpenOptionTruncate); + if (!file) { strm.Printf("Error: Failed to open '%s' for writing", path); strm.EOL(); @@ -3079,7 +3075,8 @@ bool RSModuleDescriptor::ParseRSInfo() { const addr_t size = info_sym->GetByteSize(); const FileSpec fs = m_module->GetFileSpec(); - auto buffer = DataBufferLLVM::CreateSliceFromPath(fs.GetPath(), size, addr); + auto buffer = + FileSystem::Instance().CreateDataBuffer(fs.GetPath(), size, addr); if (!buffer) return false; @@ -3718,7 +3715,8 @@ bool RenderScriptRuntime::GetKernelCoordinate(RSCoordinate &coord, continue; // Find the function name - const SymbolContext sym_ctx = frame_sp->GetSymbolContext(false); + const SymbolContext sym_ctx = + frame_sp->GetSymbolContext(eSymbolContextFunction); const ConstString func_name = sym_ctx.GetFunctionName(); if (!func_name) continue; @@ -4171,13 +4169,13 @@ public: } }; -static OptionDefinition g_renderscript_reduction_bp_set_options[] = { +static constexpr OptionDefinition g_renderscript_reduction_bp_set_options[] = { {LLDB_OPT_SET_1, false, "function-role", 't', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Break on a comma separated set of reduction kernel types " "(accumulator,outcoverter,combiner,initializer"}, {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeValue, + nullptr, {}, 0, eArgTypeValue, "Set a breakpoint on a single invocation of the kernel with specified " "coordinate.\n" "Coordinate takes the form 'x[,y][,z] where x,y,z are positive " @@ -4330,9 +4328,9 @@ private: CommandOptions m_options; }; -static OptionDefinition g_renderscript_kernel_bp_set_options[] = { +static constexpr OptionDefinition g_renderscript_kernel_bp_set_options[] = { {LLDB_OPT_SET_1, false, "coordinate", 'c', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeValue, + nullptr, {}, 0, eArgTypeValue, "Set a breakpoint on a single invocation of the kernel with specified " "coordinate.\n" "Coordinate takes the form 'x[,y][,z] where x,y,z are positive " @@ -4602,9 +4600,9 @@ public: } }; -static OptionDefinition g_renderscript_runtime_alloc_dump_options[] = { +static constexpr OptionDefinition g_renderscript_runtime_alloc_dump_options[] = { {LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeFilename, + nullptr, {}, 0, eArgTypeFilename, "Print results to specified file instead of command line."}}; class CommandObjectRenderScriptRuntimeContext : public CommandObjectMultiword { @@ -4650,8 +4648,9 @@ public: switch (short_option) { case 'f': - m_outfile.SetFile(option_arg, true, FileSpec::Style::native); - if (m_outfile.Exists()) { + m_outfile.SetFile(option_arg, FileSpec::Style::native); + FileSystem::Instance().Resolve(m_outfile); + if (FileSystem::Instance().Exists(m_outfile)) { m_outfile.Clear(); err.SetErrorStringWithFormat("file already exists: '%s'", option_arg.str().c_str()); @@ -4706,16 +4705,17 @@ public: m_options.m_outfile; // Dump allocation to file instead if (outfile_spec) { // Open output file - char path[256]; - outfile_spec.GetPath(path, sizeof(path)); - if (outfile_stream.GetFile() - .Open(path, File::eOpenOptionWrite | File::eOpenOptionCanCreate) - .Success()) { + std::string path = outfile_spec.GetPath(); + auto error = FileSystem::Instance().Open( + outfile_stream.GetFile(), outfile_spec, + File::eOpenOptionWrite | File::eOpenOptionCanCreate); + if (error.Success()) { output_strm = &outfile_stream; - result.GetOutputStream().Printf("Results written to '%s'", path); + result.GetOutputStream().Printf("Results written to '%s'", + path.c_str()); result.GetOutputStream().EOL(); } else { - result.AppendErrorWithFormat("Couldn't open file '%s'", path); + result.AppendErrorWithFormat("Couldn't open file '%s'", path.c_str()); result.SetStatus(eReturnStatusFailed); return false; } @@ -4738,9 +4738,9 @@ private: CommandOptions m_options; }; -static OptionDefinition g_renderscript_runtime_alloc_list_options[] = { +static constexpr OptionDefinition g_renderscript_runtime_alloc_list_options[] = { {LLDB_OPT_SET_1, false, "id", 'i', OptionParser::eRequiredArgument, nullptr, - nullptr, 0, eArgTypeIndex, + {}, 0, eArgTypeIndex, "Only show details of a single allocation with specified id."}}; class CommandObjectRenderScriptRuntimeAllocationList diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h index 0fe9134ce9e4..31714dd4a453 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.h @@ -10,18 +10,14 @@ #ifndef liblldb_RenderScriptRuntime_h_ #define liblldb_RenderScriptRuntime_h_ -// C Includes -// C++ Includes #include #include #include #include #include -// Other libraries and framework includes #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -// Project includes #include "lldb/Core/Module.h" #include "lldb/Expression/LLVMUserExpression.h" #include "lldb/Target/CPPLanguageRuntime.h" @@ -74,7 +70,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override { return Searcher::eDepthModule; } + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override { @@ -124,7 +120,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override { return Searcher::eDepthModule; } + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override { @@ -269,7 +265,7 @@ public: SymbolContext &context, Address *addr, bool containing) override; - Searcher::Depth GetDepth() override { return Searcher::eDepthModule; } + lldb::SearchDepth GetDepth() override { return lldb::eSearchDepthModule; } lldb::BreakpointResolverSP CopyForBreakpoint(Breakpoint &breakpoint) override { diff --git a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp index e1f8ea648414..0b298c90a50b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptx86ABIFixups.cpp @@ -7,11 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/StringRef.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CallSite.h" @@ -23,7 +20,6 @@ #include "llvm/IRReader/IRReader.h" #include "llvm/Pass.h" -// Project includes #include "lldb/Target/Process.h" #include "lldb/Utility/Log.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h b/contrib/llvm/tools/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h index 31e9873fb1ee..c08acd0151ef 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h +++ b/contrib/llvm/tools/lldb/source/Plugins/MemoryHistory/asan/MemoryHistoryASan.h @@ -10,10 +10,6 @@ #ifndef liblldb_MemoryHistoryASan_h_ #define liblldb_MemoryHistoryASan_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "lldb/Target/MemoryHistory.h" #include "lldb/Target/Process.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp b/contrib/llvm/tools/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp index 275f1fa2f70b..391ab7546967 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp @@ -33,7 +33,6 @@ typedef struct ar_hdr { #include "lldb/Host/FileSystem.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" @@ -208,7 +207,7 @@ ObjectContainerBSDArchive::Archive::FindCachedArchive( while (pos != archive_map.end() && pos->first == file) { bool match = true; if (arch.IsValid() && - pos->second->GetArchitecture().IsCompatibleMatch(arch) == false) + !pos->second->GetArchitecture().IsCompatibleMatch(arch)) match = false; else if (file_offset != LLDB_INVALID_OFFSET && pos->second->GetFileOffset() != file_offset) @@ -313,7 +312,7 @@ ObjectContainer *ObjectContainerBSDArchive::CreateInstance( // file gets updated by a new build while this .a file is being used for // debugging DataBufferSP archive_data_sp = - DataBufferLLVM::CreateSliceFromPath(file->GetPath(), length, file_offset); + FileSystem::Instance().CreateDataBuffer(*file, length, file_offset); if (!archive_data_sp) return nullptr; @@ -461,14 +460,14 @@ size_t ObjectContainerBSDArchive::GetModuleSpecifications( return 0; const size_t initial_count = specs.GetSize(); - llvm::sys::TimePoint<> file_mod_time = FileSystem::GetModificationTime(file); + llvm::sys::TimePoint<> file_mod_time = FileSystem::Instance().GetModificationTime(file); Archive::shared_ptr archive_sp( Archive::FindCachedArchive(file, ArchSpec(), file_mod_time, file_offset)); bool set_archive_arch = false; if (!archive_sp) { set_archive_arch = true; data_sp = - DataBufferLLVM::CreateSliceFromPath(file.GetPath(), file_size, file_offset); + FileSystem::Instance().CreateDataBuffer(file, file_size, file_offset); if (data_sp) { data.SetData(data_sp, 0, data_sp->GetByteSize()); archive_sp = Archive::ParseAndCacheArchiveForFile( diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h b/contrib/llvm/tools/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h index cb63eccff65e..86eaee1375a6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h @@ -16,11 +16,8 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/FileSpec.h" -// Other libraries and framework includes #include "llvm/Support/Chrono.h" -// C Includes -// C++ Includes #include #include #include diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp new file mode 100644 index 000000000000..917025030ada --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.cpp @@ -0,0 +1,315 @@ +//===-- ObjectFileBreakpad.cpp -------------------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h" +#include "lldb/Core/ModuleSpec.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Utility/DataBuffer.h" +#include "llvm/ADT/StringExtras.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::breakpad; + +namespace { +struct Header { + ArchSpec arch; + UUID uuid; + static llvm::Optional
parse(llvm::StringRef text); +}; + +enum class Token { Unknown, Module, Info, File, Func, Public, Stack }; +} // namespace + +static Token toToken(llvm::StringRef str) { + return llvm::StringSwitch(str) + .Case("MODULE", Token::Module) + .Case("INFO", Token::Info) + .Case("FILE", Token::File) + .Case("FUNC", Token::Func) + .Case("PUBLIC", Token::Public) + .Case("STACK", Token::Stack) + .Default(Token::Unknown); +} + +static llvm::StringRef toString(Token t) { + switch (t) { + case Token::Unknown: + return ""; + case Token::Module: + return "MODULE"; + case Token::Info: + return "INFO"; + case Token::File: + return "FILE"; + case Token::Func: + return "FUNC"; + case Token::Public: + return "PUBLIC"; + case Token::Stack: + return "STACK"; + } + llvm_unreachable("Unknown token!"); +} + +static llvm::Triple::OSType toOS(llvm::StringRef str) { + using llvm::Triple; + return llvm::StringSwitch(str) + .Case("Linux", Triple::Linux) + .Case("mac", Triple::MacOSX) + .Case("windows", Triple::Win32) + .Default(Triple::UnknownOS); +} + +static llvm::Triple::ArchType toArch(llvm::StringRef str) { + using llvm::Triple; + return llvm::StringSwitch(str) + .Case("arm", Triple::arm) + .Case("arm64", Triple::aarch64) + .Case("mips", Triple::mips) + .Case("ppc", Triple::ppc) + .Case("ppc64", Triple::ppc64) + .Case("s390", Triple::systemz) + .Case("sparc", Triple::sparc) + .Case("sparcv9", Triple::sparcv9) + .Case("x86", Triple::x86) + .Case("x86_64", Triple::x86_64) + .Default(Triple::UnknownArch); +} + +static llvm::StringRef consume_front(llvm::StringRef &str, size_t n) { + llvm::StringRef result = str.take_front(n); + str = str.drop_front(n); + return result; +} + +static UUID parseModuleId(llvm::Triple::OSType os, llvm::StringRef str) { + struct uuid_data { + llvm::support::ulittle32_t uuid1; + llvm::support::ulittle16_t uuid2[2]; + uint8_t uuid3[8]; + llvm::support::ulittle32_t age; + } data; + static_assert(sizeof(data) == 20, ""); + // The textual module id encoding should be between 33 and 40 bytes long, + // depending on the size of the age field, which is of variable length. + // The first three chunks of the id are encoded in big endian, so we need to + // byte-swap those. + if (str.size() < 33 || str.size() > 40) + return UUID(); + uint32_t t; + if (to_integer(consume_front(str, 8), t, 16)) + data.uuid1 = t; + else + return UUID(); + for (int i = 0; i < 2; ++i) { + if (to_integer(consume_front(str, 4), t, 16)) + data.uuid2[i] = t; + else + return UUID(); + } + for (int i = 0; i < 8; ++i) { + if (!to_integer(consume_front(str, 2), data.uuid3[i], 16)) + return UUID(); + } + if (to_integer(str, t, 16)) + data.age = t; + else + return UUID(); + + // On non-windows, the age field should always be zero, so we don't include to + // match the native uuid format of these platforms. + return UUID::fromData(&data, os == llvm::Triple::Win32 ? 20 : 16); +} + +llvm::Optional
Header::parse(llvm::StringRef text) { + // A valid module should start with something like: + // MODULE Linux x86_64 E5894855C35DCCCCCCCCCCCCCCCCCCCC0 a.out + // optionally followed by + // INFO CODE_ID 554889E55DC3CCCCCCCCCCCCCCCCCCCC [a.exe] + llvm::StringRef token, line; + std::tie(line, text) = text.split('\n'); + std::tie(token, line) = getToken(line); + if (toToken(token) != Token::Module) + return llvm::None; + + std::tie(token, line) = getToken(line); + llvm::Triple triple; + triple.setOS(toOS(token)); + if (triple.getOS() == llvm::Triple::UnknownOS) + return llvm::None; + + std::tie(token, line) = getToken(line); + triple.setArch(toArch(token)); + if (triple.getArch() == llvm::Triple::UnknownArch) + return llvm::None; + + llvm::StringRef module_id; + std::tie(module_id, line) = getToken(line); + + std::tie(line, text) = text.split('\n'); + std::tie(token, line) = getToken(line); + if (token == "INFO") { + std::tie(token, line) = getToken(line); + if (token != "CODE_ID") + return llvm::None; + + std::tie(token, line) = getToken(line); + // If we don't have any text following the code id (e.g. on linux), we + // should use the module id as UUID. Otherwise, we revert back to the module + // id. + if (line.trim().empty()) { + UUID uuid; + if (uuid.SetFromStringRef(token, token.size() / 2) != token.size()) + return llvm::None; + + return Header{ArchSpec(triple), uuid}; + } + } + + // We reach here if we don't have a INFO CODE_ID section, or we chose not to + // use it. In either case, we need to properly decode the module id, whose + // fields are encoded in big-endian. + UUID uuid = parseModuleId(triple.getOS(), module_id); + if (!uuid) + return llvm::None; + + return Header{ArchSpec(triple), uuid}; +} + +void ObjectFileBreakpad::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + CreateMemoryInstance, GetModuleSpecifications); +} + +void ObjectFileBreakpad::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ConstString ObjectFileBreakpad::GetPluginNameStatic() { + static ConstString g_name("breakpad"); + return g_name; +} + +ObjectFile *ObjectFileBreakpad::CreateInstance( + const ModuleSP &module_sp, DataBufferSP &data_sp, offset_t data_offset, + const FileSpec *file, offset_t file_offset, offset_t length) { + if (!data_sp) { + data_sp = MapFileData(*file, length, file_offset); + if (!data_sp) + return nullptr; + data_offset = 0; + } + auto text = toStringRef(data_sp->GetData()); + llvm::Optional
header = Header::parse(text); + if (!header) + return nullptr; + + // Update the data to contain the entire file if it doesn't already + if (data_sp->GetByteSize() < length) { + data_sp = MapFileData(*file, length, file_offset); + if (!data_sp) + return nullptr; + data_offset = 0; + } + + return new ObjectFileBreakpad(module_sp, data_sp, data_offset, file, + file_offset, length, std::move(header->arch), + std::move(header->uuid)); +} + +ObjectFile *ObjectFileBreakpad::CreateMemoryInstance( + const ModuleSP &module_sp, DataBufferSP &data_sp, + const ProcessSP &process_sp, addr_t header_addr) { + return nullptr; +} + +size_t ObjectFileBreakpad::GetModuleSpecifications( + const FileSpec &file, DataBufferSP &data_sp, offset_t data_offset, + offset_t file_offset, offset_t length, ModuleSpecList &specs) { + auto text = toStringRef(data_sp->GetData()); + llvm::Optional
header = Header::parse(text); + if (!header) + return 0; + ModuleSpec spec(file, std::move(header->arch)); + spec.GetUUID() = std::move(header->uuid); + specs.Append(spec); + return 1; +} + +ObjectFileBreakpad::ObjectFileBreakpad(const ModuleSP &module_sp, + DataBufferSP &data_sp, + offset_t data_offset, + const FileSpec *file, offset_t offset, + offset_t length, ArchSpec arch, + UUID uuid) + : ObjectFile(module_sp, file, offset, length, data_sp, data_offset), + m_arch(std::move(arch)), m_uuid(std::move(uuid)) {} + +bool ObjectFileBreakpad::ParseHeader() { + // We already parsed the header during initialization. + return true; +} + +Symtab *ObjectFileBreakpad::GetSymtab() { + // TODO + return nullptr; +} + +bool ObjectFileBreakpad::GetUUID(UUID *uuid) { + *uuid = m_uuid; + return true; +} + +void ObjectFileBreakpad::CreateSections(SectionList &unified_section_list) { + if (m_sections_ap) + return; + m_sections_ap = llvm::make_unique(); + + Token current_section = Token::Unknown; + offset_t section_start; + llvm::StringRef text = toStringRef(m_data.GetData()); + uint32_t next_section_id = 1; + auto maybe_add_section = [&](const uint8_t *end_ptr) { + if (current_section == Token::Unknown) + return; // We have been called before parsing the first line. + + offset_t end_offset = end_ptr - m_data.GetDataStart(); + auto section_sp = std::make_shared
( + GetModule(), this, next_section_id++, + ConstString(toString(current_section)), eSectionTypeOther, + /*file_vm_addr*/ 0, /*vm_size*/ 0, section_start, + end_offset - section_start, /*log2align*/ 0, /*flags*/ 0); + m_sections_ap->AddSection(section_sp); + unified_section_list.AddSection(section_sp); + }; + while (!text.empty()) { + llvm::StringRef line; + std::tie(line, text) = text.split('\n'); + + Token token = toToken(getToken(line).first); + if (token == Token::Unknown) { + // We assume this is a line record, which logically belongs to the Func + // section. Errors will be handled when parsing the Func section. + token = Token::Func; + } + if (token == current_section) + continue; + + // Changing sections, finish off the previous one, if there was any. + maybe_add_section(line.bytes_begin()); + // And start a new one. + current_section = token; + section_start = line.bytes_begin() - m_data.GetDataStart(); + } + // Finally, add the last section. + maybe_add_section(m_data.GetDataEnd()); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h new file mode 100644 index 000000000000..ba2a3ad30e5f --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h @@ -0,0 +1,109 @@ +//===-- ObjectFileBreakpad.h ---------------------------------- -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H +#define LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H + +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/ArchSpec.h" +#include "llvm/ADT/Triple.h" + +namespace lldb_private { +namespace breakpad { + +class ObjectFileBreakpad : public ObjectFile { +public: + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); + static void Terminate(); + + static ConstString GetPluginNameStatic(); + static const char *GetPluginDescriptionStatic() { + return "Breakpad object file reader."; + } + + static ObjectFile * + CreateInstance(const lldb::ModuleSP &module_sp, lldb::DataBufferSP &data_sp, + lldb::offset_t data_offset, const FileSpec *file, + lldb::offset_t file_offset, lldb::offset_t length); + + static ObjectFile *CreateMemoryInstance(const lldb::ModuleSP &module_sp, + lldb::DataBufferSP &data_sp, + const lldb::ProcessSP &process_sp, + lldb::addr_t header_addr); + + static size_t GetModuleSpecifications(const FileSpec &file, + lldb::DataBufferSP &data_sp, + lldb::offset_t data_offset, + lldb::offset_t file_offset, + lldb::offset_t length, + ModuleSpecList &specs); + + //------------------------------------------------------------------ + // PluginInterface protocol + //------------------------------------------------------------------ + ConstString GetPluginName() override { return GetPluginNameStatic(); } + + uint32_t GetPluginVersion() override { return 1; } + + //------------------------------------------------------------------ + // ObjectFile Protocol. + //------------------------------------------------------------------ + + bool ParseHeader() override; + + lldb::ByteOrder GetByteOrder() const override { + return m_arch.GetByteOrder(); + } + + bool IsExecutable() const override { return false; } + + uint32_t GetAddressByteSize() const override { + return m_arch.GetAddressByteSize(); + } + + AddressClass GetAddressClass(lldb::addr_t file_addr) override { + return AddressClass::eInvalid; + } + + Symtab *GetSymtab() override; + + bool IsStripped() override { return false; } + + void CreateSections(SectionList &unified_section_list) override; + + void Dump(Stream *s) override {} + + ArchSpec GetArchitecture() override { return m_arch; } + + bool GetUUID(UUID *uuid) override; + + FileSpecList GetDebugSymbolFilePaths() override { return FileSpecList(); } + + uint32_t GetDependentModules(FileSpecList &files) override { return 0; } + + Type CalculateType() override { return eTypeDebugInfo; } + + Strata CalculateStrata() override { return eStrataUser; } + +private: + ArchSpec m_arch; + UUID m_uuid; + + ObjectFileBreakpad(const lldb::ModuleSP &module_sp, + lldb::DataBufferSP &data_sp, lldb::offset_t data_offset, + const FileSpec *file, lldb::offset_t offset, + lldb::offset_t length, ArchSpec arch, UUID uuid); +}; + +} // namespace breakpad +} // namespace lldb_private +#endif // LLDB_PLUGINS_OBJECTFILE_BREAKPAD_OBJECTFILEBREAKPAD_H diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp index 16cbb6e5753b..3d4735286bf2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp @@ -38,7 +38,7 @@ static bool GetMaxU64(const lldb_private::DataExtractor &data, lldb::offset_t saved_offset = *offset; for (uint32_t i = 0; i < count; ++i, ++value) { - if (GetMaxU64(data, offset, value, byte_size) == false) { + if (!GetMaxU64(data, offset, value, byte_size)) { *offset = saved_offset; return false; } @@ -60,7 +60,7 @@ static bool GetMaxS64(const lldb_private::DataExtractor &data, lldb::offset_t saved_offset = *offset; for (uint32_t i = 0; i < count; ++i, ++value) { - if (GetMaxS64(data, offset, value, byte_size) == false) { + if (!GetMaxS64(data, offset, value, byte_size)) { *offset = saved_offset; return false; } @@ -133,7 +133,7 @@ bool ELFHeader::Parse(lldb_private::DataExtractor &data, return false; // Read e_entry, e_phoff and e_shoff. - if (GetMaxU64(data, offset, &e_entry, byte_size, 3) == false) + if (!GetMaxU64(data, offset, &e_entry, byte_size, 3)) return false; // Read e_flags. @@ -232,11 +232,11 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, return false; // Read sh_flags. - if (GetMaxU64(data, offset, &sh_flags, byte_size) == false) + if (!GetMaxU64(data, offset, &sh_flags, byte_size)) return false; // Read sh_addr, sh_off and sh_size. - if (GetMaxU64(data, offset, &sh_addr, byte_size, 3) == false) + if (!GetMaxU64(data, offset, &sh_addr, byte_size, 3)) return false; // Read sh_link and sh_info. @@ -244,7 +244,7 @@ bool ELFSectionHeader::Parse(const lldb_private::DataExtractor &data, return false; // Read sh_addralign and sh_entsize. - if (GetMaxU64(data, offset, &sh_addralign, byte_size, 2) == false) + if (!GetMaxU64(data, offset, &sh_addralign, byte_size, 2)) return false; return true; @@ -332,7 +332,7 @@ bool ELFSymbol::Parse(const lldb_private::DataExtractor &data, if (parsing_32) { // Read st_value and st_size. - if (GetMaxU64(data, offset, &st_value, byte_size, 2) == false) + if (!GetMaxU64(data, offset, &st_value, byte_size, 2)) return false; // Read st_info and st_other. @@ -376,7 +376,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, if (parsing_32) { // Read p_offset, p_vaddr, p_paddr, p_filesz and p_memsz. - if (GetMaxU64(data, offset, &p_offset, byte_size, 5) == false) + if (!GetMaxU64(data, offset, &p_offset, byte_size, 5)) return false; // Read p_flags. @@ -384,7 +384,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, return false; // Read p_align. - if (GetMaxU64(data, offset, &p_align, byte_size) == false) + if (!GetMaxU64(data, offset, &p_align, byte_size)) return false; } else { // Read p_flags. @@ -392,7 +392,7 @@ bool ELFProgramHeader::Parse(const lldb_private::DataExtractor &data, return false; // Read p_offset, p_vaddr, p_paddr, p_filesz, p_memsz and p_align. - if (GetMaxU64(data, offset, &p_offset, byte_size, 6) == false) + if (!GetMaxU64(data, offset, &p_offset, byte_size, 6)) return false; } @@ -420,10 +420,7 @@ bool ELFRel::Parse(const lldb_private::DataExtractor &data, const unsigned byte_size = data.GetAddressByteSize(); // Read r_offset and r_info. - if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) - return false; - - return true; + return GetMaxU64(data, offset, &r_offset, byte_size, 2) != false; } //------------------------------------------------------------------------------ @@ -436,11 +433,11 @@ bool ELFRela::Parse(const lldb_private::DataExtractor &data, const unsigned byte_size = data.GetAddressByteSize(); // Read r_offset and r_info. - if (GetMaxU64(data, offset, &r_offset, byte_size, 2) == false) + if (!GetMaxU64(data, offset, &r_offset, byte_size, 2)) return false; // Read r_addend; - if (GetMaxS64(data, offset, &r_addend, byte_size) == false) + if (!GetMaxS64(data, offset, &r_addend, byte_size)) return false; return true; diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp index 8701908378f1..9a6563afa0a0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp @@ -17,7 +17,9 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/RangeMap.h" #include "lldb/Core/Section.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Symbol/DWARFCallFrameInfo.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/SectionLoadList.h" @@ -29,6 +31,7 @@ #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" +#include "llvm/ADT/IntervalMap.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/StringRef.h" #include "llvm/Object/Decompressor.h" @@ -235,6 +238,8 @@ unsigned ELFRelocation::RelocAddend64(const ELFRelocation &rel) { } // end anonymous namespace +static user_id_t SegmentID(size_t PHdrIndex) { return ~PHdrIndex; } + bool ELFNote::Parse(const DataExtractor &data, lldb::offset_t *offset) { // Read all fields. if (data.GetU32(offset, &n_namesz, 3) == NULL) @@ -433,9 +438,8 @@ ObjectFile *ObjectFileELF::CreateInstance(const lldb::ModuleSP &module_sp, if (address_size == 4 || address_size == 8) { std::unique_ptr objfile_ap(new ObjectFileELF( module_sp, data_sp, data_offset, file, file_offset, length)); - ArchSpec spec; - if (objfile_ap->GetArchitecture(spec) && - objfile_ap->SetModulesArchitecture(spec)) + ArchSpec spec = objfile_ap->GetArchitecture(); + if (spec && objfile_ap->SetModulesArchitecture(spec)) return objfile_ap.release(); } @@ -452,9 +456,8 @@ ObjectFile *ObjectFileELF::CreateMemoryInstance( if (address_size == 4 || address_size == 8) { std::unique_ptr objfile_ap( new ObjectFileELF(module_sp, data_sp, process_sp, header_addr)); - ArchSpec spec; - if (objfile_ap->GetArchitecture(spec) && - objfile_ap->SetModulesArchitecture(spec)) + ArchSpec spec = objfile_ap->GetArchitecture(); + if (spec && objfile_ap->SetModulesArchitecture(spec)) return objfile_ap.release(); } } @@ -538,14 +541,13 @@ static uint32_t calc_gnu_debuglink_crc32(const void *buf, size_t size) { uint32_t ObjectFileELF::CalculateELFNotesSegmentsCRC32( const ProgramHeaderColl &program_headers, DataExtractor &object_data) { - typedef ProgramHeaderCollConstIter Iter; uint32_t core_notes_crc = 0; - for (Iter I = program_headers.begin(); I != program_headers.end(); ++I) { - if (I->p_type == llvm::ELF::PT_NOTE) { - const elf_off ph_offset = I->p_offset; - const size_t ph_size = I->p_filesz; + for (const ELFProgramHeader &H : program_headers) { + if (H.p_type == llvm::ELF::PT_NOTE) { + const elf_off ph_offset = H.p_offset; + const size_t ph_size = H.p_filesz; DataExtractor segment_data; if (segment_data.SetData(object_data, ph_offset, ph_size) != ph_size) { @@ -713,7 +715,8 @@ size_t ObjectFileELF::GetModuleSpecifications( func_cat, "Calculating module crc32 %s with size %" PRIu64 " KiB", file.GetLastPathComponent().AsCString(), - (file.GetByteSize() - file_offset) / 1024); + (FileSystem::Instance().GetByteSize(file) - file_offset) / + 1024); // For core files - which usually don't happen to have a // gnu_debuglink, and are pretty bulky - calculating whole @@ -803,21 +806,10 @@ bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value, SectionList *section_list = GetSectionList(); if (section_list) { if (!value_is_offset) { - bool found_offset = false; - for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) { - const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i); - if (header == nullptr) - continue; - - if (header->p_type != PT_LOAD || header->p_offset != 0) - continue; - - value = value - header->p_vaddr; - found_offset = true; - break; - } - if (!found_offset) + addr_t base = GetBaseAddress().GetFileAddress(); + if (base == LLDB_INVALID_ADDRESS) return false; + value -= base; } const size_t num_sections = section_list->GetSize(); @@ -827,7 +819,8 @@ bool ObjectFileELF::SetLoadAddress(Target &target, lldb::addr_t value, // Iterate through the object file sections to find all of the sections // that have SHF_ALLOC in their flag bits. SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); - if (section_sp && section_sp->Test(SHF_ALLOC)) { + if (section_sp->Test(SHF_ALLOC) || + section_sp->GetType() == eSectionTypeContainer) { lldb::addr_t load_addr = section_sp->GetFileAddress(); // We don't want to update the load address of a section with type // eSectionTypeAbsoluteAddress as they already have the absolute load @@ -892,11 +885,11 @@ AddressClass ObjectFileELF::GetAddressClass(addr_t file_addr) { } size_t ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I) { - return std::distance(m_section_headers.begin(), I) + 1u; + return std::distance(m_section_headers.begin(), I); } size_t ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const { - return std::distance(m_section_headers.begin(), I) + 1u; + return std::distance(m_section_headers.begin(), I); } bool ObjectFileELF::ParseHeader() { @@ -953,7 +946,7 @@ lldb_private::FileSpecList ObjectFileELF::GetDebugSymbolFilePaths() { FileSpecList file_spec_list; if (!m_gnu_debuglink_file.empty()) { - FileSpec file_spec(m_gnu_debuglink_file, false); + FileSpec file_spec(m_gnu_debuglink_file); file_spec_list.Append(file_spec); } return file_spec_list; @@ -1055,6 +1048,18 @@ lldb_private::Address ObjectFileELF::GetEntryPointAddress() { return m_entry_point_address; } +Address ObjectFileELF::GetBaseAddress() { + for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { + const ELFProgramHeader &H = EnumPHdr.value(); + if (H.p_type != PT_LOAD) + continue; + + return Address( + GetSectionList()->FindSectionByID(SegmentID(EnumPHdr.index())), 0); + } + return LLDB_INVALID_ADDRESS; +} + //---------------------------------------------------------------------- // ParseDependentModules //---------------------------------------------------------------------- @@ -1084,7 +1089,7 @@ size_t ObjectFileELF::ParseDependentModules() { return 0; // sh_link: section header index of string table used by entries in the // section. - Section *dynstr = section_list->FindSectionByID(header->sh_link + 1).get(); + Section *dynstr = section_list->FindSectionByID(header->sh_link).get(); if (!dynstr) return 0; @@ -1107,7 +1112,9 @@ size_t ObjectFileELF::ParseDependentModules() { uint32_t str_index = static_cast(symbol.d_val); const char *lib_name = dynstr_data.PeekCStr(str_index); - m_filespec_ap->Append(FileSpec(lib_name, true)); + FileSpec file_spec(lib_name); + FileSystem::Instance().Resolve(file_spec); + m_filespec_ap->Append(file_spec); } } @@ -1141,7 +1148,7 @@ size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, uint32_t idx; lldb::offset_t offset; for (idx = 0, offset = 0; idx < header.e_phnum; ++idx) { - if (program_headers[idx].Parse(data, &offset) == false) + if (!program_headers[idx].Parse(data, &offset)) break; } @@ -1154,8 +1161,8 @@ size_t ObjectFileELF::GetProgramHeaderInfo(ProgramHeaderColl &program_headers, //---------------------------------------------------------------------- // ParseProgramHeaders //---------------------------------------------------------------------- -size_t ObjectFileELF::ParseProgramHeaders() { - return GetProgramHeaderInfo(m_program_headers, m_data, m_header); +bool ObjectFileELF::ParseProgramHeaders() { + return GetProgramHeaderInfo(m_program_headers, m_data, m_header) != 0; } lldb_private::Status @@ -1390,7 +1397,7 @@ ObjectFileELF::RefineModuleDetailsFromNote(lldb_private::DataExtractor &data, arch_spec.GetTriple().getOS() == llvm::Triple::OSType::UnknownOS) // In case of MIPSR6, the LLDB_NT_OWNER_GNU note is missing for some // cases (e.g. compile with -nostdlib) Hence set OS to Linux - arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); + arch_spec.GetTriple().setOS(llvm::Triple::OSType::Linux); } } @@ -1494,7 +1501,7 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, const uint32_t sub_type = subTypeFromElfHeader(header); arch_spec.SetArchitecture(eArchTypeELF, header.e_machine, sub_type, header.e_ident[EI_OSABI]); - + // Validate if it is ok to remove GetOsFromOSABI. Note, that now the OS is // determined based on EI_OSABI flag and the info extracted from ELF notes // (see RefineModuleDetailsFromNote). However in some cases that still @@ -1553,7 +1560,7 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, uint32_t idx; lldb::offset_t offset; for (idx = 0, offset = 0; idx < header.e_shnum; ++idx) { - if (section_headers[idx].Parse(sh_data, &offset) == false) + if (!section_headers[idx].Parse(sh_data, &offset)) break; } if (idx < section_headers.size()) @@ -1701,27 +1708,6 @@ size_t ObjectFileELF::GetSectionHeaderInfo(SectionHeaderColl §ion_headers, return 0; } -size_t ObjectFileELF::GetProgramHeaderCount() { return ParseProgramHeaders(); } - -const elf::ELFProgramHeader * -ObjectFileELF::GetProgramHeaderByIndex(lldb::user_id_t id) { - if (!id || !ParseProgramHeaders()) - return NULL; - - if (--id < m_program_headers.size()) - return &m_program_headers[id]; - - return NULL; -} - -DataExtractor ObjectFileELF::GetSegmentDataByIndex(lldb::user_id_t id) { - const elf::ELFProgramHeader *segment_header = GetProgramHeaderByIndex(id); - if (segment_header == NULL) - return DataExtractor(); - return DataExtractor(m_data, segment_header->p_offset, - segment_header->p_filesz); -} - llvm::StringRef ObjectFileELF::StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const { size_t pos = symbol_name.find('@'); @@ -1739,10 +1725,10 @@ size_t ObjectFileELF::ParseSectionHeaders() { const ObjectFileELF::ELFSectionHeaderInfo * ObjectFileELF::GetSectionHeaderByIndex(lldb::user_id_t id) { - if (!id || !ParseSectionHeaders()) + if (!ParseSectionHeaders()) return NULL; - if (--id < m_section_headers.size()) + if (id < m_section_headers.size()) return &m_section_headers[id]; return NULL; @@ -1757,233 +1743,273 @@ lldb::user_id_t ObjectFileELF::GetSectionIndexByName(const char *name) { return 0; } -void ObjectFileELF::CreateSections(SectionList &unified_section_list) { - if (!m_sections_ap.get() && ParseSectionHeaders()) { - m_sections_ap.reset(new SectionList()); +static SectionType GetSectionTypeFromName(llvm::StringRef Name) { + return llvm::StringSwitch(Name) + .Case(".ARM.exidx", eSectionTypeARMexidx) + .Case(".ARM.extab", eSectionTypeARMextab) + .Cases(".bss", ".tbss", eSectionTypeZeroFill) + .Cases(".data", ".tdata", eSectionTypeData) + .Case(".debug_abbrev", eSectionTypeDWARFDebugAbbrev) + .Case(".debug_abbrev.dwo", eSectionTypeDWARFDebugAbbrevDwo) + .Case(".debug_addr", eSectionTypeDWARFDebugAddr) + .Case(".debug_aranges", eSectionTypeDWARFDebugAranges) + .Case(".debug_cu_index", eSectionTypeDWARFDebugCuIndex) + .Case(".debug_frame", eSectionTypeDWARFDebugFrame) + .Case(".debug_info", eSectionTypeDWARFDebugInfo) + .Case(".debug_info.dwo", eSectionTypeDWARFDebugInfoDwo) + .Cases(".debug_line", ".debug_line.dwo", eSectionTypeDWARFDebugLine) + .Cases(".debug_line_str", ".debug_line_str.dwo", + eSectionTypeDWARFDebugLineStr) + .Cases(".debug_loc", ".debug_loc.dwo", eSectionTypeDWARFDebugLoc) + .Cases(".debug_loclists", ".debug_loclists.dwo", + eSectionTypeDWARFDebugLocLists) + .Case(".debug_macinfo", eSectionTypeDWARFDebugMacInfo) + .Cases(".debug_macro", ".debug_macro.dwo", eSectionTypeDWARFDebugMacro) + .Case(".debug_names", eSectionTypeDWARFDebugNames) + .Case(".debug_pubnames", eSectionTypeDWARFDebugPubNames) + .Case(".debug_pubtypes", eSectionTypeDWARFDebugPubTypes) + .Case(".debug_ranges", eSectionTypeDWARFDebugRanges) + .Case(".debug_rnglists", eSectionTypeDWARFDebugRngLists) + .Case(".debug_str", eSectionTypeDWARFDebugStr) + .Case(".debug_str.dwo", eSectionTypeDWARFDebugStrDwo) + .Case(".debug_str_offsets", eSectionTypeDWARFDebugStrOffsets) + .Case(".debug_str_offsets.dwo", eSectionTypeDWARFDebugStrOffsetsDwo) + .Case(".debug_types", eSectionTypeDWARFDebugTypes) + .Case(".eh_frame", eSectionTypeEHFrame) + .Case(".gnu_debugaltlink", eSectionTypeDWARFGNUDebugAltLink) + .Case(".gosymtab", eSectionTypeGoSymtab) + .Case(".text", eSectionTypeCode) + .Default(eSectionTypeOther); +} - // Object files frequently have 0 for every section address, meaning we - // need to compute synthetic addresses in order for "file addresses" from - // different sections to not overlap - bool synthaddrs = (CalculateType() == ObjectFile::Type::eTypeObjectFile); - uint64_t nextaddr = 0; +SectionType ObjectFileELF::GetSectionType(const ELFSectionHeaderInfo &H) const { + switch (H.sh_type) { + case SHT_PROGBITS: + if (H.sh_flags & SHF_EXECINSTR) + return eSectionTypeCode; + break; + case SHT_SYMTAB: + return eSectionTypeELFSymbolTable; + case SHT_DYNSYM: + return eSectionTypeELFDynamicSymbols; + case SHT_RELA: + case SHT_REL: + return eSectionTypeELFRelocationEntries; + case SHT_DYNAMIC: + return eSectionTypeELFDynamicLinkInfo; + } + SectionType Type = GetSectionTypeFromName(H.section_name.GetStringRef()); + if (Type == eSectionTypeOther) { + // the kalimba toolchain assumes that ELF section names are free-form. + // It does support linkscripts which (can) give rise to various + // arbitrarily named sections being "Code" or "Data". + Type = kalimbaSectionType(m_header, H); + } + return Type; +} - for (SectionHeaderCollIter I = m_section_headers.begin(); - I != m_section_headers.end(); ++I) { - const ELFSectionHeaderInfo &header = *I; +static uint32_t GetTargetByteSize(SectionType Type, const ArchSpec &arch) { + switch (Type) { + case eSectionTypeData: + case eSectionTypeZeroFill: + return arch.GetDataByteSize(); + case eSectionTypeCode: + return arch.GetCodeByteSize(); + default: + return 1; + } +} - ConstString &name = I->section_name; - const uint64_t file_size = - header.sh_type == SHT_NOBITS ? 0 : header.sh_size; - const uint64_t vm_size = header.sh_flags & SHF_ALLOC ? header.sh_size : 0; +static Permissions GetPermissions(const ELFSectionHeader &H) { + Permissions Perm = Permissions(0); + if (H.sh_flags & SHF_ALLOC) + Perm |= ePermissionsReadable; + if (H.sh_flags & SHF_WRITE) + Perm |= ePermissionsWritable; + if (H.sh_flags & SHF_EXECINSTR) + Perm |= ePermissionsExecutable; + return Perm; +} - static ConstString g_sect_name_text(".text"); - static ConstString g_sect_name_data(".data"); - static ConstString g_sect_name_bss(".bss"); - static ConstString g_sect_name_tdata(".tdata"); - static ConstString g_sect_name_tbss(".tbss"); - static ConstString g_sect_name_dwarf_debug_abbrev(".debug_abbrev"); - static ConstString g_sect_name_dwarf_debug_addr(".debug_addr"); - static ConstString g_sect_name_dwarf_debug_aranges(".debug_aranges"); - static ConstString g_sect_name_dwarf_debug_cu_index(".debug_cu_index"); - static ConstString g_sect_name_dwarf_debug_frame(".debug_frame"); - static ConstString g_sect_name_dwarf_debug_info(".debug_info"); - static ConstString g_sect_name_dwarf_debug_line(".debug_line"); - static ConstString g_sect_name_dwarf_debug_loc(".debug_loc"); - static ConstString g_sect_name_dwarf_debug_macinfo(".debug_macinfo"); - static ConstString g_sect_name_dwarf_debug_macro(".debug_macro"); - static ConstString g_sect_name_dwarf_debug_names(".debug_names"); - static ConstString g_sect_name_dwarf_debug_pubnames(".debug_pubnames"); - static ConstString g_sect_name_dwarf_debug_pubtypes(".debug_pubtypes"); - static ConstString g_sect_name_dwarf_debug_ranges(".debug_ranges"); - static ConstString g_sect_name_dwarf_debug_str(".debug_str"); - static ConstString g_sect_name_dwarf_debug_str_offsets( - ".debug_str_offsets"); - static ConstString g_sect_name_dwarf_debug_abbrev_dwo( - ".debug_abbrev.dwo"); - static ConstString g_sect_name_dwarf_debug_info_dwo(".debug_info.dwo"); - static ConstString g_sect_name_dwarf_debug_line_dwo(".debug_line.dwo"); - static ConstString g_sect_name_dwarf_debug_macro_dwo(".debug_macro.dwo"); - static ConstString g_sect_name_dwarf_debug_loc_dwo(".debug_loc.dwo"); - static ConstString g_sect_name_dwarf_debug_str_dwo(".debug_str.dwo"); - static ConstString g_sect_name_dwarf_debug_str_offsets_dwo( - ".debug_str_offsets.dwo"); - static ConstString g_sect_name_dwarf_debug_types(".debug_types"); - static ConstString g_sect_name_eh_frame(".eh_frame"); - static ConstString g_sect_name_arm_exidx(".ARM.exidx"); - static ConstString g_sect_name_arm_extab(".ARM.extab"); - static ConstString g_sect_name_go_symtab(".gosymtab"); - static ConstString g_sect_name_dwarf_gnu_debugaltlink(".gnu_debugaltlink"); +static Permissions GetPermissions(const ELFProgramHeader &H) { + Permissions Perm = Permissions(0); + if (H.p_flags & PF_R) + Perm |= ePermissionsReadable; + if (H.p_flags & PF_W) + Perm |= ePermissionsWritable; + if (H.p_flags & PF_X) + Perm |= ePermissionsExecutable; + return Perm; +} - SectionType sect_type = eSectionTypeOther; +namespace { - bool is_thread_specific = false; +using VMRange = lldb_private::Range; - if (name == g_sect_name_text) - sect_type = eSectionTypeCode; - else if (name == g_sect_name_data) - sect_type = eSectionTypeData; - else if (name == g_sect_name_bss) - sect_type = eSectionTypeZeroFill; - else if (name == g_sect_name_tdata) { - sect_type = eSectionTypeData; - is_thread_specific = true; - } else if (name == g_sect_name_tbss) { - sect_type = eSectionTypeZeroFill; - is_thread_specific = true; - } - // .debug_abbrev – Abbreviations used in the .debug_info section - // .debug_aranges – Lookup table for mapping addresses to compilation - // units .debug_frame – Call frame information .debug_info – The core - // DWARF information section .debug_line – Line number information - // .debug_loc – Location lists used in DW_AT_location attributes - // .debug_macinfo – Macro information .debug_pubnames – Lookup table - // for mapping object and function names to compilation units - // .debug_pubtypes – Lookup table for mapping type names to compilation - // units .debug_ranges – Address ranges used in DW_AT_ranges attributes - // .debug_str – String table used in .debug_info MISSING? - // .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, - // http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html MISSING? - // .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build - // /gdb-add-index?pathrev=144644 MISSING? .debug_types - Type - // descriptions from DWARF 4? See - // http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo - else if (name == g_sect_name_dwarf_debug_abbrev) - sect_type = eSectionTypeDWARFDebugAbbrev; - else if (name == g_sect_name_dwarf_debug_addr) - sect_type = eSectionTypeDWARFDebugAddr; - else if (name == g_sect_name_dwarf_debug_aranges) - sect_type = eSectionTypeDWARFDebugAranges; - else if (name == g_sect_name_dwarf_debug_cu_index) - sect_type = eSectionTypeDWARFDebugCuIndex; - else if (name == g_sect_name_dwarf_debug_frame) - sect_type = eSectionTypeDWARFDebugFrame; - else if (name == g_sect_name_dwarf_debug_info) - sect_type = eSectionTypeDWARFDebugInfo; - else if (name == g_sect_name_dwarf_debug_line) - sect_type = eSectionTypeDWARFDebugLine; - else if (name == g_sect_name_dwarf_debug_loc) - sect_type = eSectionTypeDWARFDebugLoc; - else if (name == g_sect_name_dwarf_debug_macinfo) - sect_type = eSectionTypeDWARFDebugMacInfo; - else if (name == g_sect_name_dwarf_debug_macro) - sect_type = eSectionTypeDWARFDebugMacro; - else if (name == g_sect_name_dwarf_debug_names) - sect_type = eSectionTypeDWARFDebugNames; - else if (name == g_sect_name_dwarf_debug_pubnames) - sect_type = eSectionTypeDWARFDebugPubNames; - else if (name == g_sect_name_dwarf_debug_pubtypes) - sect_type = eSectionTypeDWARFDebugPubTypes; - else if (name == g_sect_name_dwarf_debug_ranges) - sect_type = eSectionTypeDWARFDebugRanges; - else if (name == g_sect_name_dwarf_debug_str) - sect_type = eSectionTypeDWARFDebugStr; - else if (name == g_sect_name_dwarf_debug_types) - sect_type = eSectionTypeDWARFDebugTypes; - else if (name == g_sect_name_dwarf_debug_str_offsets) - sect_type = eSectionTypeDWARFDebugStrOffsets; - else if (name == g_sect_name_dwarf_debug_abbrev_dwo) - sect_type = eSectionTypeDWARFDebugAbbrev; - else if (name == g_sect_name_dwarf_debug_info_dwo) - sect_type = eSectionTypeDWARFDebugInfo; - else if (name == g_sect_name_dwarf_debug_line_dwo) - sect_type = eSectionTypeDWARFDebugLine; - else if (name == g_sect_name_dwarf_debug_macro_dwo) - sect_type = eSectionTypeDWARFDebugMacro; - else if (name == g_sect_name_dwarf_debug_loc_dwo) - sect_type = eSectionTypeDWARFDebugLoc; - else if (name == g_sect_name_dwarf_debug_str_dwo) - sect_type = eSectionTypeDWARFDebugStr; - else if (name == g_sect_name_dwarf_debug_str_offsets_dwo) - sect_type = eSectionTypeDWARFDebugStrOffsets; - else if (name == g_sect_name_eh_frame) - sect_type = eSectionTypeEHFrame; - else if (name == g_sect_name_arm_exidx) - sect_type = eSectionTypeARMexidx; - else if (name == g_sect_name_arm_extab) - sect_type = eSectionTypeARMextab; - else if (name == g_sect_name_go_symtab) - sect_type = eSectionTypeGoSymtab; - else if (name == g_sect_name_dwarf_gnu_debugaltlink) - sect_type = eSectionTypeDWARFGNUDebugAltLink; +struct SectionAddressInfo { + SectionSP Segment; + VMRange Range; +}; - const uint32_t permissions = - ((header.sh_flags & SHF_ALLOC) ? ePermissionsReadable : 0u) | - ((header.sh_flags & SHF_WRITE) ? ePermissionsWritable : 0u) | - ((header.sh_flags & SHF_EXECINSTR) ? ePermissionsExecutable : 0u); - switch (header.sh_type) { - case SHT_SYMTAB: - assert(sect_type == eSectionTypeOther); - sect_type = eSectionTypeELFSymbolTable; - break; - case SHT_DYNSYM: - assert(sect_type == eSectionTypeOther); - sect_type = eSectionTypeELFDynamicSymbols; - break; - case SHT_RELA: - case SHT_REL: - assert(sect_type == eSectionTypeOther); - sect_type = eSectionTypeELFRelocationEntries; - break; - case SHT_DYNAMIC: - assert(sect_type == eSectionTypeOther); - sect_type = eSectionTypeELFDynamicLinkInfo; - break; - } +// (Unlinked) ELF object files usually have 0 for every section address, meaning +// we need to compute synthetic addresses in order for "file addresses" from +// different sections to not overlap. This class handles that logic. +class VMAddressProvider { + using VMMap = llvm::IntervalMap>; - if (eSectionTypeOther == sect_type) { - // the kalimba toolchain assumes that ELF section names are free-form. - // It does support linkscripts which (can) give rise to various - // arbitrarily named sections being "Code" or "Data". - sect_type = kalimbaSectionType(m_header, header); - } + ObjectFile::Type ObjectType; + addr_t NextVMAddress = 0; + VMMap::Allocator Alloc; + VMMap Segments = VMMap(Alloc); + VMMap Sections = VMMap(Alloc); + lldb_private::Log *Log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); - // In common case ELF code section can have arbitrary name (for example, - // we can specify it using section attribute for particular function) so - // assume that section is a code section if it has SHF_EXECINSTR flag set - // and has SHT_PROGBITS type. - if (eSectionTypeOther == sect_type && - llvm::ELF::SHT_PROGBITS == header.sh_type && - (header.sh_flags & SHF_EXECINSTR)) { - sect_type = eSectionTypeCode; - } - - const uint32_t target_bytes_size = - (eSectionTypeData == sect_type || eSectionTypeZeroFill == sect_type) - ? m_arch_spec.GetDataByteSize() - : eSectionTypeCode == sect_type ? m_arch_spec.GetCodeByteSize() - : 1; - elf::elf_xword log2align = - (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign); - - uint64_t addr = header.sh_addr; - - if ((header.sh_flags & SHF_ALLOC) && synthaddrs) { - nextaddr = - (nextaddr + header.sh_addralign - 1) & ~(header.sh_addralign - 1); - addr = nextaddr; - nextaddr += vm_size; - } - - SectionSP section_sp(new Section( - GetModule(), // Module to which this section belongs. - this, // ObjectFile to which this section belongs and should read - // section data from. - SectionIndex(I), // Section ID. - name, // Section name. - sect_type, // Section type. - addr, // VM address. - vm_size, // VM size in bytes of this section. - header.sh_offset, // Offset of this section in the file. - file_size, // Size of the section as found in the file. - log2align, // Alignment of the section - header.sh_flags, // Flags for this section. - target_bytes_size)); // Number of host bytes per target byte - - section_sp->SetPermissions(permissions); - if (is_thread_specific) - section_sp->SetIsThreadSpecific(is_thread_specific); - m_sections_ap->AddSection(section_sp); + VMRange GetVMRange(const ELFSectionHeader &H) { + addr_t Address = H.sh_addr; + addr_t Size = H.sh_flags & SHF_ALLOC ? H.sh_size : 0; + if (ObjectType == ObjectFile::Type::eTypeObjectFile && Segments.empty() && (H.sh_flags & SHF_ALLOC)) { + NextVMAddress = + llvm::alignTo(NextVMAddress, std::max(H.sh_addralign, 1)); + Address = NextVMAddress; + NextVMAddress += Size; } + return VMRange(Address, Size); + } + +public: + VMAddressProvider(ObjectFile::Type Type) : ObjectType(Type) {} + + llvm::Optional GetAddressInfo(const ELFProgramHeader &H) { + if (H.p_memsz == 0) { + LLDB_LOG(Log, + "Ignoring zero-sized PT_LOAD segment. Corrupt object file?"); + return llvm::None; + } + + if (Segments.overlaps(H.p_vaddr, H.p_vaddr + H.p_memsz)) { + LLDB_LOG(Log, + "Ignoring overlapping PT_LOAD segment. Corrupt object file?"); + return llvm::None; + } + return VMRange(H.p_vaddr, H.p_memsz); + } + + llvm::Optional GetAddressInfo(const ELFSectionHeader &H) { + VMRange Range = GetVMRange(H); + SectionSP Segment; + auto It = Segments.find(Range.GetRangeBase()); + if ((H.sh_flags & SHF_ALLOC) && It.valid()) { + addr_t MaxSize; + if (It.start() <= Range.GetRangeBase()) { + MaxSize = It.stop() - Range.GetRangeBase(); + Segment = *It; + } else + MaxSize = It.start() - Range.GetRangeBase(); + if (Range.GetByteSize() > MaxSize) { + LLDB_LOG(Log, "Shortening section crossing segment boundaries. " + "Corrupt object file?"); + Range.SetByteSize(MaxSize); + } + } + if (Range.GetByteSize() > 0 && + Sections.overlaps(Range.GetRangeBase(), Range.GetRangeEnd())) { + LLDB_LOG(Log, "Ignoring overlapping section. Corrupt object file?"); + return llvm::None; + } + if (Segment) + Range.Slide(-Segment->GetFileAddress()); + return SectionAddressInfo{Segment, Range}; + } + + void AddSegment(const VMRange &Range, SectionSP Seg) { + Segments.insert(Range.GetRangeBase(), Range.GetRangeEnd(), std::move(Seg)); + } + + void AddSection(SectionAddressInfo Info, SectionSP Sect) { + if (Info.Range.GetByteSize() == 0) + return; + if (Info.Segment) + Info.Range.Slide(Info.Segment->GetFileAddress()); + Sections.insert(Info.Range.GetRangeBase(), Info.Range.GetRangeEnd(), + std::move(Sect)); + } +}; +} + +void ObjectFileELF::CreateSections(SectionList &unified_section_list) { + if (m_sections_ap) + return; + + m_sections_ap = llvm::make_unique(); + VMAddressProvider address_provider(CalculateType()); + + size_t LoadID = 0; + for (const auto &EnumPHdr : llvm::enumerate(ProgramHeaders())) { + const ELFProgramHeader &PHdr = EnumPHdr.value(); + if (PHdr.p_type != PT_LOAD) + continue; + + auto InfoOr = address_provider.GetAddressInfo(PHdr); + if (!InfoOr) + continue; + + ConstString Name(("PT_LOAD[" + llvm::Twine(LoadID++) + "]").str()); + uint32_t Log2Align = llvm::Log2_64(std::max(PHdr.p_align, 1)); + SectionSP Segment = std::make_shared
( + GetModule(), this, SegmentID(EnumPHdr.index()), Name, + eSectionTypeContainer, InfoOr->GetRangeBase(), InfoOr->GetByteSize(), + PHdr.p_offset, PHdr.p_filesz, Log2Align, /*flags*/ 0); + Segment->SetPermissions(GetPermissions(PHdr)); + m_sections_ap->AddSection(Segment); + + address_provider.AddSegment(*InfoOr, std::move(Segment)); + } + + ParseSectionHeaders(); + if (m_section_headers.empty()) + return; + + for (SectionHeaderCollIter I = std::next(m_section_headers.begin()); + I != m_section_headers.end(); ++I) { + const ELFSectionHeaderInfo &header = *I; + + ConstString &name = I->section_name; + const uint64_t file_size = + header.sh_type == SHT_NOBITS ? 0 : header.sh_size; + + auto InfoOr = address_provider.GetAddressInfo(header); + if (!InfoOr) + continue; + + SectionType sect_type = GetSectionType(header); + + const uint32_t target_bytes_size = + GetTargetByteSize(sect_type, m_arch_spec); + + elf::elf_xword log2align = + (header.sh_addralign == 0) ? 0 : llvm::Log2_64(header.sh_addralign); + + SectionSP section_sp(new Section( + InfoOr->Segment, GetModule(), // Module to which this section belongs. + this, // ObjectFile to which this section belongs and should + // read section data from. + SectionIndex(I), // Section ID. + name, // Section name. + sect_type, // Section type. + InfoOr->Range.GetRangeBase(), // VM address. + InfoOr->Range.GetByteSize(), // VM size in bytes of this section. + header.sh_offset, // Offset of this section in the file. + file_size, // Size of the section as found in the file. + log2align, // Alignment of the section + header.sh_flags, // Flags for this section. + target_bytes_size)); // Number of host bytes per target byte + + section_sp->SetPermissions(GetPermissions(header)); + section_sp->SetIsThreadSpecific(header.sh_flags & SHF_TLS); + (InfoOr->Segment ? InfoOr->Segment->GetChildren() : *m_sections_ap) + .AddSection(section_sp); + address_provider.AddSection(std::move(*InfoOr), std::move(section_sp)); } // For eTypeDebugInfo files, the Symbol Vendor will take care of updating the @@ -2050,8 +2076,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, bool skip_oatdata_oatexec = file_extension == ConstString(".oat") || file_extension == ConstString(".odex"); - ArchSpec arch; - GetArchitecture(arch); + ArchSpec arch = GetArchitecture(); ModuleSP module_sp(GetModule()); SectionList *module_section_list = module_sp ? module_sp->GetSectionList() : nullptr; @@ -2063,7 +2088,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, unsigned i; for (i = 0; i < num_symbols; ++i) { - if (symbol.Parse(symtab_data, &offset) == false) + if (!symbol.Parse(symtab_data, &offset)) break; const char *symbol_name = strtab_data.PeekCStr(symbol.st_name); @@ -2083,9 +2108,9 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, SectionSP symbol_section_sp; SymbolType symbol_type = eSymbolTypeInvalid; - Elf64_Half section_idx = symbol.st_shndx; + Elf64_Half shndx = symbol.st_shndx; - switch (section_idx) { + switch (shndx) { case SHN_ABS: symbol_type = eSymbolTypeAbsolute; break; @@ -2093,7 +2118,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, symbol_type = eSymbolTypeUndefined; break; default: - symbol_section_sp = section_list->GetSectionAtIndex(section_idx); + symbol_section_sp = section_list->FindSectionByID(shndx); break; } @@ -2262,7 +2287,7 @@ unsigned ObjectFileELF::ParseSymbols(Symtab *symtab, user_id_t start_id, // symbols. See above for more details. uint64_t symbol_value = symbol.st_value + symbol_value_offset; - if (symbol_section_sp == nullptr && section_idx == SHN_ABS && + if (symbol_section_sp == nullptr && shndx == SHN_ABS && symbol.st_size != 0) { // We don't have a section for a symbol with non-zero size. Create a new // section for it so the address range covered by the symbol is also @@ -2375,9 +2400,8 @@ unsigned ObjectFileELF::ParseSymbolTable(Symtab *symbol_table, assert(symtab_hdr->sh_type == SHT_SYMTAB || symtab_hdr->sh_type == SHT_DYNSYM); - // sh_link: section header index of associated string table. Section ID's are - // ones based. - user_id_t strtab_id = symtab_hdr->sh_link + 1; + // sh_link: section header index of associated string table. + user_id_t strtab_id = symtab_hdr->sh_link; Section *strtab = section_list->FindSectionByID(strtab_id).get(); if (symtab && strtab) { @@ -2529,7 +2553,7 @@ static unsigned ParsePLTRelocations( unsigned slot_type = hdr->GetRelocationJumpSlotType(); unsigned i; for (i = 0; i < num_relocations; ++i) { - if (rel.Parse(rel_data, &offset) == false) + if (!rel.Parse(rel_data, &offset)) break; if (reloc_type(rel) != slot_type) @@ -2587,10 +2611,6 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id, if (!symtab_id || !plt_id) return 0; - // Section ID's are ones based; - symtab_id++; - plt_id++; - const ELFSectionHeaderInfo *plt_hdr = GetSectionHeaderByIndex(plt_id); if (!plt_hdr) return 0; @@ -2616,7 +2636,7 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id, return 0; // sh_link points to associated string table. - Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link + 1).get(); + Section *strtab = section_list->FindSectionByID(sym_hdr->sh_link).get(); if (!strtab) return 0; @@ -2662,7 +2682,7 @@ unsigned ObjectFileELF::ApplyRelocations( } for (unsigned i = 0; i < num_relocations; ++i) { - if (rel.Parse(rel_data, &offset) == false) + if (!rel.Parse(rel_data, &offset)) break; Symbol *symbol = NULL; @@ -2684,6 +2704,7 @@ unsigned ObjectFileELF::ApplyRelocations( } } else { switch (reloc_type(rel)) { + case R_AARCH64_ABS64: case R_X86_64_64: { symbol = symtab->FindSymbolByID(reloc_symbol(rel)); if (symbol) { @@ -2692,26 +2713,34 @@ unsigned ObjectFileELF::ApplyRelocations( uint64_t *dst = reinterpret_cast( data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset64(rel)); - *dst = value + ELFRelocation::RelocAddend64(rel); + uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); + memcpy(dst, &val_offset, sizeof(uint64_t)); } break; } case R_X86_64_32: - case R_X86_64_32S: { + case R_X86_64_32S: + case R_AARCH64_ABS32: { symbol = symtab->FindSymbolByID(reloc_symbol(rel)); if (symbol) { addr_t value = symbol->GetAddressRef().GetFileAddress(); value += ELFRelocation::RelocAddend32(rel); - assert( - (reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) || + if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) || (reloc_type(rel) == R_X86_64_32S && - ((int64_t)value <= INT32_MAX && (int64_t)value >= INT32_MIN))); + ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) || + (reloc_type(rel) == R_AARCH64_ABS32 && + ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) { + Log *log = + lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); + log->Printf("Failed to apply debug info relocations"); + break; + } uint32_t truncated_addr = (value & 0xFFFFFFFF); DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); uint32_t *dst = reinterpret_cast( data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset32(rel)); - *dst = truncated_addr; + memcpy(dst, &truncated_addr, sizeof(uint32_t)); } break; } @@ -2735,9 +2764,8 @@ unsigned ObjectFileELF::RelocateDebugSections(const ELFSectionHeader *rel_hdr, if (!section_list) return 0; - // Section ID's are ones based. - user_id_t symtab_id = rel_hdr->sh_link + 1; - user_id_t debug_id = rel_hdr->sh_info + 1; + user_id_t symtab_id = rel_hdr->sh_link; + user_id_t debug_id = rel_hdr->sh_info; const ELFSectionHeader *symtab_hdr = GetSectionHeaderByIndex(symtab_id); if (!symtab_hdr) @@ -2975,8 +3003,7 @@ void ObjectFileELF::Dump(Stream *s) { s->Indent(); s->PutCString("ObjectFileELF"); - ArchSpec header_arch; - GetArchitecture(header_arch); + ArchSpec header_arch = GetArchitecture(); *s << ", file = '" << m_file << "', arch = " << header_arch.GetArchitectureName() << "\n"; @@ -3153,11 +3180,9 @@ void ObjectFileELF::DumpELFProgramHeaders(Stream *s) { s->PutCString("==== --------------- -------- -------- -------- " "-------- -------- ------------------------- --------\n"); - uint32_t idx = 0; - for (ProgramHeaderCollConstIter I = m_program_headers.begin(); - I != m_program_headers.end(); ++I, ++idx) { - s->Printf("[%2u] ", idx); - ObjectFileELF::DumpELFProgramHeader(s, *I); + for (const auto &H : llvm::enumerate(m_program_headers)) { + s->Format("[{0,2}] ", H.index()); + ObjectFileELF::DumpELFProgramHeader(s, H.value()); s->EOL(); } } @@ -3264,9 +3289,9 @@ void ObjectFileELF::DumpDependentModules(lldb_private::Stream *s) { } } -bool ObjectFileELF::GetArchitecture(ArchSpec &arch) { +ArchSpec ObjectFileELF::GetArchitecture() { if (!ParseHeader()) - return false; + return ArchSpec(); if (m_section_headers.empty()) { // Allow elf notes to be parsed which may affect the detected architecture. @@ -3277,23 +3302,17 @@ bool ObjectFileELF::GetArchitecture(ArchSpec &arch) { m_arch_spec.TripleOSIsUnspecifiedUnknown()) { // Core files don't have section headers yet they have PT_NOTE program // headers that might shed more light on the architecture - if (ParseProgramHeaders()) { - for (size_t i = 1, count = GetProgramHeaderCount(); i <= count; ++i) { - const elf::ELFProgramHeader *header = GetProgramHeaderByIndex(i); - if (header && header->p_type == PT_NOTE && header->p_offset != 0 && - header->p_filesz > 0) { - DataExtractor data; - if (data.SetData(m_data, header->p_offset, header->p_filesz) == - header->p_filesz) { - lldb_private::UUID uuid; - RefineModuleDetailsFromNote(data, m_arch_spec, uuid); - } - } + for (const elf::ELFProgramHeader &H : ProgramHeaders()) { + if (H.p_type != PT_NOTE || H.p_offset == 0 || H.p_filesz == 0) + continue; + DataExtractor data; + if (data.SetData(m_data, H.p_offset, H.p_filesz) == H.p_filesz) { + UUID uuid; + RefineModuleDetailsFromNote(data, m_arch_spec, uuid); } } } - arch = m_arch_spec; - return true; + return m_arch_spec; } ObjectFile::Type ObjectFileELF::CalculateType() { @@ -3385,8 +3404,6 @@ size_t ObjectFileELF::ReadSectionData(Section *section, if (section->GetObjectFile() != this) return section->GetObjectFile()->ReadSectionData(section, section_data); - Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); - size_t result = ObjectFile::ReadSectionData(section, section_data); if (result == 0 || !section->Test(SHF_COMPRESSED)) return result; @@ -3397,29 +3414,43 @@ size_t ObjectFileELF::ReadSectionData(Section *section, size_t(section_data.GetByteSize())}, GetByteOrder() == eByteOrderLittle, GetAddressByteSize() == 8); if (!Decompressor) { - LLDB_LOG_ERROR(log, Decompressor.takeError(), - "Unable to initialize decompressor for section {0}", - section->GetName()); - return result; + GetModule()->ReportWarning( + "Unable to initialize decompressor for section '%s': %s", + section->GetName().GetCString(), + llvm::toString(Decompressor.takeError()).c_str()); + section_data.Clear(); + return 0; } + auto buffer_sp = std::make_shared(Decompressor->getDecompressedSize(), 0); - if (auto Error = Decompressor->decompress( + if (auto error = Decompressor->decompress( {reinterpret_cast(buffer_sp->GetBytes()), size_t(buffer_sp->GetByteSize())})) { - LLDB_LOG_ERROR(log, std::move(Error), "Decompression of section {0} failed", - section->GetName()); - return result; + GetModule()->ReportWarning( + "Decompression of section '%s' failed: %s", + section->GetName().GetCString(), + llvm::toString(std::move(error)).c_str()); + section_data.Clear(); + return 0; } + section_data.SetData(buffer_sp); return buffer_sp->GetByteSize(); } +llvm::ArrayRef ObjectFileELF::ProgramHeaders() { + ParseProgramHeaders(); + return m_program_headers; +} + +DataExtractor ObjectFileELF::GetSegmentData(const ELFProgramHeader &H) { + return DataExtractor(m_data, H.p_offset, H.p_filesz); +} + bool ObjectFileELF::AnySegmentHasPhysicalAddress() { - size_t header_count = ParseProgramHeaders(); - for (size_t i = 1; i <= header_count; ++i) { - auto header = GetProgramHeaderByIndex(i); - if (header->p_paddr != 0) + for (const ELFProgramHeader &H : ProgramHeaders()) { + if (H.p_paddr != 0) return true; } return false; @@ -3430,19 +3461,17 @@ ObjectFileELF::GetLoadableData(Target &target) { // Create a list of loadable data from loadable segments, using physical // addresses if they aren't all null std::vector loadables; - size_t header_count = ParseProgramHeaders(); bool should_use_paddr = AnySegmentHasPhysicalAddress(); - for (size_t i = 1; i <= header_count; ++i) { + for (const ELFProgramHeader &H : ProgramHeaders()) { LoadableData loadable; - auto header = GetProgramHeaderByIndex(i); - if (header->p_type != llvm::ELF::PT_LOAD) + if (H.p_type != llvm::ELF::PT_LOAD) continue; - loadable.Dest = should_use_paddr ? header->p_paddr : header->p_vaddr; + loadable.Dest = should_use_paddr ? H.p_paddr : H.p_vaddr; if (loadable.Dest == LLDB_INVALID_ADDRESS) continue; - if (header->p_filesz == 0) + if (H.p_filesz == 0) continue; - auto segment_data = GetSegmentDataByIndex(i); + auto segment_data = GetSegmentData(H); loadable.Contents = llvm::ArrayRef(segment_data.GetDataStart(), segment_data.GetByteSize()); loadables.push_back(loadable); diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h index 2664595fd81d..08fd5bdc60a9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.h @@ -10,10 +10,8 @@ #ifndef liblldb_ObjectFileELF_h_ #define liblldb_ObjectFileELF_h_ -// C Includes #include -// C++ Includes #include #include "lldb/Symbol/ObjectFile.h" @@ -123,7 +121,7 @@ public: void Dump(lldb_private::Stream *s) override; - bool GetArchitecture(lldb_private::ArchSpec &arch) override; + lldb_private::ArchSpec GetArchitecture() override; bool GetUUID(lldb_private::UUID *uuid) override; @@ -136,6 +134,8 @@ public: lldb_private::Address GetEntryPointAddress() override; + lldb_private::Address GetBaseAddress() override; + ObjectFile::Type CalculateType() override; ObjectFile::Strata CalculateStrata() override; @@ -147,14 +147,8 @@ public: size_t ReadSectionData(lldb_private::Section *section, lldb_private::DataExtractor §ion_data) override; - // Returns number of program headers found in the ELF file. - size_t GetProgramHeaderCount(); - - // Returns the program header with the given index. - const elf::ELFProgramHeader *GetProgramHeaderByIndex(lldb::user_id_t id); - - // Returns segment data for the given index. - lldb_private::DataExtractor GetSegmentDataByIndex(lldb::user_id_t id); + llvm::ArrayRef ProgramHeaders(); + lldb_private::DataExtractor GetSegmentData(const elf::ELFProgramHeader &H); llvm::StringRef StripLinkerSymbolAnnotations(llvm::StringRef symbol_name) const override; @@ -176,8 +170,6 @@ private: const lldb::ProcessSP &process_sp, lldb::addr_t header_addr); typedef std::vector ProgramHeaderColl; - typedef ProgramHeaderColl::iterator ProgramHeaderCollIter; - typedef ProgramHeaderColl::const_iterator ProgramHeaderCollConstIter; struct ELFSectionHeaderInfo : public elf::ELFSectionHeader { lldb_private::ConstString section_name; @@ -230,10 +222,10 @@ private: /// The address class for each symbol in the elf file FileAddressToAddressClassMap m_address_class_map; - /// Returns a 1 based index of the given section header. + /// Returns the index of the given section header. size_t SectionIndex(const SectionHeaderCollIter &I); - /// Returns a 1 based index of the given section header. + /// Returns the index of the given section header. size_t SectionIndex(const SectionHeaderCollConstIter &I) const; // Parses the ELF program headers. @@ -248,14 +240,16 @@ private: /// Parses all section headers present in this object file and populates /// m_program_headers. This method will compute the header list only once. - /// Returns the number of headers parsed. - size_t ParseProgramHeaders(); + /// Returns true iff the headers have been successfully parsed. + bool ParseProgramHeaders(); /// Parses all section headers present in this object file and populates /// m_section_headers. This method will compute the header list only once. /// Returns the number of headers parsed. size_t ParseSectionHeaders(); + lldb::SectionType GetSectionType(const ELFSectionHeaderInfo &H) const; + static void ParseARMAttributes(lldb_private::DataExtractor &data, uint64_t length, lldb_private::ArchSpec &arch_spec); diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp index af040322ec52..cfe61992be0d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.cpp @@ -153,8 +153,7 @@ void ObjectFileJIT::Dump(Stream *s) { s->Indent(); s->PutCString("ObjectFileJIT"); - ArchSpec arch; - if (GetArchitecture(arch)) + if (ArchSpec arch = GetArchitecture()) *s << ", arch = " << arch.GetArchitectureName(); s->EOL(); @@ -184,17 +183,16 @@ lldb_private::Address ObjectFileJIT::GetEntryPointAddress() { return Address(); } -lldb_private::Address ObjectFileJIT::GetHeaderAddress() { return Address(); } +lldb_private::Address ObjectFileJIT::GetBaseAddress() { return Address(); } ObjectFile::Type ObjectFileJIT::CalculateType() { return eTypeJIT; } ObjectFile::Strata ObjectFileJIT::CalculateStrata() { return eStrataJIT; } -bool ObjectFileJIT::GetArchitecture(ArchSpec &arch) { - ObjectFileJITDelegateSP delegate_sp(m_delegate_wp.lock()); - if (delegate_sp) - return delegate_sp->GetArchitecture(arch); - return false; +ArchSpec ObjectFileJIT::GetArchitecture() { + if (ObjectFileJITDelegateSP delegate_sp = m_delegate_wp.lock()) + return delegate_sp->GetArchitecture(); + return ArchSpec(); } //------------------------------------------------------------------ @@ -218,7 +216,7 @@ bool ObjectFileJIT::SetLoadAddress(Target &target, lldb::addr_t value, // that size on disk (to avoid __PAGEZERO) and load them SectionSP section_sp(section_list->GetSectionAtIndex(sect_idx)); if (section_sp && section_sp->GetFileSize() > 0 && - section_sp->IsThreadSpecific() == false) { + !section_sp->IsThreadSpecific()) { if (target.GetSectionLoadList().SetSectionLoadAddress( section_sp, section_sp->GetFileAddress() + value)) ++num_loaded_sections; diff --git a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h index c964906a5e8e..3d9e4748d3df 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ObjectFile/JIT/ObjectFileJIT.h @@ -10,10 +10,6 @@ #ifndef liblldb_ObjectFileJIT_h_ #define liblldb_ObjectFileJIT_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Address.h" #include "lldb/Symbol/ObjectFile.h" @@ -77,7 +73,7 @@ public: void Dump(lldb_private::Stream *s) override; - bool GetArchitecture(lldb_private::ArchSpec &arch) override; + lldb_private::ArchSpec GetArchitecture() override; bool GetUUID(lldb_private::UUID *uuid) override; @@ -93,7 +89,7 @@ public: lldb_private::Address GetEntryPointAddress() override; - lldb_private::Address GetHeaderAddress() override; + lldb_private::Address GetBaseAddress() override; ObjectFile::Type CalculateType() override; diff --git a/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp b/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp deleted file mode 100644 index 3f6083931513..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.cpp +++ /dev/null @@ -1,498 +0,0 @@ -//===-- OperatingSystemGo.cpp -----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -// Project includes -#include "OperatingSystemGo.h" - -#include "Plugins/Process/Utility/DynamicRegisterInfo.h" -#include "Plugins/Process/Utility/RegisterContextMemory.h" -#include "Plugins/Process/Utility/ThreadMemory.h" -#include "lldb/Core/Debugger.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Section.h" -#include "lldb/Core/ValueObjectVariable.h" -#include "lldb/Interpreter/CommandInterpreter.h" -#include "lldb/Interpreter/OptionGroupBoolean.h" -#include "lldb/Interpreter/OptionGroupUInt64.h" -#include "lldb/Interpreter/OptionValueProperties.h" -#include "lldb/Interpreter/Options.h" -#include "lldb/Interpreter/Property.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Symbol/VariableList.h" -#include "lldb/Target/Process.h" -#include "lldb/Target/StopInfo.h" -#include "lldb/Target/Target.h" -#include "lldb/Target/Thread.h" -#include "lldb/Target/ThreadList.h" -#include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/StreamString.h" - -using namespace lldb; -using namespace lldb_private; - -namespace { - -static PropertyDefinition g_properties[] = { - {"enable", OptionValue::eTypeBoolean, true, true, nullptr, nullptr, - "Specify whether goroutines should be treated as threads."}, - {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}}; - -enum { - ePropertyEnableGoroutines, -}; - -class PluginProperties : public Properties { -public: - PluginProperties() : Properties() { - m_collection_sp.reset(new OptionValueProperties(GetSettingName())); - m_collection_sp->Initialize(g_properties); - } - - ~PluginProperties() override = default; - - static ConstString GetSettingName() { - return OperatingSystemGo::GetPluginNameStatic(); - } - - bool GetEnableGoroutines() { - const uint32_t idx = ePropertyEnableGoroutines; - return m_collection_sp->GetPropertyAtIndexAsBoolean( - NULL, idx, g_properties[idx].default_uint_value); - } - - bool SetEnableGoroutines(bool enable) { - const uint32_t idx = ePropertyEnableGoroutines; - return m_collection_sp->SetPropertyAtIndexAsUInt64(NULL, idx, enable); - } -}; - -typedef std::shared_ptr OperatingSystemGoPropertiesSP; - -static const OperatingSystemGoPropertiesSP &GetGlobalPluginProperties() { - static OperatingSystemGoPropertiesSP g_settings_sp; - if (!g_settings_sp) - g_settings_sp.reset(new PluginProperties()); - return g_settings_sp; -} - -class RegisterContextGo : public RegisterContextMemory { -public: - RegisterContextGo(lldb_private::Thread &thread, uint32_t concrete_frame_idx, - DynamicRegisterInfo ®_info, lldb::addr_t reg_data_addr) - : RegisterContextMemory(thread, concrete_frame_idx, reg_info, - reg_data_addr) { - const RegisterInfo *sp = reg_info.GetRegisterInfoAtIndex( - reg_info.ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_SP)); - const RegisterInfo *pc = reg_info.GetRegisterInfoAtIndex( - reg_info.ConvertRegisterKindToRegisterNumber(eRegisterKindGeneric, - LLDB_REGNUM_GENERIC_PC)); - size_t byte_size = std::max(sp->byte_offset + sp->byte_size, - pc->byte_offset + pc->byte_size); - - DataBufferSP reg_data_sp(new DataBufferHeap(byte_size, 0)); - m_reg_data.SetData(reg_data_sp); - } - - ~RegisterContextGo() override = default; - - bool ReadRegister(const lldb_private::RegisterInfo *reg_info, - lldb_private::RegisterValue ®_value) override { - switch (reg_info->kinds[eRegisterKindGeneric]) { - case LLDB_REGNUM_GENERIC_SP: - case LLDB_REGNUM_GENERIC_PC: - return RegisterContextMemory::ReadRegister(reg_info, reg_value); - default: - reg_value.SetValueToInvalid(); - return true; - } - } - - bool WriteRegister(const lldb_private::RegisterInfo *reg_info, - const lldb_private::RegisterValue ®_value) override { - switch (reg_info->kinds[eRegisterKindGeneric]) { - case LLDB_REGNUM_GENERIC_SP: - case LLDB_REGNUM_GENERIC_PC: - return RegisterContextMemory::WriteRegister(reg_info, reg_value); - default: - return false; - } - } - -private: - DISALLOW_COPY_AND_ASSIGN(RegisterContextGo); -}; - -} // anonymous namespace - -struct OperatingSystemGo::Goroutine { - uint64_t m_lostack; - uint64_t m_histack; - uint64_t m_goid; - addr_t m_gobuf; - uint32_t m_status; -}; - -void OperatingSystemGo::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), CreateInstance, - DebuggerInitialize); -} - -void OperatingSystemGo::DebuggerInitialize(Debugger &debugger) { - if (!PluginManager::GetSettingForOperatingSystemPlugin( - debugger, PluginProperties::GetSettingName())) { - const bool is_global_setting = true; - PluginManager::CreateSettingForOperatingSystemPlugin( - debugger, GetGlobalPluginProperties()->GetValueProperties(), - ConstString("Properties for the goroutine thread plug-in."), - is_global_setting); - } -} - -void OperatingSystemGo::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -OperatingSystem *OperatingSystemGo::CreateInstance(Process *process, - bool force) { - if (!force) { - TargetSP target_sp = process->CalculateTarget(); - if (!target_sp) - return nullptr; - ModuleList &module_list = target_sp->GetImages(); - std::lock_guard guard(module_list.GetMutex()); - const size_t num_modules = module_list.GetSize(); - bool found_go_runtime = false; - for (size_t i = 0; i < num_modules; ++i) { - Module *module = module_list.GetModulePointerAtIndexUnlocked(i); - const SectionList *section_list = module->GetSectionList(); - if (section_list) { - SectionSP section_sp( - section_list->FindSectionByType(eSectionTypeGoSymtab, true)); - if (section_sp) { - found_go_runtime = true; - break; - } - } - } - if (!found_go_runtime) - return nullptr; - } - return new OperatingSystemGo(process); -} - -OperatingSystemGo::OperatingSystemGo(lldb_private::Process *process) - : OperatingSystem(process), m_reginfo(new DynamicRegisterInfo) {} - -OperatingSystemGo::~OperatingSystemGo() = default; - -ConstString OperatingSystemGo::GetPluginNameStatic() { - static ConstString g_name("goroutines"); - return g_name; -} - -const char *OperatingSystemGo::GetPluginDescriptionStatic() { - return "Operating system plug-in that reads runtime data-structures for " - "goroutines."; -} - -bool OperatingSystemGo::Init(ThreadList &threads) { - if (threads.GetSize(false) < 1) - return false; - TargetSP target_sp = m_process->CalculateTarget(); - if (!target_sp) - return false; - // Go 1.6 stores goroutines in a slice called runtime.allgs - ValueObjectSP allgs_sp = FindGlobal(target_sp, "runtime.allgs"); - if (allgs_sp) { - m_allg_sp = allgs_sp->GetChildMemberWithName(ConstString("array"), true); - m_allglen_sp = allgs_sp->GetChildMemberWithName(ConstString("len"), true); - } else { - // Go 1.4 stores goroutines in the variable runtime.allg. - m_allg_sp = FindGlobal(target_sp, "runtime.allg"); - m_allglen_sp = FindGlobal(target_sp, "runtime.allglen"); - } - - if (m_allg_sp && !m_allglen_sp) { - StreamSP error_sp = target_sp->GetDebugger().GetAsyncErrorStream(); - error_sp->Printf("Unsupported Go runtime version detected."); - return false; - } - - if (!m_allg_sp) - return false; - - RegisterContextSP real_registers_sp = - threads.GetThreadAtIndex(0, false)->GetRegisterContext(); - - std::unordered_map register_sets; - for (size_t set_idx = 0; set_idx < real_registers_sp->GetRegisterSetCount(); - ++set_idx) { - const RegisterSet *set = real_registers_sp->GetRegisterSet(set_idx); - ConstString name(set->name); - for (size_t reg_idx = 0; reg_idx < set->num_registers; ++reg_idx) { - register_sets[reg_idx] = name; - } - } - TypeSP gobuf_sp = FindType(target_sp, "runtime.gobuf"); - if (!gobuf_sp) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); - - if (log) - log->Printf("OperatingSystemGo unable to find struct Gobuf"); - return false; - } - CompilerType gobuf_type(gobuf_sp->GetLayoutCompilerType()); - for (size_t idx = 0; idx < real_registers_sp->GetRegisterCount(); ++idx) { - RegisterInfo reg = *real_registers_sp->GetRegisterInfoAtIndex(idx); - int field_index = -1; - if (reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_SP) { - field_index = 0; - } else if (reg.kinds[eRegisterKindGeneric] == LLDB_REGNUM_GENERIC_PC) { - field_index = 1; - } - if (field_index == -1) { - reg.byte_offset = ~0; - } else { - std::string field_name; - uint64_t bit_offset = 0; - CompilerType field_type = gobuf_type.GetFieldAtIndex( - field_index, field_name, &bit_offset, nullptr, nullptr); - reg.byte_size = field_type.GetByteSize(nullptr); - reg.byte_offset = bit_offset / 8; - } - ConstString name(reg.name); - ConstString alt_name(reg.alt_name); - m_reginfo->AddRegister(reg, name, alt_name, register_sets[idx]); - } - return true; -} - -//------------------------------------------------------------------ -// PluginInterface protocol -//------------------------------------------------------------------ -ConstString OperatingSystemGo::GetPluginName() { return GetPluginNameStatic(); } - -uint32_t OperatingSystemGo::GetPluginVersion() { return 1; } - -bool OperatingSystemGo::UpdateThreadList(ThreadList &old_thread_list, - ThreadList &real_thread_list, - ThreadList &new_thread_list) { - new_thread_list = real_thread_list; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); - - if (!(m_allg_sp || Init(real_thread_list)) || (m_allg_sp && !m_allglen_sp) || - !GetGlobalPluginProperties()->GetEnableGoroutines()) { - return new_thread_list.GetSize(false) > 0; - } - - if (log) - log->Printf("OperatingSystemGo::UpdateThreadList(%d, %d, %d) fetching " - "thread data from Go for pid %" PRIu64, - old_thread_list.GetSize(false), real_thread_list.GetSize(false), - new_thread_list.GetSize(0), m_process->GetID()); - uint64_t allglen = m_allglen_sp->GetValueAsUnsigned(0); - if (allglen == 0) { - return new_thread_list.GetSize(false) > 0; - } - std::vector goroutines; - // The threads that are in "new_thread_list" upon entry are the threads from - // the lldb_private::Process subclass, no memory threads will be in this - // list. - - Status err; - for (uint64_t i = 0; i < allglen; ++i) { - goroutines.push_back(CreateGoroutineAtIndex(i, err)); - if (err.Fail()) { - LLDB_LOG(log, "error: {0}", err); - return new_thread_list.GetSize(false) > 0; - } - } - // Make a map so we can match goroutines with backing threads. - std::map stack_map; - for (uint32_t i = 0; i < real_thread_list.GetSize(false); ++i) { - ThreadSP thread = real_thread_list.GetThreadAtIndex(i, false); - stack_map[thread->GetRegisterContext()->GetSP()] = thread; - } - for (const Goroutine &goroutine : goroutines) { - if (0 /* Gidle */ == goroutine.m_status || - 6 /* Gdead */ == goroutine.m_status) { - continue; - } - ThreadSP memory_thread = - old_thread_list.FindThreadByID(goroutine.m_goid, false); - if (memory_thread && IsOperatingSystemPluginThread(memory_thread) && - memory_thread->IsValid()) { - memory_thread->ClearBackingThread(); - } else { - memory_thread.reset(new ThreadMemory(*m_process, goroutine.m_goid, "", "", - goroutine.m_gobuf)); - } - // Search for the backing thread if the goroutine is running. - if (2 == (goroutine.m_status & 0xfff)) { - auto backing_it = stack_map.lower_bound(goroutine.m_lostack); - if (backing_it != stack_map.end()) { - if (goroutine.m_histack >= backing_it->first) { - if (log) - log->Printf( - "OperatingSystemGo::UpdateThreadList found backing thread " - "%" PRIx64 " (%" PRIx64 ") for thread %" PRIx64 "", - backing_it->second->GetID(), - backing_it->second->GetProtocolID(), memory_thread->GetID()); - memory_thread->SetBackingThread(backing_it->second); - new_thread_list.RemoveThreadByID(backing_it->second->GetID(), false); - } - } - } - new_thread_list.AddThread(memory_thread); - } - - return new_thread_list.GetSize(false) > 0; -} - -void OperatingSystemGo::ThreadWasSelected(Thread *thread) {} - -RegisterContextSP -OperatingSystemGo::CreateRegisterContextForThread(Thread *thread, - addr_t reg_data_addr) { - RegisterContextSP reg_ctx_sp; - if (!thread) - return reg_ctx_sp; - - if (!IsOperatingSystemPluginThread(thread->shared_from_this())) - return reg_ctx_sp; - - reg_ctx_sp.reset( - new RegisterContextGo(*thread, 0, *m_reginfo, reg_data_addr)); - return reg_ctx_sp; -} - -StopInfoSP -OperatingSystemGo::CreateThreadStopReason(lldb_private::Thread *thread) { - StopInfoSP stop_info_sp; - return stop_info_sp; -} - -lldb::ThreadSP OperatingSystemGo::CreateThread(lldb::tid_t tid, - addr_t context) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); - - if (log) - log->Printf("OperatingSystemGo::CreateThread (tid = 0x%" PRIx64 - ", context = 0x%" PRIx64 ") not implemented", - tid, context); - - return ThreadSP(); -} - -ValueObjectSP OperatingSystemGo::FindGlobal(TargetSP target, const char *name) { - VariableList variable_list; - - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); - - if (log) { - log->Printf( - "exe: %s", - target->GetExecutableModule()->GetSpecificationDescription().c_str()); - log->Printf("modules: %zu", target->GetImages().GetSize()); - } - - uint32_t match_count = target->GetImages().FindGlobalVariables( - ConstString(name), 1, variable_list); - if (match_count > 0) { - ExecutionContextScope *exe_scope = target->GetProcessSP().get(); - if (exe_scope == NULL) - exe_scope = target.get(); - return ValueObjectVariable::Create(exe_scope, - variable_list.GetVariableAtIndex(0)); - } - return ValueObjectSP(); -} - -TypeSP OperatingSystemGo::FindType(TargetSP target_sp, const char *name) { - ConstString const_typename(name); - SymbolContext sc; - const bool exact_match = false; - - const ModuleList &module_list = target_sp->GetImages(); - size_t count = module_list.GetSize(); - for (size_t idx = 0; idx < count; idx++) { - ModuleSP module_sp(module_list.GetModuleAtIndex(idx)); - if (module_sp) { - TypeSP type_sp(module_sp->FindFirstType(sc, const_typename, exact_match)); - if (type_sp) - return type_sp; - } - } - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OS)); - - if (log) - log->Printf("OperatingSystemGo::FindType(%s): not found", name); - return TypeSP(); -} - -OperatingSystemGo::Goroutine -OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Status &err) { - err.Clear(); - Goroutine result = {}; - ValueObjectSP g = - m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err); - if (err.Fail()) { - return result; - } - - ConstString name("goid"); - ValueObjectSP val = g->GetChildMemberWithName(name, true); - bool success = false; - result.m_goid = val->GetValueAsUnsigned(0, &success); - if (!success) { - err.SetErrorToGenericError(); - err.SetErrorString("unable to read goid"); - return result; - } - name.SetCString("atomicstatus"); - val = g->GetChildMemberWithName(name, true); - result.m_status = (uint32_t)val->GetValueAsUnsigned(0, &success); - if (!success) { - err.SetErrorToGenericError(); - err.SetErrorString("unable to read atomicstatus"); - return result; - } - name.SetCString("sched"); - val = g->GetChildMemberWithName(name, true); - result.m_gobuf = val->GetAddressOf(false); - name.SetCString("stack"); - val = g->GetChildMemberWithName(name, true); - name.SetCString("lo"); - ValueObjectSP child = val->GetChildMemberWithName(name, true); - result.m_lostack = child->GetValueAsUnsigned(0, &success); - if (!success) { - err.SetErrorToGenericError(); - err.SetErrorString("unable to read stack.lo"); - return result; - } - name.SetCString("hi"); - child = val->GetChildMemberWithName(name, true); - result.m_histack = child->GetValueAsUnsigned(0, &success); - if (!success) { - err.SetErrorToGenericError(); - err.SetErrorString("unable to read stack.hi"); - return result; - } - return result; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h b/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h deleted file mode 100644 index 5d255a348a63..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Go/OperatingSystemGo.h +++ /dev/null @@ -1,90 +0,0 @@ -//===-- OperatingSystemGo.h -------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef _liblldb_OperatingSystemGo_h_ -#define _liblldb_OperatingSystemGo_h_ - -// C Includes -// C++ Includes -#include - -// Other libraries and framework includes -// Project includes -#include "lldb/Target/OperatingSystem.h" - -class DynamicRegisterInfo; - -class OperatingSystemGo : public lldb_private::OperatingSystem { -public: - OperatingSystemGo(lldb_private::Process *process); - - ~OperatingSystemGo() override; - - //------------------------------------------------------------------ - // Static Functions - //------------------------------------------------------------------ - static lldb_private::OperatingSystem * - CreateInstance(lldb_private::Process *process, bool force); - - static void Initialize(); - - static void DebuggerInitialize(lldb_private::Debugger &debugger); - - static void Terminate(); - - static lldb_private::ConstString GetPluginNameStatic(); - - static const char *GetPluginDescriptionStatic(); - - //------------------------------------------------------------------ - // lldb_private::PluginInterface Methods - //------------------------------------------------------------------ - lldb_private::ConstString GetPluginName() override; - - uint32_t GetPluginVersion() override; - - //------------------------------------------------------------------ - // lldb_private::OperatingSystem Methods - //------------------------------------------------------------------ - bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, - lldb_private::ThreadList &real_thread_list, - lldb_private::ThreadList &new_thread_list) override; - - void ThreadWasSelected(lldb_private::Thread *thread) override; - - lldb::RegisterContextSP - CreateRegisterContextForThread(lldb_private::Thread *thread, - lldb::addr_t reg_data_addr) override; - - lldb::StopInfoSP - CreateThreadStopReason(lldb_private::Thread *thread) override; - - //------------------------------------------------------------------ - // Method for lazy creation of threads on demand - //------------------------------------------------------------------ - lldb::ThreadSP CreateThread(lldb::tid_t tid, lldb::addr_t context) override; - -private: - struct Goroutine; - - static lldb::ValueObjectSP FindGlobal(lldb::TargetSP target, - const char *name); - - static lldb::TypeSP FindType(lldb::TargetSP target_sp, const char *name); - - bool Init(lldb_private::ThreadList &threads); - - Goroutine CreateGoroutineAtIndex(uint64_t idx, lldb_private::Status &err); - - std::unique_ptr m_reginfo; - lldb::ValueObjectSP m_allg_sp; - lldb::ValueObjectSP m_allglen_sp; -}; - -#endif // liblldb_OperatingSystemGo_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp b/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp index d6252c473270..89a0f2253936 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp @@ -10,9 +10,6 @@ #ifndef LLDB_DISABLE_PYTHON #include "OperatingSystemPython.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "Plugins/Process/Utility/DynamicRegisterInfo.h" #include "Plugins/Process/Utility/RegisterContextDummy.h" #include "Plugins/Process/Utility/RegisterContextMemory.h" @@ -20,7 +17,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/ValueObjectVariable.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" @@ -32,6 +28,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadList.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" @@ -53,7 +50,8 @@ OperatingSystem *OperatingSystemPython::CreateInstance(Process *process, // Python OperatingSystem plug-ins must be requested by name, so force must // be true FileSpec python_os_plugin_spec(process->GetPythonOSPluginPath()); - if (python_os_plugin_spec && python_os_plugin_spec.Exists()) { + if (python_os_plugin_spec && + FileSystem::Instance().Exists(python_os_plugin_spec)) { std::unique_ptr os_ap( new OperatingSystemPython(process, python_os_plugin_spec)); if (os_ap.get() && os_ap->IsValid()) @@ -215,7 +213,7 @@ bool OperatingSystemPython::UpdateThreadList(ThreadList &old_thread_list, // beginning of the list uint32_t insert_idx = 0; for (uint32_t core_idx = 0; core_idx < num_cores; ++core_idx) { - if (core_used_map[core_idx] == false) { + if (!core_used_map[core_idx]) { new_thread_list.InsertThread( core_thread_list.GetThreadAtIndex(core_idx, false), insert_idx); ++insert_idx; diff --git a/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h b/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h index 2e1680410962..c812464fa747 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h +++ b/contrib/llvm/tools/lldb/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h @@ -12,10 +12,6 @@ #ifndef LLDB_DISABLE_PYTHON -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/OperatingSystem.h" #include "lldb/Utility/StructuredData.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp index bc8111d1078b..59cce3a6bc2b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp @@ -10,25 +10,21 @@ #include "PlatformFreeBSD.h" #include "lldb/Host/Config.h" -// C Includes #include #ifndef LLDB_DISABLE_POSIX #include #endif -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/BreakpointSite.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" @@ -52,7 +48,7 @@ PlatformSP PlatformFreeBSD::CreateInstance(bool force, const ArchSpec *arch) { arch ? arch->GetTriple().getTriple() : ""); bool create = force; - if (create == false && arch && arch->IsValid()) { + if (!create && arch && arch->IsValid()) { const llvm::Triple &triple = arch->GetTriple(); switch (triple.getOS()) { case llvm::Triple::FreeBSD: @@ -274,9 +270,9 @@ lldb::ProcessSP PlatformFreeBSD::Attach(ProcessAttachInfo &attach_info, TargetSP new_target_sp; ArchSpec emptyArchSpec; - error = debugger.GetTargetList().CreateTarget(debugger, "", emptyArchSpec, - false, m_remote_platform_sp, - new_target_sp); + error = debugger.GetTargetList().CreateTarget( + debugger, "", emptyArchSpec, eLoadDependentsNo, m_remote_platform_sp, + new_target_sp); target = new_target_sp.get(); } else error.Clear(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp index 3aa8ecb4c228..aadcf961c729 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp @@ -10,23 +10,19 @@ #include "PlatformNetBSD.h" #include "lldb/Host/Config.h" -// C Includes #include #ifndef LLDB_DISABLE_POSIX #include #endif -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" @@ -50,7 +46,7 @@ PlatformSP PlatformNetBSD::CreateInstance(bool force, const ArchSpec *arch) { arch ? arch->GetTriple().getTriple() : ""); bool create = force; - if (create == false && arch && arch->IsValid()) { + if (!create && arch && arch->IsValid()) { const llvm::Triple &triple = arch->GetTriple(); switch (triple.getOS()) { case llvm::Triple::NetBSD: @@ -271,8 +267,8 @@ PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, if (target == nullptr) { LLDB_LOG(log, "creating new target"); TargetSP new_target_sp; - error = debugger.GetTargetList().CreateTarget(debugger, "", "", false, - nullptr, new_target_sp); + error = debugger.GetTargetList().CreateTarget( + debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp); if (error.Fail()) { LLDB_LOG(log, "failed to create new target: {0}", error); return process_sp; @@ -291,8 +287,8 @@ PlatformNetBSD::DebugProcess(ProcessLaunchInfo &launch_info, Debugger &debugger, // Now create the gdb-remote process. LLDB_LOG(log, "having target create process with gdb-remote plugin"); - process_sp = target->CreateProcess( - launch_info.GetListenerForProcess(debugger), "gdb-remote", nullptr); + process_sp = + target->CreateProcess(launch_info.GetListener(), "gdb-remote", nullptr); if (!process_sp) { error.SetErrorString("CreateProcess() failed for gdb-remote process"); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp index 10ca8fbfbdd7..7358acb61f79 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Platform/OpenBSD/PlatformOpenBSD.cpp @@ -10,23 +10,19 @@ #include "PlatformOpenBSD.h" #include "lldb/Host/Config.h" -// C Includes #include #ifndef LLDB_DISABLE_POSIX #include #endif -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamString.h" @@ -50,7 +46,7 @@ PlatformSP PlatformOpenBSD::CreateInstance(bool force, const ArchSpec *arch) { arch ? arch->GetTriple().getTriple() : ""); bool create = force; - if (create == false && arch && arch->IsValid()) { + if (!create && arch && arch->IsValid()) { const llvm::Triple &triple = arch->GetTriple(); switch (triple.getOS()) { case llvm::Triple::OpenBSD: diff --git a/contrib/llvm/tools/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/contrib/llvm/tools/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp index 5e7ffe71918e..bfa1376d3151 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp @@ -9,10 +9,6 @@ #include "PlatformPOSIX.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -128,23 +124,25 @@ PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec, if (IsHost()) { // If we have "ls" as the exe_file, resolve the executable location based // on the current path variables - if (!resolved_module_spec.GetFileSpec().Exists()) { + if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) { resolved_module_spec.GetFileSpec().GetPath(exe_path, sizeof(exe_path)); - resolved_module_spec.GetFileSpec().SetFile(exe_path, true, + resolved_module_spec.GetFileSpec().SetFile(exe_path, FileSpec::Style::native); + FileSystem::Instance().Resolve(resolved_module_spec.GetFileSpec()); } - if (!resolved_module_spec.GetFileSpec().Exists()) - resolved_module_spec.GetFileSpec().ResolveExecutableLocation(); + if (!FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) + FileSystem::Instance().ResolveExecutableLocation( + resolved_module_spec.GetFileSpec()); // Resolve any executable within a bundle on MacOSX Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); - if (resolved_module_spec.GetFileSpec().Exists()) + if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) error.Clear(); else { - const uint32_t permissions = - resolved_module_spec.GetFileSpec().GetPermissions(); + const uint32_t permissions = FileSystem::Instance().GetPermissions( + resolved_module_spec.GetFileSpec()); if (permissions && (permissions & eFilePermissionsEveryoneR) == 0) error.SetErrorStringWithFormat( "executable '%s' is not readable", @@ -166,7 +164,7 @@ PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec, // Resolve any executable within a bundle on MacOSX Host::ResolveExecutableInBundle(resolved_module_spec.GetFileSpec()); - if (resolved_module_spec.GetFileSpec().Exists()) + if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec())) error.Clear(); else error.SetErrorStringWithFormat("the platform is not currently " @@ -237,7 +235,8 @@ PlatformPOSIX::ResolveExecutable(const ModuleSpec &module_spec, } if (error.Fail() || !exe_module_sp) { - if (resolved_module_spec.GetFileSpec().Readable()) { + if (FileSystem::Instance().Readable( + resolved_module_spec.GetFileSpec())) { error.SetErrorStringWithFormat( "'%s' doesn't contain any '%s' platform architectures: %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), @@ -455,7 +454,7 @@ lldb::user_id_t PlatformPOSIX::GetFileSize(const FileSpec &file_spec) { Status PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst) { if (IsHost()) - return FileSystem::Symlink(src, dst); + return FileSystem::Instance().Symlink(src, dst); else if (m_remote_platform_sp) return m_remote_platform_sp->CreateSymlink(src, dst); else @@ -464,7 +463,7 @@ Status PlatformPOSIX::CreateSymlink(const FileSpec &src, const FileSpec &dst) { bool PlatformPOSIX::GetFileExists(const FileSpec &file_spec) { if (IsHost()) - return file_spec.Exists(); + return FileSystem::Instance().Exists(file_spec); else if (m_remote_platform_sp) return m_remote_platform_sp->GetFileExists(file_spec); else @@ -813,8 +812,8 @@ lldb::ProcessSP PlatformPOSIX::Attach(ProcessAttachInfo &attach_info, if (target == NULL) { TargetSP new_target_sp; - error = debugger.GetTargetList().CreateTarget(debugger, "", "", false, - NULL, new_target_sp); + error = debugger.GetTargetList().CreateTarget( + debugger, "", "", eLoadDependentsNo, NULL, new_target_sp); target = new_target_sp.get(); if (log) log->Printf("PlatformPOSIX::%s created new target", __FUNCTION__); @@ -1244,7 +1243,8 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, options.SetTrapExceptions(false); // dlopen can't throw exceptions, so // don't do the work to trap them. options.SetTimeout(std::chrono::seconds(2)); - + options.SetIsForUtilityExpr(true); + Value return_value; // Fetch the clang types we will need: ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext(); @@ -1281,8 +1281,7 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process, std::string name_string; process->ReadCStringFromMemory(buffer_addr, name_string, utility_error); if (utility_error.Success()) - loaded_image->SetFile(name_string, false, - llvm::sys::path::Style::posix); + loaded_image->SetFile(name_string, llvm::sys::path::Style::posix); } return process->AddImageToken(token); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/contrib/llvm/tools/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h index cc6f7299c194..97333ef1eb7c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Platform/POSIX/PlatformPOSIX.h @@ -10,13 +10,9 @@ #ifndef liblldb_PlatformPOSIX_h_ #define liblldb_PlatformPOSIX_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/Options.h" #include "lldb/Target/Platform.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp b/contrib/llvm/tools/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp index 348bb825a5c5..f6ace706ca3f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.cpp @@ -10,9 +10,6 @@ #include "PlatformRemoteGDBServer.h" #include "lldb/Host/Config.h" -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" @@ -43,7 +40,7 @@ static bool g_initialized = false; void PlatformRemoteGDBServer::Initialize() { Platform::Initialize(); - if (g_initialized == false) { + if (!g_initialized) { g_initialized = true; PluginManager::RegisterPlugin( PlatformRemoteGDBServer::GetPluginNameStatic(), @@ -107,7 +104,7 @@ Status PlatformRemoteGDBServer::ResolveExecutable( // Resolve any executable within an apk on Android? // Host::ResolveExecutableInBundle (resolved_module_spec.GetFileSpec()); - if (resolved_module_spec.GetFileSpec().Exists() || + if (FileSystem::Instance().Exists(resolved_module_spec.GetFileSpec()) || module_spec.GetUUID().IsValid()) { if (resolved_module_spec.GetArchitecture().IsValid() || resolved_module_spec.GetUUID().IsValid()) { @@ -142,7 +139,7 @@ Status PlatformRemoteGDBServer::ResolveExecutable( } if (error.Fail() || !exe_module_sp) { - if (resolved_module_spec.GetFileSpec().Readable()) { + if (FileSystem::Instance().Readable(resolved_module_spec.GetFileSpec())) { error.SetErrorStringWithFormat( "'%s' doesn't contain any '%s' platform architectures: %s", resolved_module_spec.GetFileSpec().GetPath().c_str(), @@ -488,8 +485,8 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess( if (target == NULL) { TargetSP new_target_sp; - error = debugger.GetTargetList().CreateTarget(debugger, "", "", false, - NULL, new_target_sp); + error = debugger.GetTargetList().CreateTarget( + debugger, "", "", eLoadDependentsNo, NULL, new_target_sp); target = new_target_sp.get(); } else error.Clear(); @@ -499,8 +496,8 @@ lldb::ProcessSP PlatformRemoteGDBServer::DebugProcess( // The darwin always currently uses the GDB remote debugger plug-in // so even when debugging locally we are debugging remotely! - process_sp = target->CreateProcess( - launch_info.GetListenerForProcess(debugger), "gdb-remote", NULL); + process_sp = target->CreateProcess(launch_info.GetListener(), + "gdb-remote", NULL); if (process_sp) { error = process_sp->ConnectRemote(nullptr, connect_url.c_str()); @@ -574,8 +571,8 @@ lldb::ProcessSP PlatformRemoteGDBServer::Attach( if (target == NULL) { TargetSP new_target_sp; - error = debugger.GetTargetList().CreateTarget(debugger, "", "", false, - NULL, new_target_sp); + error = debugger.GetTargetList().CreateTarget( + debugger, "", "", eLoadDependentsNo, NULL, new_target_sp); target = new_target_sp.get(); } else error.Clear(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h b/contrib/llvm/tools/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h index a31933b5d9b0..7abb33423bc1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Platform/gdb-server/PlatformRemoteGDBServer.h @@ -11,12 +11,8 @@ #ifndef liblldb_PlatformRemoteGDBServer_h_ #define liblldb_PlatformRemoteGDBServer_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h" #include "Plugins/Process/Utility/GDBRemoteSignals.h" #include "lldb/Target/Platform.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp index 3505443abcb0..70d9a5248fd9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.cpp @@ -19,10 +19,10 @@ // C++ includes // LLDB includes -#include "lldb/Core/State.h" #include "lldb/Host/PseudoTerminal.h" #include "lldb/Target/ProcessLaunchInfo.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "CFBundle.h" @@ -63,12 +63,13 @@ Status NativeProcessProtocol::Launch( // Verify the working directory is valid if one was specified. FileSpec working_dir(launch_info.GetWorkingDirectory()); - if (working_dir && - (!working_dir.ResolvePath() || - !llvm::sys::fs::is_directory(working_dir.GetPath())) { - error.SetErrorStringWithFormat("No such file or directory: %s", + if (working_dir) { + FileInstance::Instance().Resolve(working_dir); + if (!FileSystem::Instance().IsDirectory(working_dir)) { + error.SetErrorStringWithFormat("No such file or directory: %s", working_dir.GetCString()); - return error; + return error; + } } // Launch the inferior. diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h index 0b186fd7d80c..9abdd5360eba 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Darwin/NativeProcessDarwin.h @@ -21,7 +21,6 @@ #include #include -// Other libraries and framework includes #include "lldb/Host/Debug.h" #include "lldb/Host/HostThread.h" #include "lldb/Host/Pipe.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp index 66d3ca77fa91..f0c9286c6832 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include #include #include @@ -16,12 +15,9 @@ #include #include -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/State.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/State.h" -// Project includes #include "FreeBSDThread.h" #include "POSIXStopInfo.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" @@ -42,7 +38,6 @@ #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/HostNativeThread.h" @@ -50,6 +45,7 @@ #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/State.h" #include "llvm/ADT/SmallString.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h index c93cc4fbfd73..a8559fe8b2ca 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/FreeBSDThread.h @@ -10,11 +10,9 @@ #ifndef liblldb_FreeBSDThread_H_ #define liblldb_FreeBSDThread_H_ -// C++ Includes #include #include -// Other libraries and framework includes #include "RegisterContextPOSIX.h" #include "lldb/Target/Thread.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp index fa0bcea8f6bd..a13d4bcc4ecb 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessFreeBSD.cpp @@ -8,7 +8,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include #include #include @@ -18,18 +17,17 @@ #include #include -// C++ Includes #include #include -// Other libraries and framework includes #include "lldb/Core/PluginManager.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/Target.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include "FreeBSDThread.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" @@ -38,13 +36,11 @@ #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" -// Other libraries and framework includes #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/DynamicLoader.h" @@ -52,6 +48,7 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/State.h" #include "lldb/Host/posix/Fcntl.h" @@ -287,7 +284,7 @@ bool ProcessFreeBSD::CanDebug(lldb::TargetSP target_sp, // For now we are just making sure the file exists for a given module ModuleSP exe_module_sp(target_sp->GetExecutableModule()); if (exe_module_sp.get()) - return exe_module_sp->GetFileSpec().Exists(); + return FileSystem::Instance().Exists(exe_module_sp->GetFileSpec()); // If there is no executable module, we return true since we might be // preparing to attach. return true; @@ -335,7 +332,7 @@ ProcessFreeBSD::DoAttachToProcessWithID(lldb::pid_t pid, GetTarget().SetArchitecture(module_arch); // Initialize the target module list - GetTarget().SetExecutableModule(exe_module_sp, true); + GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsYes); SetSTDIOFileDescriptor(m_monitor->GetTerminalFD()); @@ -373,12 +370,13 @@ Status ProcessFreeBSD::DoLaunch(Module *module, assert(m_monitor == NULL); FileSpec working_dir = launch_info.GetWorkingDirectory(); - namespace fs = llvm::sys::fs; - if (working_dir && (!working_dir.ResolvePath() || - !fs::is_directory(working_dir.GetPath()))) { - error.SetErrorStringWithFormat("No such file or directory: %s", + if (working_dir) { + FileSystem::Instance().Resolve(working_dir); + if (!FileSystem::Instance().IsDirectory(working_dir.GetPath())) { + error.SetErrorStringWithFormat("No such file or directory: %s", working_dir.GetCString()); - return error; + return error; + } } SetPrivateState(eStateLaunching); @@ -390,8 +388,7 @@ Status ProcessFreeBSD::DoLaunch(Module *module, FileSpec stdout_file_spec{}; FileSpec stderr_file_spec{}; - const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0), - false}; + const FileSpec dbg_pts_file_spec{launch_info.GetPTY().GetSlaveName(NULL, 0)}; file_action = launch_info.GetFileActionForFD(STDIN_FILENO); stdin_file_spec = @@ -519,7 +516,7 @@ void ProcessFreeBSD::DoDidExec() { executable_search_paths.GetSize() ? &executable_search_paths : NULL); if (!error.Success()) return; - target->SetExecutableModule(exe_module_sp, true); + target->SetExecutableModule(exe_module_sp, eLoadDependentsYes); } } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index 51fdf2e5ef33..617ae3030f10 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -7,7 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes #include #include #include @@ -19,16 +18,14 @@ #include #include -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Host/Host.h" #include "lldb/Host/PseudoTerminal.h" #include "lldb/Host/ThreadLauncher.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Status.h" #include "llvm/Support/Errno.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h index 1d3e2d746fa9..ca7c4e03966c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -10,14 +10,11 @@ #ifndef liblldb_ProcessMonitor_H_ #define liblldb_ProcessMonitor_H_ -// C Includes #include #include -// C++ Includes #include -// Other libraries and framework includes #include "lldb/Host/HostThread.h" #include "lldb/Utility/FileSpec.h" #include "lldb/lldb-types.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h index b1b44e71de46..32973abd9207 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIX.h @@ -10,9 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_H_ #define liblldb_RegisterContextPOSIX_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "Plugins/Process/Utility/RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/ArchSpec.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp index 8ddc253aea5d..0642a30ade70 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm.cpp @@ -7,9 +7,9 @@ // //===---------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp index 93ffeb5ea79b..b35ee18d6a96 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_arm64.cpp @@ -7,9 +7,9 @@ // //===---------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_arm64.h" #include "ProcessFreeBSD.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp index 734167e1fc98..17df44cf85ee 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_mips64.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/RegisterContextPOSIX_mips64.h" #include "ProcessFreeBSD.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp index 5cc6cd290629..a8d75963ea6b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_powerpc.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "ProcessFreeBSD.h" #include "ProcessMonitor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp index 7db7f803b371..68fd5ac13bb0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/FreeBSD/RegisterContextPOSIXProcessMonitor_x86.cpp @@ -7,9 +7,9 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/FreeBSD/ProcessFreeBSD.h" #include "Plugins/Process/FreeBSD/ProcessMonitor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp index 1a4cb21d000e..a1b7d7df4553 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp @@ -9,18 +9,14 @@ #include "NativeProcessNetBSD.h" -// C Includes -// C++ Includes -// Other libraries and framework includes #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostProcess.h" -#include "lldb/Host/common/NativeBreakpoint.h" #include "lldb/Host/common/NativeRegisterContext.h" #include "lldb/Host/posix/ProcessLauncherPosixFork.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/State.h" #include "llvm/Support/Errno.h" // System includes - They have to be included after framework includes because @@ -322,100 +318,6 @@ Status NativeProcessNetBSD::PtraceWrapper(int req, lldb::pid_t pid, void *addr, return error; } -Status NativeProcessNetBSD::GetSoftwareBreakpointPCOffset( - uint32_t &actual_opcode_size) { - // FIXME put this behind a breakpoint protocol class that can be - // set per architecture. Need ARM, MIPS support here. - static const uint8_t g_i386_opcode[] = {0xCC}; - switch (m_arch.GetMachine()) { - case llvm::Triple::x86_64: - actual_opcode_size = static_cast(sizeof(g_i386_opcode)); - return Status(); - default: - assert(false && "CPU type not supported!"); - return Status("CPU type not supported"); - } -} - -Status -NativeProcessNetBSD::FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread) { - Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_BREAKPOINTS)); - Status error; - // Find out the size of a breakpoint (might depend on where we are in the - // code). - NativeRegisterContext& context = thread.GetRegisterContext(); - uint32_t breakpoint_size = 0; - error = GetSoftwareBreakpointPCOffset(breakpoint_size); - if (error.Fail()) { - LLDB_LOG(log, "GetBreakpointSize() failed: {0}", error); - return error; - } else - LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size); - // First try probing for a breakpoint at a software breakpoint location: PC - - // breakpoint size. - const lldb::addr_t initial_pc_addr = - context.GetPCfromBreakpointLocation(); - lldb::addr_t breakpoint_addr = initial_pc_addr; - if (breakpoint_size > 0) { - // Do not allow breakpoint probe to wrap around. - if (breakpoint_addr >= breakpoint_size) - breakpoint_addr -= breakpoint_size; - } - // Check if we stopped because of a breakpoint. - NativeBreakpointSP breakpoint_sp; - error = m_breakpoint_list.GetBreakpoint(breakpoint_addr, breakpoint_sp); - if (!error.Success() || !breakpoint_sp) { - // We didn't find one at a software probe location. Nothing to do. - LLDB_LOG(log, - "pid {0} no lldb breakpoint found at current pc with " - "adjustment: {1}", - GetID(), breakpoint_addr); - return Status(); - } - // If the breakpoint is not a software breakpoint, nothing to do. - if (!breakpoint_sp->IsSoftwareBreakpoint()) { - LLDB_LOG( - log, - "pid {0} breakpoint found at {1:x}, not software, nothing to adjust", - GetID(), breakpoint_addr); - return Status(); - } - // - // We have a software breakpoint and need to adjust the PC. - // - // Sanity check. - if (breakpoint_size == 0) { - // Nothing to do! How did we get here? - LLDB_LOG(log, - "pid {0} breakpoint found at {1:x}, it is software, but the " - "size is zero, nothing to do (unexpected)", - GetID(), breakpoint_addr); - return Status(); - } - // - // We have a software breakpoint and need to adjust the PC. - // - // Sanity check. - if (breakpoint_size == 0) { - // Nothing to do! How did we get here? - LLDB_LOG(log, - "pid {0} breakpoint found at {1:x}, it is software, but the " - "size is zero, nothing to do (unexpected)", - GetID(), breakpoint_addr); - return Status(); - } - // Change the program counter. - LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(), - thread.GetID(), initial_pc_addr, breakpoint_addr); - error = context.SetPC(breakpoint_addr); - if (error.Fail()) { - LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(), - thread.GetID(), error); - return error; - } - return error; -} - Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) { Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); LLDB_LOG(log, "pid {0}", GetID()); @@ -637,7 +539,7 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() { info.SetName(vm[i].kve_path); m_mem_region_cache.emplace_back( - info, FileSpec(info.GetName().GetCString(), true)); + info, FileSpec(info.GetName().GetCString())); } free(vm); @@ -682,23 +584,6 @@ Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size, return SetSoftwareBreakpoint(addr, size); } -Status NativeProcessNetBSD::GetSoftwareBreakpointTrapOpcode( - size_t trap_opcode_size_hint, size_t &actual_opcode_size, - const uint8_t *&trap_opcode_bytes) { - static const uint8_t g_i386_opcode[] = {0xCC}; - - switch (m_arch.GetMachine()) { - case llvm::Triple::x86: - case llvm::Triple::x86_64: - trap_opcode_bytes = g_i386_opcode; - actual_opcode_size = sizeof(g_i386_opcode); - return Status(); - default: - assert(false && "CPU type not supported!"); - return Status("CPU type not supported"); - } -} - Status NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path, FileSpec &file_spec) { return Status("Unimplemented"); @@ -824,15 +709,6 @@ Status NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf, return Status(); } -Status NativeProcessNetBSD::ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, - size_t size, - size_t &bytes_read) { - Status error = ReadMemory(addr, buf, size, bytes_read); - if (error.Fail()) - return error; - return m_breakpoint_list.RemoveTrapsFromBuffer(addr, buf, size); -} - Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) { const unsigned char *src = static_cast(buf); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h index 142f74ecf194..a3f1c4c6a06a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h @@ -58,9 +58,6 @@ public: Status ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override; - Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, - size_t &bytes_read) override; - Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override; @@ -93,16 +90,6 @@ public: static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr, int data = 0, int *result = nullptr); -protected: - // --------------------------------------------------------------------- - // NativeProcessProtocol protected interface - // --------------------------------------------------------------------- - - Status - GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint, - size_t &actual_opcode_size, - const uint8_t *&trap_opcode_bytes) override; - private: MainLoop::SignalHandleUP m_sigchld_handle; ArchSpec m_arch; @@ -125,8 +112,6 @@ private: void MonitorSIGTRAP(lldb::pid_t pid); void MonitorSignal(lldb::pid_t pid, int signal); - Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size); - Status FixupBreakpointPCAsNeeded(NativeThreadNetBSD &thread); Status PopulateMemoryRegionCache(); void SigchldHandler(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp index 16b6f2c52dd5..78da3527122f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeRegisterContextNetBSD_x86_64.cpp @@ -11,10 +11,10 @@ #include "NativeRegisterContextNetBSD_x86_64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Host/HostInfo.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" #include "Plugins/Process/Utility/RegisterContextNetBSD_x86_64.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp index 83f1da78d01d..6f5d1120e40d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/NetBSD/NativeThreadNetBSD.cpp @@ -14,9 +14,9 @@ #include "Plugins/Process/POSIX/CrashReason.h" #include "Plugins/Process/POSIX/ProcessPOSIXLog.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h index 134013517a11..3ac798b3d4b3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/POSIX/ProcessPOSIXLog.h @@ -11,11 +11,7 @@ #ifndef liblldb_ProcessPOSIXLog_h_ #define liblldb_ProcessPOSIXLog_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Log.h" #define POSIX_LOG_PROCESS (1u << 1) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ARMUtils.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ARMUtils.h index 2bbd519b246a..2c14dc936cbc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ARMUtils.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ARMUtils.h @@ -12,7 +12,7 @@ #include "ARMDefines.h" #include "InstructionUtils.h" -#include "llvm/Support/MathExtras.h" // for SignExtend64 template function +#include "llvm/Support/MathExtras.h" // Common utilities for the ARM/Thumb Instruction Set Architecture. diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp index 5f34e9915ede..dcbf474fa55a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp @@ -464,7 +464,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { end = m_value_regs_map.end(); pos != end; ++pos) { if (pos->second.size() > 1) { - std::sort(pos->second.begin(), pos->second.end()); + llvm::sort(pos->second.begin(), pos->second.end()); reg_num_collection::iterator unique_end = std::unique(pos->second.begin(), pos->second.end()); if (unique_end != pos->second.end()) @@ -514,7 +514,7 @@ void DynamicRegisterInfo::Finalize(const ArchSpec &arch) { end = m_invalidate_regs_map.end(); pos != end; ++pos) { if (pos->second.size() > 1) { - std::sort(pos->second.begin(), pos->second.end()); + llvm::sort(pos->second.begin(), pos->second.end()); reg_num_collection::iterator unique_end = std::unique(pos->second.begin(), pos->second.end()); if (unique_end != pos->second.end()) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h index acb3e3eb8a84..68f3902e0c96 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/DynamicRegisterInfo.h @@ -10,13 +10,9 @@ #ifndef lldb_DynamicRegisterInfo_h_ #define lldb_DynamicRegisterInfo_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Utility/ConstString.h" #include "lldb/Utility/StructuredData.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp index f695a11c9759..0b56b6093559 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "FreeBSDSignals.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h index 8ec96e824f7a..174025cabb82 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/FreeBSDSignals.h @@ -10,7 +10,6 @@ #ifndef liblldb_FreeBSDSignals_H_ #define liblldb_FreeBSDSignals_H_ -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp index abcc8a38669a..cc0537c2a8b3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// C++ Includes -// Other libraries and framework includes -// Project includes #include "GDBRemoteSignals.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h index 5900fa75d6f2..79d8ec3fbbaf 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/GDBRemoteSignals.h @@ -10,10 +10,6 @@ #ifndef liblldb_GDBRemoteSignals_H_ #define liblldb_GDBRemoteSignals_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h index 7675a95246a7..dc24922e7c17 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryThread.h @@ -10,18 +10,14 @@ #ifndef liblldb_HistoryThread_h_ #define liblldb_HistoryThread_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Broadcaster.h" -#include "lldb/Core/Event.h" #include "lldb/Core/UserSettingsController.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/StackFrameList.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/UserID.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.h index 3b64e38bfaa7..2cbfb680ef49 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/HistoryUnwind.h @@ -10,12 +10,8 @@ #ifndef liblldb_HistoryUnwind_h_ #define liblldb_HistoryUnwind_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Unwind.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp new file mode 100644 index 000000000000..d45bf6dcd84f --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxProcMaps.cpp @@ -0,0 +1,113 @@ +//===-- LinuxProcMaps.cpp ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LinuxProcMaps.h" +#include "llvm/ADT/StringRef.h" +#include "lldb/Target/MemoryRegionInfo.h" +#include "lldb/Utility/Status.h" +#include "lldb/Utility/StringExtractor.h" + +using namespace lldb_private; + +static Status +ParseMemoryRegionInfoFromProcMapsLine(llvm::StringRef maps_line, + MemoryRegionInfo &memory_region_info) { + memory_region_info.Clear(); + + StringExtractor line_extractor(maps_line); + + // Format: {address_start_hex}-{address_end_hex} perms offset dev inode + // pathname perms: rwxp (letter is present if set, '-' if not, final + // character is p=private, s=shared). + + // Parse out the starting address + lldb::addr_t start_address = line_extractor.GetHexMaxU64(false, 0); + + // Parse out hyphen separating start and end address from range. + if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != '-')) + return Status( + "malformed /proc/{pid}/maps entry, missing dash between address range"); + + // Parse out the ending address + lldb::addr_t end_address = line_extractor.GetHexMaxU64(false, start_address); + + // Parse out the space after the address. + if (!line_extractor.GetBytesLeft() || (line_extractor.GetChar() != ' ')) + return Status( + "malformed /proc/{pid}/maps entry, missing space after range"); + + // Save the range. + memory_region_info.GetRange().SetRangeBase(start_address); + memory_region_info.GetRange().SetRangeEnd(end_address); + + // Any memory region in /proc/{pid}/maps is by definition mapped into the + // process. + memory_region_info.SetMapped(MemoryRegionInfo::OptionalBool::eYes); + + // Parse out each permission entry. + if (line_extractor.GetBytesLeft() < 4) + return Status("malformed /proc/{pid}/maps entry, missing some portion of " + "permissions"); + + // Handle read permission. + const char read_perm_char = line_extractor.GetChar(); + if (read_perm_char == 'r') + memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eYes); + else if (read_perm_char == '-') + memory_region_info.SetReadable(MemoryRegionInfo::OptionalBool::eNo); + else + return Status("unexpected /proc/{pid}/maps read permission char"); + + // Handle write permission. + const char write_perm_char = line_extractor.GetChar(); + if (write_perm_char == 'w') + memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eYes); + else if (write_perm_char == '-') + memory_region_info.SetWritable(MemoryRegionInfo::OptionalBool::eNo); + else + return Status("unexpected /proc/{pid}/maps write permission char"); + + // Handle execute permission. + const char exec_perm_char = line_extractor.GetChar(); + if (exec_perm_char == 'x') + memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eYes); + else if (exec_perm_char == '-') + memory_region_info.SetExecutable(MemoryRegionInfo::OptionalBool::eNo); + else + return Status("unexpected /proc/{pid}/maps exec permission char"); + + line_extractor.GetChar(); // Read the private bit + line_extractor.SkipSpaces(); // Skip the separator + line_extractor.GetHexMaxU64(false, 0); // Read the offset + line_extractor.GetHexMaxU64(false, 0); // Read the major device number + line_extractor.GetChar(); // Read the device id separator + line_extractor.GetHexMaxU64(false, 0); // Read the major device number + line_extractor.SkipSpaces(); // Skip the separator + line_extractor.GetU64(0, 10); // Read the inode number + + line_extractor.SkipSpaces(); + const char *name = line_extractor.Peek(); + if (name) + memory_region_info.SetName(name); + + return Status(); +} + +void lldb_private::ParseLinuxMapRegions(llvm::StringRef linux_map, + LinuxMapCallback const &callback) { + llvm::StringRef lines(linux_map); + llvm::StringRef line; + while (!lines.empty()) { + std::tie(line, lines) = lines.split('\n'); + MemoryRegionInfo region; + Status error = ParseMemoryRegionInfoFromProcMapsLine(line, region); + if (!callback(region, error)) + break; + } +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h new file mode 100644 index 000000000000..e6eabb28fc82 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxProcMaps.h @@ -0,0 +1,28 @@ +//===-- LinuxProcMaps.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_LinuxProcMaps_H_ +#define liblldb_LinuxProcMaps_H_ + +#include "lldb/lldb-forward.h" +#include "llvm/ADT/StringRef.h" +#include + + +namespace lldb_private { + +typedef std::function LinuxMapCallback; + +void ParseLinuxMapRegions(llvm::StringRef linux_map, + LinuxMapCallback const &callback); + +} // namespace lldb_private + +#endif // liblldb_LinuxProcMaps_H_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp index eb01075ed133..6f1f67ac3570 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.cpp @@ -7,9 +7,6 @@ // //===----------------------------------------------------------------------===// -// C++ Includes -// Other libraries and framework includes -// Project includes #include "LinuxSignals.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.h index e41126225cee..f93a9d2e36d1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/LinuxSignals.h @@ -10,10 +10,6 @@ #ifndef liblldb_LinuxSignals_H_ #define liblldb_LinuxSignals_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp index 36231023aa3a..b6f3b34893bf 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.cpp @@ -8,9 +8,6 @@ // //===----------------------------------------------------------------------===// -// C++ Includes -// Other libraries and framework includes -// Project includes #include "MipsLinuxSignals.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h index e48ea5943f2b..2796f6b8e4d7 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/MipsLinuxSignals.h @@ -11,10 +11,6 @@ #ifndef liblldb_MipsLinuxSignals_H_ #define liblldb_MipsLinuxSignals_H_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp index 7ed7189d8048..a4baab9ac85f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "NetBSDSignals.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.h index 4338f881645e..7bb57fa0c0d6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/NetBSDSignals.h @@ -10,7 +10,6 @@ #ifndef liblldb_NetBSDSignals_H_ #define liblldb_NetBSDSignals_H_ -// Project includes #include "lldb/Target/UnixSignals.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp index 5d9ff02fafdd..9ad896abd0b4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp @@ -10,14 +10,12 @@ #include "RegisterContextDarwin_arm.h" #include "RegisterContextDarwinConstants.h" -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "Plugins/Process/Utility/InstructionUtils.h" @@ -28,7 +26,6 @@ #define LLVM_EXTENSION #endif -// Project includes #include "Utility/ARM_DWARF_Registers.h" #include "Utility/ARM_ehframe_Registers.h" @@ -1673,7 +1670,7 @@ uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr, return LLDB_INVALID_INDEX32; // We must watch for either read or write - if (read == false && write == false) + if (!read && !write) return LLDB_INVALID_INDEX32; // Can't watch more than 4 bytes per WVR/WCR pair diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h index cdf3479dff69..b46946d608bc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextDarwin_arm_h_ #define liblldb_RegisterContextDarwin_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp index 03ce7ef9f524..b478645e035d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.cpp @@ -11,16 +11,14 @@ #include "RegisterContextDarwin_arm64.h" #include "RegisterContextDarwinConstants.h" -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" @@ -32,7 +30,6 @@ #define LLVM_EXTENSION #endif -// Project includes #include "Utility/ARM64_DWARF_Registers.h" using namespace lldb; @@ -341,13 +338,23 @@ bool RegisterContextDarwin_arm64::ReadRegister(const RegisterInfo *reg_info, case gpr_x26: case gpr_x27: case gpr_x28: - case gpr_fp: - case gpr_sp: - case gpr_lr: - case gpr_pc: - case gpr_cpsr: value.SetUInt64(gpr.x[reg - gpr_x0]); break; + case gpr_fp: + value.SetUInt64(gpr.fp); + break; + case gpr_sp: + value.SetUInt64(gpr.sp); + break; + case gpr_lr: + value.SetUInt64(gpr.lr); + break; + case gpr_pc: + value.SetUInt64(gpr.pc); + break; + case gpr_cpsr: + value.SetUInt64(gpr.cpsr); + break; case gpr_w0: case gpr_w1: @@ -949,7 +956,7 @@ uint32_t RegisterContextDarwin_arm64::SetHardwareWatchpoint(lldb::addr_t addr, return LLDB_INVALID_INDEX32; // We must watch for either read or write - if (read == false && write == false) + if (!read && !write) return LLDB_INVALID_INDEX32; // Can't watch more than 4 bytes per WVR/WCR pair diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h index 4a0e50947ee7..9e826d85af08 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_arm64.h @@ -11,10 +11,6 @@ #ifndef liblldb_RegisterContextDarwin_arm64_h_ #define liblldb_RegisterContextDarwin_arm64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp index 24414211d9aa..c9e4b37a17f3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp @@ -7,17 +7,14 @@ // //===----------------------------------------------------------------------===// -// C Includes -#include // offsetof +#include -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" @@ -27,7 +24,6 @@ #define LLVM_EXTENSION #endif -// Project includes #include "RegisterContextDarwin_i386.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h index aea8a2900911..ad6a1e48fc34 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextDarwin_i386_h_ #define liblldb_RegisterContextDarwin_i386_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp index ecad8240b294..95460308857a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp @@ -7,19 +7,16 @@ // //===----------------------------------------------------------------------===// -// C Includes -#include // PRIx64 +#include #include -#include // offsetof +#include -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" @@ -29,7 +26,6 @@ #define LLVM_EXTENSION #endif -// Project includes #include "RegisterContextDarwin_x86_64.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h index fdd5e8036dee..6d94bf75aad4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextDarwin_x86_64_h_ #define liblldb_RegisterContextDarwin_x86_64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp index dd6ca92a74ee..c51c30f45a5d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/FuncUnwinders.h" @@ -28,6 +27,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" #include "RegisterContextDummy.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h index ea70288f3d69..d5608616c896 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextDummy.h @@ -11,12 +11,8 @@ #ifndef lldb_RegisterContextDummy_h_ #define lldb_RegisterContextDummy_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h index c9a65b1cacce..b74d0ea75469 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_powerpc.h @@ -11,10 +11,6 @@ #ifndef liblldb_RegisterContextFreeBSD_powerpc_h_ #define liblldb_RegisterContextFreeBSD_powerpc_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterInfoInterface.h" class RegisterContextFreeBSD_powerpc diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp index cc0d696b338a..c9b77663a803 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.cpp @@ -11,7 +11,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/FuncUnwinders.h" @@ -28,6 +27,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" #include "RegisterContextHistory.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h index acaf8fe5c04a..01b3624f8c5b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextHistory.h @@ -11,12 +11,8 @@ #ifndef lldb_RegisterContextHistory_h_ #define lldb_RegisterContextHistory_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp index ba9a8071bcfb..8c420a87e1b0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp @@ -10,7 +10,6 @@ #include "lldb/Core/Address.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/ArmUnwindInfo.h" @@ -31,6 +30,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" #include "RegisterContextLLDB.h" @@ -54,7 +54,8 @@ RegisterContextLLDB::RegisterContextLLDB(Thread &thread, : RegisterContext(thread, frame_number), m_thread(thread), m_fast_unwind_plan_sp(), m_full_unwind_plan_sp(), m_fallback_unwind_plan_sp(), m_all_registers_available(false), - m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS), m_start_pc(), + m_frame_type(-1), m_cfa(LLDB_INVALID_ADDRESS), + m_afa(LLDB_INVALID_ADDRESS), m_start_pc(), m_current_pc(), m_current_offset(0), m_current_offset_backed_up_one(0), m_sym_ctx(sym_ctx), m_sym_ctx_valid(false), m_frame_number(frame_number), m_registers(), m_parent_unwind(unwind_lldb) { @@ -150,7 +151,8 @@ void RegisterContextLLDB::InitializeZerothFrame() { // We require either a symbol or function in the symbols context to be // successfully filled in or this context is of no use to us. - const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; + const SymbolContextItem resolve_scope = + eSymbolContextFunction | eSymbolContextSymbol; if (pc_module_sp.get() && (pc_module_sp->ResolveSymbolContextForAddress( m_current_pc, resolve_scope, m_sym_ctx) & resolve_scope)) { @@ -227,7 +229,7 @@ void RegisterContextLLDB::InitializeZerothFrame() { return; } - if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) { + if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { // Try the fall back unwind plan since the // full unwind plan failed. FuncUnwindersSP func_unwinders_sp; @@ -255,12 +257,14 @@ void RegisterContextLLDB::InitializeZerothFrame() { m_frame_type = eNotAValidFrame; return; } - } + } else + ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa); UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 " cfa is 0x%" PRIx64 - " using %s UnwindPlan", + " afa is 0x%" PRIx64 " using %s UnwindPlan", (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), (uint64_t)m_cfa, + (uint64_t)m_afa, m_full_unwind_plan_sp->GetSourceName().GetCString()); } @@ -320,7 +324,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { above_trap_handler = true; if (pc == 0 || pc == 0x1) { - if (above_trap_handler == false) { + if (!above_trap_handler) { m_frame_type = eNotAValidFrame; UnwindLogMsg("this frame has a pc of 0x0"); return; @@ -378,7 +382,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { RegisterKind row_register_kind = m_full_unwind_plan_sp->GetRegisterKind(); UnwindPlan::RowSP row = m_full_unwind_plan_sp->GetRowForFunctionOffset(0); if (row.get()) { - if (!ReadCFAValueForRow(row_register_kind, row, m_cfa)) { + if (!ReadFrameAddress(row_register_kind, row->GetCFAValue(), m_cfa)) { UnwindLogMsg("failed to get cfa value"); if (m_frame_type != eSkipFrame) // don't override eSkipFrame { @@ -387,6 +391,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { return; } + ReadFrameAddress(row_register_kind, row->GetAFAValue(), m_afa); + // A couple of sanity checks.. if (m_cfa == LLDB_INVALID_ADDRESS || m_cfa == 0 || m_cfa == 1) { UnwindLogMsg("could not find a valid cfa address"); @@ -419,7 +425,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { } } - UnwindLogMsg("initialized frame cfa is 0x%" PRIx64, (uint64_t)m_cfa); + UnwindLogMsg("initialized frame cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, + (uint64_t)m_cfa, (uint64_t)m_afa); return; } m_frame_type = eNotAValidFrame; @@ -436,7 +443,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { // then we might not find the correct unwind information later. Instead, let // ResolveSymbolContextForAddress fail, and handle the case via // decr_pc_and_recompute_addr_range below. - const uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; + const SymbolContextItem resolve_scope = + eSymbolContextFunction | eSymbolContextSymbol; uint32_t resolved_scope = pc_module_sp->ResolveSymbolContextForAddress( m_current_pc, resolve_scope, m_sym_ctx, resolve_tail_call_address); @@ -466,7 +474,7 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { bool decr_pc_and_recompute_addr_range = false; // If the symbol lookup failed... - if (m_sym_ctx_valid == false) + if (!m_sym_ctx_valid) decr_pc_and_recompute_addr_range = true; // Or if we're in the middle of the stack (and not "above" an asynchronous @@ -494,7 +502,8 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { temporary_pc.SetLoadAddress(pc - 1, &process->GetTarget()); m_sym_ctx.Clear(false); m_sym_ctx_valid = false; - uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; + SymbolContextItem resolve_scope = + eSymbolContextFunction | eSymbolContextSymbol; ModuleSP temporary_module_sp = temporary_pc.GetModule(); if (temporary_module_sp && @@ -581,13 +590,15 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { return; } - if (!ReadCFAValueForRow(row_register_kind, active_row, m_cfa)) { + if (!ReadFrameAddress(row_register_kind, active_row->GetCFAValue(), m_cfa)) { UnwindLogMsg("failed to get cfa"); m_frame_type = eNotAValidFrame; return; } - UnwindLogMsg("m_cfa = 0x%" PRIx64, m_cfa); + ReadFrameAddress(row_register_kind, active_row->GetAFAValue(), m_afa); + + UnwindLogMsg("m_cfa = 0x%" PRIx64 " m_afa = 0x%" PRIx64, m_cfa, m_afa); if (CheckIfLoopingStack()) { TryFallbackUnwindPlan(); @@ -600,9 +611,10 @@ void RegisterContextLLDB::InitializeNonZerothFrame() { } UnwindLogMsg("initialized frame current pc is 0x%" PRIx64 - " cfa is 0x%" PRIx64, + " cfa is 0x%" PRIx64 " afa is 0x%" PRIx64, (uint64_t)m_current_pc.GetLoadAddress(exe_ctx.GetTargetPtr()), - (uint64_t)m_cfa); + (uint64_t)m_cfa, + (uint64_t)m_afa); } bool RegisterContextLLDB::CheckIfLoopingStack() { @@ -1238,7 +1250,7 @@ RegisterContextLLDB::SavedLocationForRegister( // Address register and it hasn't been saved anywhere yet -- that is, // it's still live in the actual register. Handle this specially. - if (have_unwindplan_regloc == false && return_address_reg.IsValid() && + if (!have_unwindplan_regloc && return_address_reg.IsValid() && IsFrameZero()) { if (return_address_reg.GetAsKind(eRegisterKindLLDB) != LLDB_INVALID_REGNUM) { @@ -1311,17 +1323,13 @@ RegisterContextLLDB::SavedLocationForRegister( unwindplan_regloc)) { can_fetch_pc_value = true; } - if (ReadCFAValueForRow(unwindplan_registerkind, active_row, - cfa_value)) { + if (ReadFrameAddress(unwindplan_registerkind, + active_row->GetCFAValue(), cfa_value)) { can_fetch_cfa = true; } } - if (can_fetch_pc_value && can_fetch_cfa) { - have_unwindplan_regloc = true; - } else { - have_unwindplan_regloc = false; - } + have_unwindplan_regloc = can_fetch_pc_value && can_fetch_cfa; } else { // We were unable to fall back to another unwind plan have_unwindplan_regloc = false; @@ -1332,7 +1340,7 @@ RegisterContextLLDB::SavedLocationForRegister( ExecutionContext exe_ctx(m_thread.shared_from_this()); Process *process = exe_ctx.GetProcessPtr(); - if (have_unwindplan_regloc == false) { + if (!have_unwindplan_regloc) { // If the UnwindPlan failed to give us an unwind location for this // register, we may be able to fall back to some ABI-defined default. For // example, some ABIs allow to determine the caller's SP via the CFA. Also, @@ -1351,7 +1359,7 @@ RegisterContextLLDB::SavedLocationForRegister( } } - if (have_unwindplan_regloc == false) { + if (!have_unwindplan_regloc) { if (IsFrameZero()) { // This is frame 0 - we should return the actual live register context // value @@ -1397,7 +1405,7 @@ RegisterContextLLDB::SavedLocationForRegister( } if (unwindplan_regloc.IsSame()) { - if (IsFrameZero() == false && + if (!IsFrameZero() && (regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_PC || regnum.GetAsKind(eRegisterKindGeneric) == LLDB_REGNUM_GENERIC_RA)) { UnwindLogMsg("register %s (%d) is marked as 'IsSame' - it is a pc or " @@ -1441,6 +1449,36 @@ RegisterContextLLDB::SavedLocationForRegister( return UnwindLLDB::RegisterSearchResult::eRegisterFound; } + if (unwindplan_regloc.IsAFAPlusOffset()) { + if (m_afa == LLDB_INVALID_ADDRESS) + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + + int offset = unwindplan_regloc.GetOffset(); + regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred; + regloc.location.inferred_value = m_afa + offset; + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; + UnwindLogMsg("supplying caller's register %s (%d), value is AFA plus " + "offset %d [value is 0x%" PRIx64 "]", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, + regloc.location.inferred_value); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + + if (unwindplan_regloc.IsAtAFAPlusOffset()) { + if (m_afa == LLDB_INVALID_ADDRESS) + return UnwindLLDB::RegisterSearchResult::eRegisterNotFound; + + int offset = unwindplan_regloc.GetOffset(); + regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation; + regloc.location.target_memory_location = m_afa + offset; + m_registers[regnum.GetAsKind(eRegisterKindLLDB)] = regloc; + UnwindLogMsg("supplying caller's register %s (%d) from the stack, saved at " + "AFA plus offset %d [saved at 0x%" PRIx64 "]", + regnum.GetName(), regnum.GetAsKind(eRegisterKindLLDB), offset, + regloc.location.target_memory_location); + return UnwindLLDB::RegisterSearchResult::eRegisterFound; + } + if (unwindplan_regloc.IsInOtherRegister()) { uint32_t unwindplan_regnum = unwindplan_regloc.GetRegisterNumber(); RegisterNumber row_regnum(m_thread, unwindplan_registerkind, @@ -1555,7 +1593,6 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { addr_t old_caller_pc_value = LLDB_INVALID_ADDRESS; addr_t new_caller_pc_value = LLDB_INVALID_ADDRESS; - addr_t old_this_frame_cfa_value = m_cfa; UnwindLLDB::RegisterLocation regloc; if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), regloc) == @@ -1585,6 +1622,7 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { // the value of the m_cfa ivar. Save is down below a bit in 'old_cfa'. UnwindPlanSP original_full_unwind_plan_sp = m_full_unwind_plan_sp; addr_t old_cfa = m_cfa; + addr_t old_afa = m_afa; m_registers.clear(); @@ -1595,19 +1633,21 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { if (active_row && active_row->GetCFAValue().GetValueType() != - UnwindPlan::Row::CFAValue::unspecified) { + UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; - if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row, new_cfa) || + if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), + active_row->GetCFAValue(), new_cfa) || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { UnwindLogMsg("failed to get cfa with fallback unwindplan"); m_fallback_unwind_plan_sp.reset(); m_full_unwind_plan_sp = original_full_unwind_plan_sp; - m_cfa = old_cfa; return false; } m_cfa = new_cfa; + ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), + active_row->GetAFAValue(), m_afa); + if (SavedLocationForRegister(pc_regnum.GetAsKind(eRegisterKindLLDB), regloc) == UnwindLLDB::RegisterSearchResult::eRegisterFound) { @@ -1628,19 +1668,18 @@ bool RegisterContextLLDB::TryFallbackUnwindPlan() { m_fallback_unwind_plan_sp.reset(); m_full_unwind_plan_sp = original_full_unwind_plan_sp; m_cfa = old_cfa; + m_afa = old_afa; return false; } - if (old_caller_pc_value != LLDB_INVALID_ADDRESS) { - if (old_caller_pc_value == new_caller_pc_value && - new_cfa == old_this_frame_cfa_value) { - UnwindLogMsg("fallback unwind plan got the same values for this frame " - "CFA and caller frame pc, not using"); - m_fallback_unwind_plan_sp.reset(); - m_full_unwind_plan_sp = original_full_unwind_plan_sp; - m_cfa = old_cfa; - return false; - } + if (old_caller_pc_value == new_caller_pc_value && + m_cfa == old_cfa && + m_afa == old_afa) { + UnwindLogMsg("fallback unwind plan got the same values for this frame " + "CFA and caller frame pc, not using"); + m_fallback_unwind_plan_sp.reset(); + m_full_unwind_plan_sp = original_full_unwind_plan_sp; + return false; } UnwindLogMsg("trying to unwind from this function with the UnwindPlan '%s' " @@ -1674,16 +1713,19 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() { if (active_row && active_row->GetCFAValue().GetValueType() != - UnwindPlan::Row::CFAValue::unspecified) { + UnwindPlan::Row::FAValue::unspecified) { addr_t new_cfa; - if (!ReadCFAValueForRow(m_fallback_unwind_plan_sp->GetRegisterKind(), - active_row, new_cfa) || + if (!ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), + active_row->GetCFAValue(), new_cfa) || new_cfa == 0 || new_cfa == 1 || new_cfa == LLDB_INVALID_ADDRESS) { UnwindLogMsg("failed to get cfa with fallback unwindplan"); m_fallback_unwind_plan_sp.reset(); return false; } + ReadFrameAddress(m_fallback_unwind_plan_sp->GetRegisterKind(), + active_row->GetAFAValue(), m_afa); + m_full_unwind_plan_sp = m_fallback_unwind_plan_sp; m_fallback_unwind_plan_sp.reset(); @@ -1698,18 +1740,18 @@ bool RegisterContextLLDB::ForceSwitchToFallbackUnwindPlan() { return false; } -bool RegisterContextLLDB::ReadCFAValueForRow( - lldb::RegisterKind row_register_kind, const UnwindPlan::RowSP &row, - addr_t &cfa_value) { +bool RegisterContextLLDB::ReadFrameAddress( + lldb::RegisterKind row_register_kind, UnwindPlan::Row::FAValue &fa, + addr_t &address) { RegisterValue reg_value; - cfa_value = LLDB_INVALID_ADDRESS; + address = LLDB_INVALID_ADDRESS; addr_t cfa_reg_contents; - switch (row->GetCFAValue().GetValueType()) { - case UnwindPlan::Row::CFAValue::isRegisterDereferenced: { + switch (fa.GetValueType()) { + case UnwindPlan::Row::FAValue::isRegisterDereferenced: { RegisterNumber cfa_reg(m_thread, row_register_kind, - row->GetCFAValue().GetRegisterNumber()); + fa.GetRegisterNumber()); if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { const RegisterInfo *reg_info = GetRegisterInfoAtIndex(cfa_reg.GetAsKind(eRegisterKindLLDB)); @@ -1718,12 +1760,12 @@ bool RegisterContextLLDB::ReadCFAValueForRow( Status error = ReadRegisterValueFromMemory( reg_info, cfa_reg_contents, reg_info->byte_size, reg_value); if (error.Success()) { - cfa_value = reg_value.GetAsUInt64(); + address = reg_value.GetAsUInt64(); UnwindLogMsg( "CFA value via dereferencing reg %s (%d): reg has val 0x%" PRIx64 ", CFA value is 0x%" PRIx64, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), - cfa_reg_contents, cfa_value); + cfa_reg_contents, address); return true; } else { UnwindLogMsg("Tried to deref reg %s (%d) [0x%" PRIx64 @@ -1735,9 +1777,9 @@ bool RegisterContextLLDB::ReadCFAValueForRow( } break; } - case UnwindPlan::Row::CFAValue::isRegisterPlusOffset: { + case UnwindPlan::Row::FAValue::isRegisterPlusOffset: { RegisterNumber cfa_reg(m_thread, row_register_kind, - row->GetCFAValue().GetRegisterNumber()); + fa.GetRegisterNumber()); if (ReadGPRValue(cfa_reg, cfa_reg_contents)) { if (cfa_reg_contents == LLDB_INVALID_ADDRESS || cfa_reg_contents == 0 || cfa_reg_contents == 1) { @@ -1748,35 +1790,35 @@ bool RegisterContextLLDB::ReadCFAValueForRow( cfa_reg_contents = LLDB_INVALID_ADDRESS; return false; } - cfa_value = cfa_reg_contents + row->GetCFAValue().GetOffset(); + address = cfa_reg_contents + fa.GetOffset(); UnwindLogMsg( "CFA is 0x%" PRIx64 ": Register %s (%d) contents are 0x%" PRIx64 ", offset is %d", - cfa_value, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), - cfa_reg_contents, row->GetCFAValue().GetOffset()); + address, cfa_reg.GetName(), cfa_reg.GetAsKind(eRegisterKindLLDB), + cfa_reg_contents, fa.GetOffset()); return true; } break; } - case UnwindPlan::Row::CFAValue::isDWARFExpression: { + case UnwindPlan::Row::FAValue::isDWARFExpression: { ExecutionContext exe_ctx(m_thread.shared_from_this()); Process *process = exe_ctx.GetProcessPtr(); - DataExtractor dwarfdata(row->GetCFAValue().GetDWARFExpressionBytes(), - row->GetCFAValue().GetDWARFExpressionLength(), + DataExtractor dwarfdata(fa.GetDWARFExpressionBytes(), + fa.GetDWARFExpressionLength(), process->GetByteOrder(), process->GetAddressByteSize()); ModuleSP opcode_ctx; DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr, 0, - row->GetCFAValue().GetDWARFExpressionLength()); + fa.GetDWARFExpressionLength()); dwarfexpr.SetRegisterKind(row_register_kind); Value result; Status error; if (dwarfexpr.Evaluate(&exe_ctx, this, 0, nullptr, nullptr, result, &error)) { - cfa_value = result.GetScalar().ULongLong(); + address = result.GetScalar().ULongLong(); UnwindLogMsg("CFA value set by DWARF expression is 0x%" PRIx64, - cfa_value); + address); return true; } UnwindLogMsg("Failed to set CFA value via DWARF expression: %s", @@ -2005,12 +2047,8 @@ bool RegisterContextLLDB::ReadPC(addr_t &pc) { pc = abi->FixCodeAddress(pc); } - if (m_all_registers_available == false && above_trap_handler == false && - (pc == 0 || pc == 1)) { - return false; - } - - return true; + return !(m_all_registers_available == false && + above_trap_handler == false && (pc == 0 || pc == 1)); } else { return false; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h index 7e9e77dcf06d..50f12c6f8541 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h @@ -11,12 +11,8 @@ #ifndef lldb_RegisterContextLLDB_h_ #define lldb_RegisterContextLLDB_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "UnwindLLDB.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/UnwindPlan.h" @@ -192,9 +188,9 @@ private: bool ReadGPRValue(const RegisterNumber ®_num, lldb::addr_t &value); - // Get the CFA register for a given frame. - bool ReadCFAValueForRow(lldb::RegisterKind register_kind, - const UnwindPlan::RowSP &row, lldb::addr_t &value); + // Get the Frame Address register for a given frame. + bool ReadFrameAddress(lldb::RegisterKind register_kind, + UnwindPlan::Row::FAValue &fa, lldb::addr_t &address); lldb::UnwindPlanSP GetFastUnwindPlanForFrame(); @@ -225,6 +221,7 @@ private: int m_frame_type; // enum FrameType lldb::addr_t m_cfa; + lldb::addr_t m_afa; lldb_private::Address m_start_pc; lldb_private::Address m_current_pc; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp index 77c1bea34851..c0a6084cd723 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp @@ -9,16 +9,12 @@ #include "RegisterContextMacOSXFrameBackchain.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" -// Project includes #include "lldb/Utility/StringExtractorGDBRemote.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h index 4f5816aa4909..69e23c2782fd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h @@ -10,10 +10,6 @@ #ifndef lldb_RegisterContextMacOSXFrameBackchain_h_ #define lldb_RegisterContextMacOSXFrameBackchain_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp index 71d35bbd3938..69522ace1a68 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.cpp @@ -11,13 +11,9 @@ #include "RegisterContextMach_arm.h" -// C Includes #include #include -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h index a2cf6bfcbe4a..5ea47f214e25 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_arm.h @@ -10,11 +10,7 @@ #ifndef liblldb_RegisterContextMach_arm_h_ #define liblldb_RegisterContextMach_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextDarwin_arm.h" class RegisterContextMach_arm : public RegisterContextDarwin_arm { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp index 5a260d5de1d5..94138605239e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.cpp @@ -9,12 +9,8 @@ #if defined(__APPLE__) -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextMach_i386.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h index 8ac693a55584..a7e29e96b267 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_i386.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextMach_i386_h_ #define liblldb_RegisterContextMach_i386_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextDarwin_i386.h" class RegisterContextMach_i386 : public RegisterContextDarwin_i386 { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp index 0180879d51ee..e523b95ee974 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.cpp @@ -9,12 +9,8 @@ #if defined(__APPLE__) -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextMach_x86_64.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h index cd425046b08e..c73bdda79713 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMach_x86_64.h @@ -11,10 +11,6 @@ #ifndef liblldb_RegisterContextMach_x86_64_h_ #define liblldb_RegisterContextMach_x86_64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContextDarwin_x86_64.h" class RegisterContextMach_x86_64 : public RegisterContextDarwin_x86_64 { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp index 76189ea781de..f05c07f6c8e1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.cpp @@ -9,15 +9,11 @@ #include "RegisterContextMemory.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "DynamicRegisterInfo.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/Utility/Status.h" using namespace lldb; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h index cad1592af5ba..cdf2a5446e1e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextMemory.h @@ -10,12 +10,8 @@ #ifndef lldb_RegisterContextMemory_h_ #define lldb_RegisterContextMemory_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp index 352e251e3b64..b0e53cfcc91f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_arm.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h index 8c5fe9d2c2de..4b5a8fe95a4f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_arm_h_ #define liblldb_RegisterContextPOSIX_arm_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterInfoInterface.h" #include "lldb-arm-register-enums.h" #include "lldb/Target/RegisterContext.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp index 3ff93cde2347..8b00dfc81eab 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_arm64.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h index 27251da2a9af..603c12d830d9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_arm64_h_ #define liblldb_RegisterContextPOSIX_arm64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterInfoInterface.h" #include "lldb-arm64-register-enums.h" #include "lldb/Target/RegisterContext.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp index 98d1e6fa8817..9270d09f7293 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_mips64.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h index 1695ec9a0bab..09cfd42b9c51 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_mips64.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_mips64_h_ #define liblldb_RegisterContextPOSIX_mips64_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContext_mips.h" #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp index 9f0552539723..47a8e2c3f9e9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.cpp @@ -12,14 +12,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_powerpc.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h index 50f234680ca0..3260cb1ce8bc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_powerpc.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_powerpc_h_ #define liblldb_RegisterContextPOSIX_powerpc_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContext_powerpc.h" #include "RegisterInfoInterface.h" #include "lldb/Target/RegisterContext.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp index 41ae5ec6b51a..ef221c963dc4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_ppc64le.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h index 1070b4dea405..9159819f17c4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_ppc64le_h_ #define liblldb_RegisterContextPOSIX_ppc64le_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "RegisterInfoInterface.h" #include "Utility/PPC64LE_DWARF_Registers.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp index 662ac38405ef..24f131099be4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_s390x.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h index d5337630c32d..7a7b6bddd6aa 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_s390x.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_s390x_h_ #define liblldb_RegisterContextPOSIX_s390x_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContext_s390x.h" #include "RegisterInfoInterface.h" #include "lldb-s390x-register-enums.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp index d2a06e1b7897..78f561a0f04f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.cpp @@ -11,14 +11,14 @@ #include #include -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "llvm/Support/Compiler.h" #include "RegisterContextPOSIX_x86.h" @@ -376,7 +376,7 @@ RegisterContextPOSIX_x86::FPRType RegisterContextPOSIX_x86::GetFPRType() { if (m_fpr_type == eNotValid) { // TODO: Use assembly to call cpuid on the inferior and query ebx or ecx m_fpr_type = eXSAVE; // extended floating-point registers, if available - if (false == ReadFPR()) + if (!ReadFPR()) m_fpr_type = eFXSAVE; // assume generic floating-point registers } return m_fpr_type; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h index ca71a6f272f8..b6db45e55bbf 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_x86.h @@ -10,10 +10,6 @@ #ifndef liblldb_RegisterContextPOSIX_x86_h_ #define liblldb_RegisterContextPOSIX_x86_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "RegisterContext_x86.h" #include "RegisterInfoInterface.h" #include "lldb-x86-register-enums.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h index 3b3b0856a4ca..0d50c73a31a9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextThreadMemory.h @@ -10,12 +10,8 @@ #ifndef lldb_RegisterContextThreadMemory_h_ #define lldb_RegisterContextThreadMemory_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/SymbolContext.h" #include "lldb/Target/RegisterContext.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h index 6146dcaf7e5a..e3ff492d707a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContext_x86.h @@ -341,7 +341,7 @@ LLVM_PACKED_END // x86 extensions to FXSAVE (i.e. for AVX and MPX processors) LLVM_PACKED_START -struct LLVM_ALIGNAS(64) XSAVE { +struct LLVM_ALIGNAS(16) XSAVE { FXSAVE i387; // floating point registers typical in i387_fxsave_struct XSAVE_HDR header; // The xsave_hdr_struct can be used to determine if the // following extensions are usable diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h index 74d3226c8a52..ec951ea8a391 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_arm.h @@ -9,12 +9,8 @@ #ifdef DECLARE_REGISTER_INFOS_ARM_STRUCT -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h index b996533791ff..039d98ecdd2d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_arm64.h @@ -9,12 +9,8 @@ #ifdef DECLARE_REGISTER_INFOS_ARM64_STRUCT -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/lldb-defines.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h index ffdc4d0d116b..f8947876d15f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_i386.h @@ -11,7 +11,6 @@ #include #include -// Project includes #ifdef DECLARE_REGISTER_INFOS_I386_STRUCT diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h index b116b99b3f81..36483c068d26 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_mips.h @@ -7,15 +7,11 @@ // //===---------------------------------------------------------------------===// -// C Includes #include -// C++ Includes -// Other libraries and framework includes #include "lldb/Core/dwarf.h" #include "llvm/Support/Compiler.h" -// Project includes #ifdef DECLARE_REGISTER_INFOS_MIPS_STRUCT diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h index 3c3912fa6978..0194074f34f2 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_mips64.h @@ -7,15 +7,11 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes -// Other libraries and framework includes #include "lldb/Core/dwarf.h" #include "llvm/Support/Compiler.h" -// Project includes #ifdef DECLARE_REGISTER_INFOS_MIPS64_STRUCT diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h index 69f00e4ba885..dbd87ad71a45 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64.h @@ -9,7 +9,6 @@ #ifdef DECLARE_REGISTER_INFOS_PPC64_STRUCT -// C Includes #include // Computes the offset of the given GPR_PPC64 in the user data area. diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h index bffa7a1d8b63..e6fa17b60758 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_ppc64le.h @@ -9,7 +9,6 @@ #ifdef DECLARE_REGISTER_INFOS_PPC64LE_STRUCT -// C Includes #include // Computes the offset of the given GPR in the user data area. diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h index 0bbf422405ee..b750be4116a5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterInfos_s390x.h @@ -7,14 +7,10 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes -// Other libraries and framework includes #include "llvm/Support/Compiler.h" -// Project includes #ifdef DECLARE_REGISTER_INFOS_S390X_STRUCT diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp index 3dbfe611e713..de0821eb4253 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.cpp @@ -9,10 +9,12 @@ #include "StopInfoMachException.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes + +#if defined(__APPLE__) +// Needed for the EXC_RESOURCE interpretation macros +#include +#endif + #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/DynamicLoader.h" @@ -41,6 +43,12 @@ const char *StopInfoMachException::GetDescription() { const char *code_desc = NULL; const char *subcode_label = "subcode"; const char *subcode_desc = NULL; + +#if defined(__APPLE__) + char code_desc_buf[32]; + char subcode_desc_buf[32]; +#endif + switch (m_value) { case 1: // EXC_BAD_ACCESS exc_desc = "EXC_BAD_ACCESS"; @@ -275,6 +283,47 @@ const char *StopInfoMachException::GetDescription() { break; case 11: exc_desc = "EXC_RESOURCE"; +#if defined(__APPLE__) + { + int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code); + + code_label = "limit"; + code_desc = code_desc_buf; + subcode_label = "observed"; + subcode_desc = subcode_desc_buf; + + switch (resource_type) { + case RESOURCE_TYPE_CPU: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(m_exc_subcode)); + break; + case RESOURCE_TYPE_WAKEUPS: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d w/s", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s", + (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(m_exc_subcode)); + break; + case RESOURCE_TYPE_MEMORY: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", + (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code)); + subcode_desc = nullptr; + subcode_label = "unused"; + break; + case RESOURCE_TYPE_IO: + exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO"; + snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB", + (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code)); + snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB", + (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));; + break; + } + } +#endif break; case 12: exc_desc = "EXC_GUARD"; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.h index 94516454105e..027ed80e8a98 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/StopInfoMachException.h @@ -10,12 +10,8 @@ #ifndef liblldb_StopInfoMachException_h_ #define liblldb_StopInfoMachException_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/StopInfo.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ThreadMemory.h index 89229710da4d..c966ca03a017 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ThreadMemory.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/ThreadMemory.h @@ -10,12 +10,8 @@ #ifndef liblldb_ThreadMemory_h_ #define liblldb_ThreadMemory_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" class ThreadMemory : public lldb_private::Thread { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp index 55559f07f1e5..b34c87230bd1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp @@ -130,6 +130,8 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB( m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this)); + uint64_t max_stack_depth = m_thread.GetMaxBacktraceDepth(); + // We want to detect an unwind that cycles erroneously and stop backtracing. // Don't want this maximum unwind limit to be too low -- if you have a // backtrace with an "infinitely recursing" bug, it will crash when the stack @@ -138,7 +140,7 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { // unwind at 10,000 or something. Realistically anything over around 200,000 // is going to blow out the stack space. If we're still unwinding at that // point, we're probably never going to finish. - if (cur_idx > 300000) { + if (cur_idx >= max_stack_depth) { if (log) log->Printf("%*sFrame %d unwound too many frames, assuming unwind has " "gone astray, stopping.", @@ -210,15 +212,15 @@ UnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) { // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not // have its (constructed) CFA aligned correctly -- don't do the abi // alignment check for these. - if (reg_ctx_sp->IsTrapHandlerFrame() == false) { + if (!reg_ctx_sp->IsTrapHandlerFrame()) { // See if we can find a fallback unwind plan for THIS frame. It may be // that the UnwindPlan we're using for THIS frame was bad and gave us a // bad CFA. If that's not it, then see if we can change the UnwindPlan // for the frame below us ("NEXT") -- see if using that other UnwindPlan // gets us a better unwind state. - if (reg_ctx_sp->TryFallbackUnwindPlan() == false || - reg_ctx_sp->GetCFA(cursor_sp->cfa) == false || - abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) { + if (!reg_ctx_sp->TryFallbackUnwindPlan() || + !reg_ctx_sp->GetCFA(cursor_sp->cfa) || + !abi->CallFrameAddressIsValid(cursor_sp->cfa)) { if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) { // TryFallbackUnwindPlan for prev_frame succeeded and updated // reg_ctx_lldb_sp field of prev_frame. However, cfa field of @@ -383,10 +385,8 @@ bool UnwindLLDB::AddOneMoreFrame(ABI *abi) { // Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was already // updated during TryFallbackUnwindPlan call above. However, cfa field // still needs to be updated. Hence updating it here and then returning. - if (!(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( - m_frames[m_frames.size() - 2]->cfa))) - return false; - return true; + return m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA( + m_frames[m_frames.size() - 2]->cfa); } // The new frame hasn't helped in unwinding. Fall back to the original one as @@ -468,10 +468,7 @@ bool UnwindLLDB::SearchForSavedLocationForRegister( UnwindLLDB::RegisterSearchResult result; result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister( lldb_regnum, regloc); - if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound) - return true; - else - return false; + return result == UnwindLLDB::RegisterSearchResult::eRegisterFound; } while (frame_num >= 0) { UnwindLLDB::RegisterSearchResult result; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h index 3d1f85a3dec3..aec7b66d9354 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindLLDB.h @@ -10,12 +10,8 @@ #ifndef lldb_UnwindLLDB_h_ #define lldb_UnwindLLDB_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/FuncUnwinders.h" #include "lldb/Symbol/SymbolContext.h" #include "lldb/Symbol/UnwindPlan.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp index 2115b4e179c0..ae0b9fb0a526 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp @@ -114,7 +114,7 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_i386( if (!m_cursors.empty()) { lldb::addr_t first_frame_pc = m_cursors.front().pc; if (first_frame_pc != LLDB_INVALID_ADDRESS) { - const uint32_t resolve_scope = + const SymbolContextItem resolve_scope = eSymbolContextModule | eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextSymbol; @@ -205,7 +205,7 @@ size_t UnwindMacOSXFrameBackchain::GetStackFrameData_x86_64( if (!m_cursors.empty()) { lldb::addr_t first_frame_pc = m_cursors.front().pc; if (first_frame_pc != LLDB_INVALID_ADDRESS) { - const uint32_t resolve_scope = + const SymbolContextItem resolve_scope = eSymbolContextModule | eSymbolContextCompUnit | eSymbolContextFunction | eSymbolContextSymbol; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h index 328117a306ef..9ee0b08ca09a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h @@ -10,12 +10,8 @@ #ifndef lldb_UnwindMacOSXFrameBackchain_h_ #define lldb_UnwindMacOSXFrameBackchain_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Unwind.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index 7bb7b72eaac1..7d66461c15bc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -7,25 +7,21 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes #include -// Other libraries and framework includes #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/Support/Threading.h" @@ -61,8 +57,8 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp, // the header extension. const size_t header_size = sizeof(llvm::ELF::Elf64_Ehdr); - auto data_sp = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), - header_size, 0); + auto data_sp = FileSystem::Instance().CreateDataBuffer( + crash_file->GetPath(), header_size, 0); if (data_sp && data_sp->GetByteSize() == header_size && elf::ELFHeader::MagicBytesMatch(data_sp->GetBytes())) { elf::ELFHeader elf_header; @@ -81,7 +77,7 @@ lldb::ProcessSP ProcessElfCore::CreateInstance(lldb::TargetSP target_sp, bool ProcessElfCore::CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) { // For now we are just making sure the file exists for a given module - if (!m_core_module_sp && m_core_file.Exists()) { + if (!m_core_module_sp && FileSystem::Instance().Exists(m_core_file)) { ModuleSpec core_module_spec(m_core_file, target_sp->GetArchitecture()); Status error(ModuleList::GetSharedModule(core_module_spec, m_core_module_sp, NULL, NULL, NULL)); @@ -122,10 +118,10 @@ ConstString ProcessElfCore::GetPluginName() { return GetPluginNameStatic(); } uint32_t ProcessElfCore::GetPluginVersion() { return 1; } lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment( - const elf::ELFProgramHeader *header) { - const lldb::addr_t addr = header->p_vaddr; - FileRange file_range(header->p_offset, header->p_filesz); - VMRangeToFileOffset::Entry range_entry(addr, header->p_memsz, file_range); + const elf::ELFProgramHeader &header) { + const lldb::addr_t addr = header.p_vaddr; + FileRange file_range(header.p_offset, header.p_filesz); + VMRangeToFileOffset::Entry range_entry(addr, header.p_memsz, file_range); VMRangeToFileOffset::Entry *last_entry = m_core_aranges.Back(); if (last_entry && last_entry->GetRangeEnd() == range_entry.GetRangeBase() && @@ -140,12 +136,12 @@ lldb::addr_t ProcessElfCore::AddAddressRangeFromLoadSegment( // Keep a separate map of permissions that that isn't coalesced so all ranges // are maintained. const uint32_t permissions = - ((header->p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) | - ((header->p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) | - ((header->p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u); + ((header.p_flags & llvm::ELF::PF_R) ? lldb::ePermissionsReadable : 0u) | + ((header.p_flags & llvm::ELF::PF_W) ? lldb::ePermissionsWritable : 0u) | + ((header.p_flags & llvm::ELF::PF_X) ? lldb::ePermissionsExecutable : 0u); m_core_range_infos.Append( - VMRangeToPermissions::Entry(addr, header->p_memsz, permissions)); + VMRangeToPermissions::Entry(addr, header.p_memsz, permissions)); return addr; } @@ -166,8 +162,8 @@ Status ProcessElfCore::DoLoadCore() { return error; } - const uint32_t num_segments = core->GetProgramHeaderCount(); - if (num_segments == 0) { + llvm::ArrayRef segments = core->ProgramHeaders(); + if (segments.size() == 0) { error.SetErrorString("core file has no segments"); return error; } @@ -181,20 +177,17 @@ Status ProcessElfCore::DoLoadCore() { /// Walk through segments and Thread and Address Map information. /// PT_NOTE - Contains Thread and Register information /// PT_LOAD - Contains a contiguous range of Process Address Space - for (uint32_t i = 1; i <= num_segments; i++) { - const elf::ELFProgramHeader *header = core->GetProgramHeaderByIndex(i); - assert(header != NULL); - - DataExtractor data = core->GetSegmentDataByIndex(i); + for (const elf::ELFProgramHeader &H : segments) { + DataExtractor data = core->GetSegmentData(H); // Parse thread contexts and auxv structure - if (header->p_type == llvm::ELF::PT_NOTE) { - if (llvm::Error error = ParseThreadContextsFromNoteSegment(header, data)) + if (H.p_type == llvm::ELF::PT_NOTE) { + if (llvm::Error error = ParseThreadContextsFromNoteSegment(H, data)) return Status(std::move(error)); } // PT_LOAD segments contains address map - if (header->p_type == llvm::ELF::PT_LOAD) { - lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(header); + if (H.p_type == llvm::ELF::PT_LOAD) { + lldb::addr_t last_addr = AddAddressRangeFromLoadSegment(H); if (vm_addr > last_addr) ranges_are_sorted = false; vm_addr = last_addr; @@ -249,12 +242,11 @@ Status ProcessElfCore::DoLoadCore() { ModuleSpec exe_module_spec; exe_module_spec.GetArchitecture() = arch; exe_module_spec.GetFileSpec().SetFile( - m_nt_file_entries[0].path.GetCString(), false, - FileSpec::Style::native); + m_nt_file_entries[0].path.GetCString(), FileSpec::Style::native); if (exe_module_spec.GetFileSpec()) { exe_module_sp = GetTarget().GetSharedModule(exe_module_spec); if (exe_module_sp) - GetTarget().SetExecutableModule(exe_module_sp, false); + GetTarget().SetExecutableModule(exe_module_sp, eLoadDependentsNo); } } } @@ -715,8 +707,8 @@ llvm::Error ProcessElfCore::parseLinuxNotes(llvm::ArrayRef notes) { /// A note segment consists of one or more NOTE entries, but their types and /// meaning differ depending on the OS. llvm::Error ProcessElfCore::ParseThreadContextsFromNoteSegment( - const elf::ELFProgramHeader *segment_header, DataExtractor segment_data) { - assert(segment_header && segment_header->p_type == llvm::ELF::PT_NOTE); + const elf::ELFProgramHeader &segment_header, DataExtractor segment_data) { + assert(segment_header.p_type == llvm::ELF::PT_NOTE); auto notes_or_error = parseSegment(segment_data); if(!notes_or_error) @@ -744,8 +736,7 @@ uint32_t ProcessElfCore::GetNumThreadContexts() { } ArchSpec ProcessElfCore::GetArchitecture() { - ArchSpec arch; - m_core_module_sp->GetObjectFile()->GetArchitecture(arch); + ArchSpec arch = m_core_module_sp->GetObjectFile()->GetArchitecture(); ArchSpec target_arch = GetTarget().GetArchitecture(); arch.MergeFrom(target_arch); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h index 325c0152e028..2c7268662fef 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/ProcessElfCore.h @@ -17,13 +17,9 @@ #ifndef liblldb_ProcessElfCore_h_ #define liblldb_ProcessElfCore_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" @@ -140,7 +136,7 @@ private: // For ProcessElfCore only //------------------------------------------------------------------ typedef lldb_private::Range FileRange; - typedef lldb_private::RangeDataArray + typedef lldb_private::RangeDataVector VMRangeToFileOffset; typedef lldb_private::RangeDataVector VMRangeToPermissions; @@ -170,7 +166,7 @@ private: // Parse thread(s) data structures(prstatus, prpsinfo) from given NOTE segment llvm::Error ParseThreadContextsFromNoteSegment( - const elf::ELFProgramHeader *segment_header, + const elf::ELFProgramHeader &segment_header, lldb_private::DataExtractor segment_data); // Returns number of thread contexts stored in the core file @@ -178,7 +174,7 @@ private: // Parse a contiguous address range of the process from LOAD segment lldb::addr_t - AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader *header); + AddAddressRangeFromLoadSegment(const elf::ELFProgramHeader &header); llvm::Expected> parseSegment(const lldb_private::DataExtractor &segment); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp index 0d683153d9ed..80c6c0207a1e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_arm.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp index 919f8901d39a..017646b44b5c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_arm64.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp index 532a1f5c0831..beeb9b666ccd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_mips64.cpp @@ -9,8 +9,8 @@ #include "RegisterContextPOSIXCore_mips64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp index 8670e341a277..d4f86b354784 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_powerpc.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_powerpc.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp index 2237e72353ac..8116a1c7ea57 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_ppc64le.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h" #include "Plugins/Process/elf-core/RegisterUtilities.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp index f0edbf1ea854..875bb1647281 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_s390x.cpp @@ -9,9 +9,9 @@ #include "RegisterContextPOSIXCore_s390x.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataBufferHeap.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp index a1f26d52444b..27295492f43d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.cpp @@ -8,9 +8,9 @@ //===----------------------------------------------------------------------===// #include "RegisterContextPOSIXCore_x86_64.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp index 4e20b56fb111..a3a4aa053261 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp @@ -379,7 +379,7 @@ void GDBRemoteClientBase::Lock::SyncWithContinueThread(bool interrupt) { log->PutCString("GDBRemoteClientBase::Lock::Lock sent packet: \\x03"); m_comm.m_interrupt_time = steady_clock::now(); } - m_comm.m_cv.wait(lock, [this] { return m_comm.m_is_running == false; }); + m_comm.m_cv.wait(lock, [this] { return !m_comm.m_is_running; }); m_did_interrupt = true; } m_acquired = true; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp index c335b6002861..72c1314a7c94 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp @@ -9,21 +9,22 @@ #include "GDBRemoteCommunication.h" -// C Includes +#include #include #include #include -// C++ Includes -// Other libraries and framework includes #include "lldb/Core/StreamFile.h" #include "lldb/Host/ConnectionFileDescriptor.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/Socket.h" #include "lldb/Host/StringConvert.h" #include "lldb/Host/ThreadLauncher.h" +#include "lldb/Host/common/TCPSocket.h" +#include "lldb/Host/posix/ConnectionFileDescriptorPosix.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Utility/FileSpec.h" @@ -33,7 +34,6 @@ #include "llvm/ADT/SmallString.h" #include "llvm/Support/ScopedPrinter.h" -// Project includes #include "ProcessGDBRemoteLog.h" #if defined(__APPLE__) @@ -42,7 +42,8 @@ #define DEBUGSERVER_BASENAME "lldb-server" #endif -#if defined(HAVE_LIBCOMPRESSION) +#if defined(__APPLE__) +#define HAVE_LIBCOMPRESSION #include #endif @@ -54,78 +55,6 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; -GDBRemoteCommunication::History::History(uint32_t size) - : m_packets(), m_curr_idx(0), m_total_packet_count(0), - m_dumped_to_log(false) { - m_packets.resize(size); -} - -GDBRemoteCommunication::History::~History() {} - -void GDBRemoteCommunication::History::AddPacket(char packet_char, - PacketType type, - uint32_t bytes_transmitted) { - const size_t size = m_packets.size(); - if (size > 0) { - const uint32_t idx = GetNextIndex(); - m_packets[idx].packet.assign(1, packet_char); - m_packets[idx].type = type; - m_packets[idx].bytes_transmitted = bytes_transmitted; - m_packets[idx].packet_idx = m_total_packet_count; - m_packets[idx].tid = llvm::get_threadid(); - } -} - -void GDBRemoteCommunication::History::AddPacket(const std::string &src, - uint32_t src_len, - PacketType type, - uint32_t bytes_transmitted) { - const size_t size = m_packets.size(); - if (size > 0) { - const uint32_t idx = GetNextIndex(); - m_packets[idx].packet.assign(src, 0, src_len); - m_packets[idx].type = type; - m_packets[idx].bytes_transmitted = bytes_transmitted; - m_packets[idx].packet_idx = m_total_packet_count; - m_packets[idx].tid = llvm::get_threadid(); - } -} - -void GDBRemoteCommunication::History::Dump(Stream &strm) const { - const uint32_t size = GetNumPacketsInHistory(); - const uint32_t first_idx = GetFirstSavedPacketIndex(); - const uint32_t stop_idx = m_curr_idx + size; - for (uint32_t i = first_idx; i < stop_idx; ++i) { - const uint32_t idx = NormalizeIndex(i); - const Entry &entry = m_packets[idx]; - if (entry.type == ePacketTypeInvalid || entry.packet.empty()) - break; - strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", - entry.packet_idx, entry.tid, entry.bytes_transmitted, - (entry.type == ePacketTypeSend) ? "send" : "read", - entry.packet.c_str()); - } -} - -void GDBRemoteCommunication::History::Dump(Log *log) const { - if (log && !m_dumped_to_log) { - m_dumped_to_log = true; - const uint32_t size = GetNumPacketsInHistory(); - const uint32_t first_idx = GetFirstSavedPacketIndex(); - const uint32_t stop_idx = m_curr_idx + size; - for (uint32_t i = first_idx; i < stop_idx; ++i) { - const uint32_t idx = NormalizeIndex(i); - const Entry &entry = m_packets[idx]; - if (entry.type == ePacketTypeInvalid || entry.packet.empty()) - break; - log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", - entry.packet_idx, entry.tid, entry.bytes_transmitted, - (entry.type == ePacketTypeSend) ? "send" : "read", - entry.packet.c_str()); - } - } -} - //---------------------------------------------------------------------- // GDBRemoteCommunication constructor //---------------------------------------------------------------------- @@ -139,7 +68,10 @@ GDBRemoteCommunication::GDBRemoteCommunication(const char *comm_name, #endif m_echo_number(0), m_supports_qEcho(eLazyBoolCalculate), m_history(512), m_send_acks(true), m_compression_type(CompressionType::None), - m_listen_url() { + m_listen_url(), m_decompression_scratch_type(CompressionType::None), + m_decompression_scratch(nullptr) { + // Unused unless HAVE_LIBCOMPRESSION is defined. + (void)m_decompression_scratch_type; } //---------------------------------------------------------------------- @@ -150,6 +82,9 @@ GDBRemoteCommunication::~GDBRemoteCommunication() { Disconnect(); } + if (m_decompression_scratch) + free (m_decompression_scratch); + // Stop the communications read thread which is used to parse all incoming // packets. This function will block until the read thread returns. if (m_read_thread_enabled) @@ -172,7 +107,8 @@ size_t GDBRemoteCommunication::SendAck() { const size_t bytes_written = Write(&ch, 1, status, NULL); if (log) log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); - m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written); + m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend, + bytes_written); return bytes_written; } @@ -183,26 +119,31 @@ size_t GDBRemoteCommunication::SendNack() { const size_t bytes_written = Write(&ch, 1, status, NULL); if (log) log->Printf("<%4" PRIu64 "> send packet: %c", (uint64_t)bytes_written, ch); - m_history.AddPacket(ch, History::ePacketTypeSend, bytes_written); + m_history.AddPacket(ch, GDBRemoteCommunicationHistory::ePacketTypeSend, + bytes_written); return bytes_written; } GDBRemoteCommunication::PacketResult GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) { - if (IsConnected()) { StreamString packet(0, 4, eByteOrderBig); - packet.PutChar('$'); packet.Write(payload.data(), payload.size()); packet.PutChar('#'); packet.PutHex8(CalculcateChecksum(payload)); + std::string packet_str = packet.GetString(); + return SendRawPacketNoLock(packet_str); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunication::SendRawPacketNoLock(llvm::StringRef packet, + bool skip_ack) { + if (IsConnected()) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS)); ConnectionStatus status = eConnectionStatusSuccess; - // TODO: Don't shimmy through a std::string, just use StringRef. - std::string packet_str = packet.GetString(); - const char *packet_data = packet_str.c_str(); - const size_t packet_length = packet.GetSize(); + const char *packet_data = packet.data(); + const size_t packet_length = packet.size(); size_t bytes_written = Write(packet_data, packet_length, status, NULL); if (log) { size_t binary_start_offset = 0; @@ -241,11 +182,12 @@ GDBRemoteCommunication::SendPacketNoLock(llvm::StringRef payload) { (int)packet_length, packet_data); } - m_history.AddPacket(packet.GetString(), packet_length, - History::ePacketTypeSend, bytes_written); + m_history.AddPacket(packet.str(), packet_length, + GDBRemoteCommunicationHistory::ePacketTypeSend, + bytes_written); if (bytes_written == packet_length) { - if (GetSendAcks()) + if (!skip_ack && GetSendAcks()) return GetAck(); else return PacketResult::Success; @@ -597,7 +539,7 @@ bool GDBRemoteCommunication::DecompressPacket() { size_t decompressed_bytes = 0; if (decompressed_bufsize != ULONG_MAX) { - decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize + 1); + decompressed_buffer = (uint8_t *)malloc(decompressed_bufsize); if (decompressed_buffer == nullptr) { m_bytes.erase(0, size_of_first_packet); return false; @@ -605,11 +547,10 @@ bool GDBRemoteCommunication::DecompressPacket() { } #if defined(HAVE_LIBCOMPRESSION) - // libcompression is weak linked so check that compression_decode_buffer() is - // available if (m_compression_type == CompressionType::ZlibDeflate || m_compression_type == CompressionType::LZFSE || - m_compression_type == CompressionType::LZ4) { + m_compression_type == CompressionType::LZ4 || + m_compression_type == CompressionType::LZMA) { compression_algorithm compression_type; if (m_compression_type == CompressionType::LZFSE) compression_type = COMPRESSION_LZFSE; @@ -620,16 +561,33 @@ bool GDBRemoteCommunication::DecompressPacket() { else if (m_compression_type == CompressionType::LZMA) compression_type = COMPRESSION_LZMA; - // If we have the expected size of the decompressed payload, we can - // allocate the right-sized buffer and do it. If we don't have that - // information, we'll need to try decoding into a big buffer and if the - // buffer wasn't big enough, increase it and try again. + if (m_decompression_scratch_type != m_compression_type) { + if (m_decompression_scratch) { + free (m_decompression_scratch); + m_decompression_scratch = nullptr; + } + size_t scratchbuf_size = 0; + if (m_compression_type == CompressionType::LZFSE) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE); + else if (m_compression_type == CompressionType::LZ4) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZ4_RAW); + else if (m_compression_type == CompressionType::ZlibDeflate) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_ZLIB); + else if (m_compression_type == CompressionType::LZMA) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZMA); + else if (m_compression_type == CompressionType::LZFSE) + scratchbuf_size = compression_decode_scratch_buffer_size (COMPRESSION_LZFSE); + if (scratchbuf_size > 0) { + m_decompression_scratch = (void*) malloc (scratchbuf_size); + m_decompression_scratch_type = m_compression_type; + } + } if (decompressed_bufsize != ULONG_MAX && decompressed_buffer != nullptr) { decompressed_bytes = compression_decode_buffer( - decompressed_buffer, decompressed_bufsize + 10, - (uint8_t *)unescaped_content.data(), unescaped_content.size(), NULL, - compression_type); + decompressed_buffer, decompressed_bufsize, + (uint8_t *)unescaped_content.data(), unescaped_content.size(), + m_decompression_scratch, compression_type); } } #endif @@ -721,7 +679,7 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, // Size of packet before it is decompressed, for logging purposes size_t original_packet_size = m_bytes.size(); if (CompressionIsEnabled()) { - if (DecompressPacket() == false) { + if (!DecompressPacket()) { packet.Clear(); return GDBRemoteCommunication::PacketType::Standard; } @@ -860,7 +818,8 @@ GDBRemoteCommunication::CheckForPacket(const uint8_t *src, size_t src_len, } } - m_history.AddPacket(m_bytes, total_length, History::ePacketTypeRecv, + m_history.AddPacket(m_bytes, total_length, + GDBRemoteCommunicationHistory::ePacketTypeRecv, total_length); // Clear packet_str in case there is some existing data in it. @@ -997,7 +956,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess( // debugserver to use and use it if we do. const char *env_debugserver_path = getenv("LLDB_DEBUGSERVER_PATH"); if (env_debugserver_path) { - debugserver_file_spec.SetFile(env_debugserver_path, false, + debugserver_file_spec.SetFile(env_debugserver_path, FileSpec::Style::native); if (log) log->Printf("GDBRemoteCommunication::%s() gdb-remote stub exe path set " @@ -1005,13 +964,14 @@ Status GDBRemoteCommunication::StartDebugserverProcess( __FUNCTION__, env_debugserver_path); } else debugserver_file_spec = g_debugserver_file_spec; - bool debugserver_exists = debugserver_file_spec.Exists(); + bool debugserver_exists = + FileSystem::Instance().Exists(debugserver_file_spec); if (!debugserver_exists) { // The debugserver binary is in the LLDB.framework/Resources directory. debugserver_file_spec = HostInfo::GetSupportExeDir(); if (debugserver_file_spec) { debugserver_file_spec.AppendPathComponent(DEBUGSERVER_BASENAME); - debugserver_exists = debugserver_file_spec.Exists(); + debugserver_exists = FileSystem::Instance().Exists(debugserver_file_spec); if (debugserver_exists) { if (log) log->Printf( @@ -1074,7 +1034,7 @@ Status GDBRemoteCommunication::StartDebugserverProcess( debugserver_args.AppendArgument(llvm::StringRef("--setsid")); } - llvm::SmallString named_pipe_path; + llvm::SmallString<128> named_pipe_path; // socket_pipe is used by debug server to communicate back either // TCP port or domain socket name which it listens on. // The second purpose of the pipe to serve as a synchronization point - @@ -1114,9 +1074,9 @@ Status GDBRemoteCommunication::StartDebugserverProcess( __FUNCTION__, error.AsCString()); return error; } - int write_fd = socket_pipe.GetWriteFileDescriptor(); + pipe_t write = socket_pipe.GetWritePipe(); debugserver_args.AppendArgument(llvm::StringRef("--pipe")); - debugserver_args.AppendArgument(llvm::to_string(write_fd)); + debugserver_args.AppendArgument(llvm::to_string(write)); launch_info.AppendCloseFileAction(socket_pipe.GetReadFileDescriptor()); #endif } else { @@ -1304,6 +1264,42 @@ Status GDBRemoteCommunication::StartDebugserverProcess( void GDBRemoteCommunication::DumpHistory(Stream &strm) { m_history.Dump(strm); } +void GDBRemoteCommunication::SetHistoryStream(llvm::raw_ostream *strm) { + m_history.SetStream(strm); +}; + +llvm::Error +GDBRemoteCommunication::ConnectLocally(GDBRemoteCommunication &client, + GDBRemoteCommunication &server) { + const bool child_processes_inherit = false; + const int backlog = 5; + TCPSocket listen_socket(true, child_processes_inherit); + if (llvm::Error error = + listen_socket.Listen("127.0.0.1:0", backlog).ToError()) + return error; + + Socket *accept_socket; + std::future accept_status = std::async( + std::launch::async, [&] { return listen_socket.Accept(accept_socket); }); + + llvm::SmallString<32> remote_addr; + llvm::raw_svector_ostream(remote_addr) + << "connect://localhost:" << listen_socket.GetLocalPortNumber(); + + std::unique_ptr conn_up( + new ConnectionFileDescriptor()); + if (conn_up->Connect(remote_addr, nullptr) != lldb::eConnectionStatusSuccess) + return llvm::make_error("Unable to connect", + llvm::inconvertibleErrorCode()); + + client.SetConnection(conn_up.release()); + if (llvm::Error error = accept_status.get().ToError()) + return error; + + server.SetConnection(new ConnectionFileDescriptor(accept_socket)); + return llvm::Error::success(); +} + GDBRemoteCommunication::ScopedTimeout::ScopedTimeout( GDBRemoteCommunication &gdb_comm, std::chrono::seconds timeout) : m_gdb_comm(gdb_comm), m_timeout_modified(false) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h index 67796e4c61ef..369eb25b1dfa 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h @@ -10,24 +10,21 @@ #ifndef liblldb_GDBRemoteCommunication_h_ #define liblldb_GDBRemoteCommunication_h_ -// C Includes -// C++ Includes +#include "GDBRemoteCommunicationHistory.h" + #include #include #include #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Core/Communication.h" -#include "lldb/Core/Listener.h" #include "lldb/Host/HostThread.h" -#include "lldb/Host/Predicate.h" #include "lldb/Utility/Args.h" -#include "lldb/lldb-public.h" - +#include "lldb/Utility/Listener.h" +#include "lldb/Utility/Predicate.h" #include "lldb/Utility/StringExtractorGDBRemote.h" +#include "lldb/lldb-public.h" namespace lldb_private { namespace process_gdb_remote { @@ -140,86 +137,16 @@ public: // fork/exec to avoid having to connect/accept void DumpHistory(Stream &strm); + void SetHistoryStream(llvm::raw_ostream *strm); + + static llvm::Error ConnectLocally(GDBRemoteCommunication &client, + GDBRemoteCommunication &server); protected: - class History { - public: - enum PacketType { - ePacketTypeInvalid = 0, - ePacketTypeSend, - ePacketTypeRecv - }; - - struct Entry { - Entry() - : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), - packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {} - - void Clear() { - packet.clear(); - type = ePacketTypeInvalid; - bytes_transmitted = 0; - packet_idx = 0; - tid = LLDB_INVALID_THREAD_ID; - } - std::string packet; - PacketType type; - uint32_t bytes_transmitted; - uint32_t packet_idx; - lldb::tid_t tid; - }; - - History(uint32_t size); - - ~History(); - - // For single char packets for ack, nack and /x03 - void AddPacket(char packet_char, PacketType type, - uint32_t bytes_transmitted); - - void AddPacket(const std::string &src, uint32_t src_len, PacketType type, - uint32_t bytes_transmitted); - - void Dump(Stream &strm) const; - - void Dump(Log *log) const; - - bool DidDumpToLog() const { return m_dumped_to_log; } - - protected: - uint32_t GetFirstSavedPacketIndex() const { - if (m_total_packet_count < m_packets.size()) - return 0; - else - return m_curr_idx + 1; - } - - uint32_t GetNumPacketsInHistory() const { - if (m_total_packet_count < m_packets.size()) - return m_total_packet_count; - else - return (uint32_t)m_packets.size(); - } - - uint32_t GetNextIndex() { - ++m_total_packet_count; - const uint32_t idx = m_curr_idx; - m_curr_idx = NormalizeIndex(idx + 1); - return idx; - } - - uint32_t NormalizeIndex(uint32_t i) const { return i % m_packets.size(); } - - std::vector m_packets; - uint32_t m_curr_idx; - uint32_t m_total_packet_count; - mutable bool m_dumped_to_log; - }; - std::chrono::seconds m_packet_timeout; uint32_t m_echo_number; LazyBool m_supports_qEcho; - History m_history; + GDBRemoteCommunicationHistory m_history; bool m_send_acks; bool m_is_platform; // Set to true if this class represents a platform, // false if this class represents a debug session for @@ -228,6 +155,8 @@ protected: CompressionType m_compression_type; PacketResult SendPacketNoLock(llvm::StringRef payload); + PacketResult SendRawPacketNoLock(llvm::StringRef payload, + bool skip_ack = false); PacketResult ReadPacket(StringExtractorGDBRemote &response, Timeout timeout, bool sync_on_timeout); @@ -289,6 +218,9 @@ private: HostThread m_listen_thread; std::string m_listen_url; + CompressionType m_decompression_scratch_type; + void *m_decompression_scratch; + DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunication); }; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp index c8b59d5d236b..1e12ea6b2d56 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp @@ -9,17 +9,13 @@ #include "GDBRemoteCommunicationClient.h" -// C Includes #include #include -// C++ Includes #include #include -// Other libraries and framework includes #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/State.h" #include "lldb/Host/HostInfo.h" #include "lldb/Host/XML.h" #include "lldb/Symbol/Symbol.h" @@ -31,9 +27,9 @@ #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" -// Project includes #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" #include "lldb/Host/Config.h" @@ -41,7 +37,8 @@ #include "llvm/ADT/StringSwitch.h" -#if defined(HAVE_LIBCOMPRESSION) +#if defined(__APPLE__) +#define HAVE_LIBCOMPRESSION #include #endif @@ -256,10 +253,7 @@ bool GDBRemoteCommunicationClient::GetVAttachOrWaitSupported() { m_attach_or_wait_reply = eLazyBoolYes; } } - if (m_attach_or_wait_reply == eLazyBoolYes) - return true; - else - return false; + return m_attach_or_wait_reply == eLazyBoolYes; } bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() { @@ -273,14 +267,11 @@ bool GDBRemoteCommunicationClient::GetSyncThreadStateSupported() { m_prepare_for_reg_writing_reply = eLazyBoolYes; } } - if (m_prepare_for_reg_writing_reply == eLazyBoolYes) - return true; - else - return false; + return m_prepare_for_reg_writing_reply == eLazyBoolYes; } void GDBRemoteCommunicationClient::ResetDiscoverableSettings(bool did_exec) { - if (did_exec == false) { + if (!did_exec) { // Hard reset everything, this is when we first connect to a GDB server m_supports_not_sending_acks = eLazyBoolCalculate; m_supports_thread_suffix = eLazyBoolCalculate; @@ -749,7 +740,7 @@ lldb::pid_t GDBRemoteCommunicationClient::GetCurrentProcessID(bool allow_lazy) { bool sequence_mutex_unavailable; size_t size; size = GetCurrentThreadIDs(thread_ids, sequence_mutex_unavailable); - if (size && sequence_mutex_unavailable == false) { + if (size && !sequence_mutex_unavailable) { m_curr_pid = thread_ids.front(); m_curr_pid_is_valid = eLazyBoolYes; return m_curr_pid; @@ -843,8 +834,8 @@ int GDBRemoteCommunicationClient::SendEnvironmentPacket( if (name_equal_value && name_equal_value[0]) { StreamString packet; bool send_hex_encoding = false; - for (const char *p = name_equal_value; - *p != '\0' && send_hex_encoding == false; ++p) { + for (const char *p = name_equal_value; *p != '\0' && !send_hex_encoding; + ++p) { if (isprint(*p)) { switch (*p) { case '$': @@ -1134,6 +1125,9 @@ bool GDBRemoteCommunicationClient::GetHostInfo(bool force) { Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_PROCESS)); if (force || m_qHostInfo_is_valid == eLazyBoolCalculate) { + // host info computation can require DNS traffic and shelling out to external processes. + // Increase the timeout to account for that. + ScopedTimeout timeout(*this, seconds(10)); m_qHostInfo_is_valid = eLazyBoolNo; StringExtractorGDBRemote response; if (SendPacketAndWaitForResponse("qHostInfo", response, false) == @@ -1686,12 +1680,17 @@ Status GDBRemoteCommunicationClient::GetWatchpointSupportInfo(uint32_t &num) { m_supports_watchpoint_support_info = eLazyBoolYes; llvm::StringRef name; llvm::StringRef value; + bool found_num_field = false; while (response.GetNameColonValue(name, value)) { if (name.equals("num")) { value.getAsInteger(0, m_num_supported_hardware_watchpoints); num = m_num_supported_hardware_watchpoints; + found_num_field = true; } } + if (!found_num_field) { + m_supports_watchpoint_support_info = eLazyBoolNo; + } } else { m_supports_watchpoint_support_info = eLazyBoolNo; } @@ -1724,12 +1723,10 @@ GDBRemoteCommunicationClient::GetWatchpointsTriggerAfterInstruction( // On targets like MIPS and ppc64le, watchpoint exceptions are always // generated before the instruction is executed. The connected target may // not support qHostInfo or qWatchpointSupportInfo packets. - if (atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || - atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || - atype == llvm::Triple::ppc64le) - after = false; - else - after = true; + after = + !(atype == llvm::Triple::mips || atype == llvm::Triple::mipsel || + atype == llvm::Triple::mips64 || atype == llvm::Triple::mips64el || + atype == llvm::Triple::ppc64le); } else { // For MIPS and ppc64le, set m_watchpoints_trigger_after_instruction to // eLazyBoolNo if it is not calculated before. @@ -1815,7 +1812,7 @@ bool GDBRemoteCommunicationClient::GetWorkingDir(FileSpec &working_dir) { return false; std::string cwd; response.GetHexByteString(cwd); - working_dir.SetFile(cwd, false, GetHostArchitecture().GetTriple()); + working_dir.SetFile(cwd, GetHostArchitecture().GetTriple()); return !cwd.empty(); } return false; @@ -1925,8 +1922,7 @@ bool GDBRemoteCommunicationClient::DecodeProcessInfoResponse( // characters in a process name std::string name; extractor.GetHexByteString(name); - process_info.GetExecutableFile().SetFile(name, false, - FileSpec::Style::native); + process_info.GetExecutableFile().SetFile(name, FileSpec::Style::native); } else if (name.equals("cputype")) { value.getAsInteger(0, cpu); } else if (name.equals("cpusubtype")) { @@ -3559,7 +3555,7 @@ bool GDBRemoteCommunicationClient::GetModuleInfo( StringExtractor extractor(value); std::string path; extractor.GetHexByteString(path); - module_spec.GetFileSpec() = FileSpec(path, false, arch_spec.GetTriple()); + module_spec.GetFileSpec() = FileSpec(path, arch_spec.GetTriple()); } } @@ -3595,8 +3591,7 @@ ParseModuleSpec(StructuredData::Dictionary *dict) { if (!dict->GetValueForKeyAsString("file_path", string)) return llvm::None; - result.GetFileSpec() = - FileSpec(string, false, result.GetArchitecture().GetTriple()); + result.GetFileSpec() = FileSpec(string, result.GetArchitecture().GetTriple()); return result; } @@ -3774,7 +3769,7 @@ void GDBRemoteCommunicationClient::ServeSymbolLookups( // Is this the initial qSymbol:: packet? bool first_qsymbol_query = true; - if (m_supports_qSymbol && m_qSymbol_requests_done == false) { + if (m_supports_qSymbol && !m_qSymbol_requests_done) { Lock lock(*this, false); if (lock) { StreamString packet; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h index cf1d249768d7..37d53ab425f5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h @@ -12,8 +12,6 @@ #include "GDBRemoteClientBase.h" -// C Includes -// C++ Includes #include #include #include diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp new file mode 100644 index 000000000000..69b13f2a3acb --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.cpp @@ -0,0 +1,143 @@ +//===-- GDBRemoteCommunicationHistory.cpp -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "GDBRemoteCommunicationHistory.h" + +// Other libraries and framework includes +#include "lldb/Core/StreamFile.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Log.h" + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::process_gdb_remote; + +void GDBRemoteCommunicationHistory::Entry::Serialize(raw_ostream &strm) const { + yaml::Output yout(strm); + yout << const_cast(*this); + strm.flush(); +} + +GDBRemoteCommunicationHistory::GDBRemoteCommunicationHistory(uint32_t size) + : m_packets(), m_curr_idx(0), m_total_packet_count(0), + m_dumped_to_log(false) { + if (size) + m_packets.resize(size); +} + +GDBRemoteCommunicationHistory::~GDBRemoteCommunicationHistory() {} + +void GDBRemoteCommunicationHistory::AddPacket(char packet_char, PacketType type, + uint32_t bytes_transmitted) { + const size_t size = m_packets.size(); + if (size == 0) + return; + + const uint32_t idx = GetNextIndex(); + m_packets[idx].packet.data.assign(1, packet_char); + m_packets[idx].type = type; + m_packets[idx].bytes_transmitted = bytes_transmitted; + m_packets[idx].packet_idx = m_total_packet_count; + m_packets[idx].tid = llvm::get_threadid(); + if (m_stream && type == ePacketTypeRecv) + m_packets[idx].Serialize(*m_stream); +} + +void GDBRemoteCommunicationHistory::AddPacket(const std::string &src, + uint32_t src_len, PacketType type, + uint32_t bytes_transmitted) { + const size_t size = m_packets.size(); + if (size == 0) + return; + + const uint32_t idx = GetNextIndex(); + m_packets[idx].packet.data.assign(src, 0, src_len); + m_packets[idx].type = type; + m_packets[idx].bytes_transmitted = bytes_transmitted; + m_packets[idx].packet_idx = m_total_packet_count; + m_packets[idx].tid = llvm::get_threadid(); + if (m_stream && type == ePacketTypeRecv) + m_packets[idx].Serialize(*m_stream); +} + +void GDBRemoteCommunicationHistory::Dump(Stream &strm) const { + const uint32_t size = GetNumPacketsInHistory(); + const uint32_t first_idx = GetFirstSavedPacketIndex(); + const uint32_t stop_idx = m_curr_idx + size; + for (uint32_t i = first_idx; i < stop_idx; ++i) { + const uint32_t idx = NormalizeIndex(i); + const Entry &entry = m_packets[idx]; + if (entry.type == ePacketTypeInvalid || entry.packet.data.empty()) + break; + strm.Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s\n", + entry.packet_idx, entry.tid, entry.bytes_transmitted, + (entry.type == ePacketTypeSend) ? "send" : "read", + entry.packet.data.c_str()); + } +} + +void GDBRemoteCommunicationHistory::Dump(Log *log) const { + if (!log || m_dumped_to_log) + return; + + m_dumped_to_log = true; + const uint32_t size = GetNumPacketsInHistory(); + const uint32_t first_idx = GetFirstSavedPacketIndex(); + const uint32_t stop_idx = m_curr_idx + size; + for (uint32_t i = first_idx; i < stop_idx; ++i) { + const uint32_t idx = NormalizeIndex(i); + const Entry &entry = m_packets[idx]; + if (entry.type == ePacketTypeInvalid || entry.packet.data.empty()) + break; + log->Printf("history[%u] tid=0x%4.4" PRIx64 " <%4u> %s packet: %s", + entry.packet_idx, entry.tid, entry.bytes_transmitted, + (entry.type == ePacketTypeSend) ? "send" : "read", + entry.packet.data.c_str()); + } +} + +void yaml::ScalarEnumerationTraits:: + enumeration(IO &io, GDBRemoteCommunicationHistory::PacketType &value) { + io.enumCase(value, "Invalid", + GDBRemoteCommunicationHistory::ePacketTypeInvalid); + io.enumCase(value, "Send", GDBRemoteCommunicationHistory::ePacketTypeSend); + io.enumCase(value, "Recv", GDBRemoteCommunicationHistory::ePacketTypeRecv); +} + +void yaml::ScalarTraits:: + output(const GDBRemoteCommunicationHistory::Entry::BinaryData &Val, void *, + raw_ostream &Out) { + Out << toHex(Val.data); +} + +StringRef +yaml::ScalarTraits::input( + StringRef Scalar, void *, + GDBRemoteCommunicationHistory::Entry::BinaryData &Val) { + Val.data = fromHex(Scalar); + return {}; +} + +void yaml::MappingTraits::mapping( + IO &io, GDBRemoteCommunicationHistory::Entry &Entry) { + io.mapRequired("packet", Entry.packet); + io.mapRequired("type", Entry.type); + io.mapRequired("bytes", Entry.bytes_transmitted); + io.mapRequired("index", Entry.packet_idx); + io.mapRequired("tid", Entry.tid); +} + +StringRef yaml::MappingTraits::validate( + IO &io, GDBRemoteCommunicationHistory::Entry &Entry) { + if (Entry.bytes_transmitted != Entry.packet.data.size()) + return "BinaryData size doesn't match bytes transmitted"; + + return {}; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h new file mode 100644 index 000000000000..d0ca6a0235c9 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationHistory.h @@ -0,0 +1,156 @@ +//===-- GDBRemoteCommunicationHistory.h--------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_GDBRemoteCommunicationHistory_h_ +#define liblldb_GDBRemoteCommunicationHistory_h_ + +#include +#include + +#include "lldb/lldb-public.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" + +namespace lldb_private { +namespace process_gdb_remote { + +/// The history keeps a circular buffer of GDB remote packets. The history is +/// used for logging and replaying GDB remote packets. +class GDBRemoteCommunicationHistory { +public: + friend llvm::yaml::MappingTraits; + + enum PacketType { ePacketTypeInvalid = 0, ePacketTypeSend, ePacketTypeRecv }; + + /// Entry in the ring buffer containing the packet data, its type, size and + /// index. Entries can be serialized to file. + struct Entry { + Entry() + : packet(), type(ePacketTypeInvalid), bytes_transmitted(0), + packet_idx(0), tid(LLDB_INVALID_THREAD_ID) {} + + void Clear() { + packet.data.clear(); + type = ePacketTypeInvalid; + bytes_transmitted = 0; + packet_idx = 0; + tid = LLDB_INVALID_THREAD_ID; + } + + struct BinaryData { + std::string data; + }; + + void Serialize(llvm::raw_ostream &strm) const; + + BinaryData packet; + PacketType type; + uint32_t bytes_transmitted; + uint32_t packet_idx; + lldb::tid_t tid; + }; + + GDBRemoteCommunicationHistory(uint32_t size = 0); + + ~GDBRemoteCommunicationHistory(); + + // For single char packets for ack, nack and /x03 + void AddPacket(char packet_char, PacketType type, uint32_t bytes_transmitted); + + void AddPacket(const std::string &src, uint32_t src_len, PacketType type, + uint32_t bytes_transmitted); + + void Dump(Stream &strm) const; + void Dump(Log *log) const; + bool DidDumpToLog() const { return m_dumped_to_log; } + + void SetStream(llvm::raw_ostream *strm) { m_stream = strm; } + +private: + uint32_t GetFirstSavedPacketIndex() const { + if (m_total_packet_count < m_packets.size()) + return 0; + else + return m_curr_idx + 1; + } + + uint32_t GetNumPacketsInHistory() const { + if (m_total_packet_count < m_packets.size()) + return m_total_packet_count; + else + return (uint32_t)m_packets.size(); + } + + uint32_t GetNextIndex() { + ++m_total_packet_count; + const uint32_t idx = m_curr_idx; + m_curr_idx = NormalizeIndex(idx + 1); + return idx; + } + + uint32_t NormalizeIndex(uint32_t i) const { + return m_packets.empty() ? 0 : i % m_packets.size(); + } + + std::vector m_packets; + uint32_t m_curr_idx; + uint32_t m_total_packet_count; + mutable bool m_dumped_to_log; + llvm::raw_ostream *m_stream = nullptr; +}; + +} // namespace process_gdb_remote +} // namespace lldb_private + +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR( + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry) + +namespace llvm { +namespace yaml { + +template <> +struct ScalarEnumerationTraits { + static void enumeration(IO &io, + lldb_private::process_gdb_remote:: + GDBRemoteCommunicationHistory::PacketType &value); +}; + +template <> +struct ScalarTraits { + static void output(const lldb_private::process_gdb_remote:: + GDBRemoteCommunicationHistory::Entry::BinaryData &, + void *, raw_ostream &); + + static StringRef + input(StringRef, void *, + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry:: + BinaryData &); + + static QuotingType mustQuote(StringRef S) { return QuotingType::None; } +}; + +template <> +struct MappingTraits< + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry> { + static void + mapping(IO &io, + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry + &Entry); + + static StringRef validate( + IO &io, + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry &); +}; + +} // namespace yaml +} // namespace llvm + +#endif // liblldb_GDBRemoteCommunicationHistory_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp new file mode 100644 index 000000000000..6a78eb20992e --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.cpp @@ -0,0 +1,204 @@ +//===-- GDBRemoteCommunicationReplayServer.cpp ------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include + +#include "lldb/Host/Config.h" + +#include "GDBRemoteCommunicationReplayServer.h" +#include "ProcessGDBRemoteLog.h" + +// C Includes +// C++ Includes +#include + +// Project includes +#include "lldb/Host/ThreadLauncher.h" +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/StreamString.h" +#include "lldb/Utility/StringExtractorGDBRemote.h" + +using namespace llvm; +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::process_gdb_remote; + +GDBRemoteCommunicationReplayServer::GDBRemoteCommunicationReplayServer() + : GDBRemoteCommunication("gdb-remote.server", + "gdb-remote.server.rx_packet"), + m_async_broadcaster(nullptr, "lldb.gdb-remote.server.async-broadcaster"), + m_async_listener_sp( + Listener::MakeListener("lldb.gdb-remote.server.async-listener")), + m_async_thread_state_mutex(), m_skip_acks(false) { + m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, + "async thread continue"); + m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, + "async thread should exit"); + + const uint32_t async_event_mask = + eBroadcastBitAsyncContinue | eBroadcastBitAsyncThreadShouldExit; + m_async_listener_sp->StartListeningForEvents(&m_async_broadcaster, + async_event_mask); +} + +GDBRemoteCommunicationReplayServer::~GDBRemoteCommunicationReplayServer() { + StopAsyncThread(); +} + +GDBRemoteCommunication::PacketResult +GDBRemoteCommunicationReplayServer::GetPacketAndSendResponse( + Timeout timeout, Status &error, bool &interrupt, bool &quit) { + StringExtractorGDBRemote packet; + PacketResult packet_result = WaitForPacketNoLock(packet, timeout, false); + + if (packet_result != PacketResult::Success) { + if (!IsConnected()) { + error.SetErrorString("lost connection"); + quit = true; + } else { + error.SetErrorString("timeout"); + } + return packet_result; + } + + m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); + + if (m_skip_acks) { + const StringExtractorGDBRemote::ServerPacketType packet_type = + packet.GetServerPacketType(); + switch (packet_type) { + case StringExtractorGDBRemote::eServerPacketType_nack: + case StringExtractorGDBRemote::eServerPacketType_ack: + return PacketResult::Success; + default: + break; + } + } else if (packet.GetStringRef() == "QStartNoAckMode") { + m_skip_acks = true; + m_send_acks = false; + } + + while (!m_packet_history.empty()) { + // Pop last packet from the history. + GDBRemoteCommunicationHistory::Entry entry = m_packet_history.back(); + m_packet_history.pop_back(); + + // We only care about what we received from the server. Skip everything + // the client sent. + if (entry.type != GDBRemoteCommunicationHistory::ePacketTypeRecv) + continue; + + return SendRawPacketNoLock(entry.packet.data, true); + } + + quit = true; + + return packet_result; +} + +LLVM_YAML_IS_DOCUMENT_LIST_VECTOR( + std::vector< + lldb_private::process_gdb_remote::GDBRemoteCommunicationHistory::Entry>) + +llvm::Error +GDBRemoteCommunicationReplayServer::LoadReplayHistory(const FileSpec &path) { + auto error_or_file = MemoryBuffer::getFile(path.GetPath()); + if (auto err = error_or_file.getError()) + return errorCodeToError(err); + + yaml::Input yin((*error_or_file)->getBuffer()); + yin >> m_packet_history; + + if (auto err = yin.error()) + return errorCodeToError(err); + + // We want to manipulate the vector like a stack so we need to reverse the + // order of the packets to have the oldest on at the back. + std::reverse(m_packet_history.begin(), m_packet_history.end()); + + return Error::success(); +} + +bool GDBRemoteCommunicationReplayServer::StartAsyncThread() { + std::lock_guard guard(m_async_thread_state_mutex); + if (!m_async_thread.IsJoinable()) { + // Create a thread that watches our internal state and controls which + // events make it to clients (into the DCProcess event queue). + m_async_thread = ThreadLauncher::LaunchThread( + "", + GDBRemoteCommunicationReplayServer::AsyncThread, this, nullptr); + } + + // Wait for handshake. + m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); + + return m_async_thread.IsJoinable(); +} + +void GDBRemoteCommunicationReplayServer::StopAsyncThread() { + std::lock_guard guard(m_async_thread_state_mutex); + + if (!m_async_thread.IsJoinable()) + return; + + // Request thread to stop. + m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncThreadShouldExit); + + // Disconnect client. + Disconnect(); + + // Stop the thread. + m_async_thread.Join(nullptr); + m_async_thread.Reset(); +} + +void GDBRemoteCommunicationReplayServer::ReceivePacket( + GDBRemoteCommunicationReplayServer &server, bool &done) { + Status error; + bool interrupt; + auto packet_result = server.GetPacketAndSendResponse(std::chrono::seconds(1), + error, interrupt, done); + if (packet_result != GDBRemoteCommunication::PacketResult::Success && + packet_result != + GDBRemoteCommunication::PacketResult::ErrorReplyTimeout) { + done = true; + } else { + server.m_async_broadcaster.BroadcastEvent(eBroadcastBitAsyncContinue); + } +} + +thread_result_t GDBRemoteCommunicationReplayServer::AsyncThread(void *arg) { + GDBRemoteCommunicationReplayServer *server = + (GDBRemoteCommunicationReplayServer *)arg; + + EventSP event_sp; + bool done = false; + + while (true) { + if (server->m_async_listener_sp->GetEvent(event_sp, llvm::None)) { + const uint32_t event_type = event_sp->GetType(); + if (event_sp->BroadcasterIs(&server->m_async_broadcaster)) { + switch (event_type) { + case eBroadcastBitAsyncContinue: + ReceivePacket(*server, done); + if (done) + return {}; + break; + case eBroadcastBitAsyncThreadShouldExit: + default: + return {}; + } + } + } + } + + return {}; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h new file mode 100644 index 000000000000..5b840c8459b7 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationReplayServer.h @@ -0,0 +1,83 @@ +//===-- GDBRemoteCommunicationReplayServer.h --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_GDBRemoteCommunicationReplayServer_h_ +#define liblldb_GDBRemoteCommunicationReplayServer_h_ + +// Other libraries and framework includes +#include "GDBRemoteCommunication.h" +#include "GDBRemoteCommunicationHistory.h" + +// Project includes +#include "lldb/Host/HostThread.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/lldb-private-forward.h" +#include "llvm/Support/Error.h" + +// C Includes +// C++ Includes +#include +#include +#include + +class StringExtractorGDBRemote; + +namespace lldb_private { +namespace process_gdb_remote { + +class ProcessGDBRemote; + +/// Dummy GDB server that replays packets from the GDB Remote Communication +/// history. This is used to replay GDB packets. +class GDBRemoteCommunicationReplayServer : public GDBRemoteCommunication { +public: + GDBRemoteCommunicationReplayServer(); + + ~GDBRemoteCommunicationReplayServer() override; + + PacketResult GetPacketAndSendResponse(Timeout timeout, + Status &error, bool &interrupt, + bool &quit); + + bool HandshakeWithClient() { return GetAck() == PacketResult::Success; } + + llvm::Error LoadReplayHistory(const FileSpec &path); + + bool StartAsyncThread(); + void StopAsyncThread(); + +protected: + enum { + eBroadcastBitAsyncContinue = (1 << 0), + eBroadcastBitAsyncThreadShouldExit = (1 << 1), + }; + + static void ReceivePacket(GDBRemoteCommunicationReplayServer &server, + bool &done); + static lldb::thread_result_t AsyncThread(void *arg); + + /// Replay history with the oldest packet at the end. + std::vector m_packet_history; + + /// Server thread. + Broadcaster m_async_broadcaster; + lldb::ListenerSP m_async_listener_sp; + HostThread m_async_thread; + std::recursive_mutex m_async_thread_state_mutex; + + bool m_skip_acks; + +private: + DISALLOW_COPY_AND_ASSIGN(GDBRemoteCommunicationReplayServer); +}; + +} // namespace process_gdb_remote +} // namespace lldb_private + +#endif // liblldb_GDBRemoteCommunicationReplayServer_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp index 4fc1fc7a1964..026f78117a0c 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp @@ -13,11 +13,8 @@ #include "GDBRemoteCommunicationServer.h" -// C Includes -// C++ Includes #include -// Project includes #include "ProcessGDBRemoteLog.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/StringExtractorGDBRemote.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h index 880caacd6414..082fb0d85424 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h @@ -10,13 +10,9 @@ #ifndef liblldb_GDBRemoteCommunicationServer_h_ #define liblldb_GDBRemoteCommunicationServer_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "GDBRemoteCommunication.h" #include "lldb/lldb-private-forward.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp index c5b478378faa..f11ef4f1bbf8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp @@ -11,23 +11,21 @@ #include -// C Includes #ifdef __APPLE__ #include #endif -// C++ Includes #include #include -// Other libraries and framework includes #include "lldb/Core/ModuleSpec.h" #include "lldb/Host/Config.h" #include "lldb/Host/File.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" +#include "lldb/Host/SafeMachO.h" #include "lldb/Interpreter/OptionArgParser.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/FileAction.h" @@ -36,12 +34,10 @@ #include "lldb/Utility/Endian.h" #include "lldb/Utility/JSON.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/SafeMachO.h" #include "lldb/Utility/StreamGDBRemote.h" #include "lldb/Utility/StreamString.h" #include "llvm/ADT/Triple.h" -// Project includes #include "ProcessGDBRemoteLog.h" #include "lldb/Utility/StringExtractorGDBRemote.h" @@ -353,7 +349,7 @@ GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo( std::string file; extractor.GetHexByteString(file); match_info.GetProcessInfo().GetExecutableFile().SetFile( - file, false, FileSpec::Style::native); + file, FileSpec::Style::native); } else if (key.equals("name_match")) { NameMatch name_match = llvm::StringSwitch(value) .Case("equals", NameMatch::Equals) @@ -520,7 +516,8 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Open( if (packet.GetChar() == ',') { mode_t mode = packet.GetHexMaxU32(false, 0600); Status error; - const FileSpec path_spec{path, true}; + FileSpec path_spec(path); + FileSystem::Instance().Resolve(path_spec); int fd = ::open(path_spec.GetCString(), flags, mode); const int save_errno = fd == -1 ? errno : 0; StreamString response; @@ -659,12 +656,14 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Mode( std::string path; packet.GetHexByteString(path); if (!path.empty()) { - Status error; - const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error); + FileSpec file_spec(path); + FileSystem::Instance().Resolve(file_spec); + std::error_code ec; + const uint32_t mode = FileSystem::Instance().GetPermissions(file_spec, ec); StreamString response; response.Printf("F%u", mode); - if (mode == 0 || error.Fail()) - response.Printf(",%i", (int)error.GetError()); + if (mode == 0 || ec) + response.Printf(",%i", (int)Status(ec).GetError()); return SendPacketNoLock(response.GetString()); } return SendErrorResponse(23); @@ -698,7 +697,11 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_symlink( packet.GetHexByteStringTerminatedBy(dst, ','); packet.GetChar(); // Skip ',' char packet.GetHexByteString(src); - Status error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false}); + + FileSpec src_spec(src); + FileSystem::Instance().Resolve(src_spec); + Status error = FileSystem::Instance().Symlink(src_spec, FileSpec(dst)); + StreamString response; response.Printf("F%u,%u", error.GetError(), error.GetError()); return SendPacketNoLock(response.GetString()); @@ -731,9 +734,11 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell( packet.GetHexByteString(working_dir); int status, signo; std::string output; - Status err = Host::RunShellCommand( - path.c_str(), FileSpec{working_dir, true}, &status, &signo, &output, - std::chrono::seconds(10)); + FileSpec working_spec(working_dir); + FileSystem::Instance().Resolve(working_spec); + Status err = + Host::RunShellCommand(path.c_str(), working_spec, &status, &signo, + &output, std::chrono::seconds(10)); StreamGDBRemote response; if (err.Fail()) { response.PutCString("F,"); @@ -884,7 +889,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN( packet.GetHexByteString(path); const bool read = true; const bool write = false; - if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) { + if (file_action.Open(STDIN_FILENO, FileSpec(path), read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -900,7 +905,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT( packet.GetHexByteString(path); const bool read = false; const bool write = true; - if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) { + if (file_action.Open(STDOUT_FILENO, FileSpec(path), read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -916,7 +921,7 @@ GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR( packet.GetHexByteString(path); const bool read = false; const bool write = true; - if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) { + if (file_action.Open(STDERR_FILENO, FileSpec(path), read, write)) { m_process_launch_info.AppendFileAction(file_action); return SendOKResponse(); } @@ -1024,7 +1029,7 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) { if (success) { if (arg_idx == 0) m_process_launch_info.GetExecutableFile().SetFile( - arg, false, FileSpec::Style::native); + arg, FileSpec::Style::native); m_process_launch_info.GetArguments().AppendArgument(arg); if (log) log->Printf("LLGSPacketHandler::%s added arg %d: \"%s\"", @@ -1263,7 +1268,9 @@ FileSpec GDBRemoteCommunicationServerCommon::FindModuleFile( #ifdef __ANDROID__ return HostInfoAndroid::ResolveLibraryPath(module_path, arch); #else - return FileSpec(module_path, true); + FileSpec file_spec(module_path); + FileSystem::Instance().Resolve(file_spec); + return file_spec; #endif } @@ -1272,7 +1279,9 @@ GDBRemoteCommunicationServerCommon::GetModuleInfo(llvm::StringRef module_path, llvm::StringRef triple) { ArchSpec arch(triple); - const FileSpec req_module_path_spec(module_path, true); + FileSpec req_module_path_spec(module_path); + FileSystem::Instance().Resolve(req_module_path_spec); + const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch); const ModuleSpec module_spec(module_path_spec, arch); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h index e9ab8f1a11de..f3825bb36791 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.h @@ -10,12 +10,8 @@ #ifndef liblldb_GDBRemoteCommunicationServerCommon_h_ #define liblldb_GDBRemoteCommunicationServerCommon_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/lldb-private-forward.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp index 50392fa38956..cdb63e72f6bd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp @@ -14,15 +14,10 @@ #include "GDBRemoteCommunicationServerLLGS.h" #include "lldb/Utility/StreamGDBRemote.h" -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/State.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/Debug.h" #include "lldb/Host/File.h" @@ -41,12 +36,13 @@ #include "lldb/Utility/JSON.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/UriParser.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/ScopedPrinter.h" -// Project includes #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" #include "lldb/Utility/StringExtractorGDBRemote.h" @@ -222,8 +218,10 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() { m_process_launch_info.SetLaunchInSeparateProcessGroup(true); m_process_launch_info.GetFlags().Set(eLaunchFlagDebug); - const bool default_to_use_pty = true; - m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty); + if (should_forward_stdio) { + if (llvm::Error Err = m_process_launch_info.SetUpPtyRedirection()) + return Status(std::move(Err)); + } { std::lock_guard guard(m_debugged_process_mutex); @@ -1333,7 +1331,7 @@ GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir( packet.SetFilePos(::strlen("QSetWorkingDir:")); std::string path; packet.GetHexByteString(path); - m_process_launch_info.SetWorkingDirectory(FileSpec{path, true}); + m_process_launch_info.SetWorkingDirectory(FileSpec(path)); return SendOKResponse(); } @@ -3220,7 +3218,7 @@ GDBRemoteCommunicationServerLLGS::FindModuleFile(const std::string &module_path, if (m_debugged_process_up ->GetLoadedModuleFileSpec(module_path.c_str(), file_spec) .Success()) { - if (file_spec.Exists()) + if (FileSystem::Instance().Exists(file_spec)) return file_spec; } } diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h index 5a74d1acaa23..a085a3cc17dd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h @@ -10,18 +10,14 @@ #ifndef liblldb_GDBRemoteCommunicationServerLLGS_h_ #define liblldb_GDBRemoteCommunicationServerLLGS_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "lldb/Core/Communication.h" #include "lldb/Host/MainLoop.h" #include "lldb/Host/common/NativeProcessProtocol.h" #include "lldb/lldb-private-forward.h" -// Project includes #include "GDBRemoteCommunicationServerCommon.h" class StringExtractorGDBRemote; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp index 26e28a900320..3521ddafbb16 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.cpp @@ -11,15 +11,12 @@ #include -// C Includes -// C++ Includes #include #include #include #include #include -// Other libraries and framework includes #include "llvm/Support/FileSystem.h" #include "llvm/Support/Threading.h" @@ -38,7 +35,6 @@ #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/UriParser.h" -// Project includes #include "lldb/Utility/StringExtractorGDBRemote.h" using namespace lldb; @@ -168,9 +164,6 @@ Status GDBRemoteCommunicationServerPlatform::LaunchGDBServer( GDBRemoteCommunication::PacketResult GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( StringExtractorGDBRemote &packet) { -#ifdef _WIN32 - return SendErrorResponse(9); -#else // Spawn a local debugserver as a platform so we can then attach or launch a // process... @@ -221,10 +214,9 @@ GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer( PacketResult packet_result = SendPacketNoLock(response.GetString()); if (packet_result != PacketResult::Success) { if (debugserver_pid != LLDB_INVALID_PROCESS_ID) - ::kill(debugserver_pid, SIGINT); + Host::Kill(debugserver_pid, SIGINT); } return packet_result; -#endif } GDBRemoteCommunication::PacketResult @@ -532,7 +524,7 @@ const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() { const char *domainsocket_dir_env = ::getenv("LLDB_DEBUGSERVER_DOMAINSOCKET_DIR"); if (domainsocket_dir_env != nullptr) - g_domainsocket_dir = FileSpec(domainsocket_dir_env, false); + g_domainsocket_dir = FileSpec(domainsocket_dir_env); else g_domainsocket_dir = HostInfo::GetProcessTempDir(); }); @@ -542,15 +534,15 @@ const FileSpec &GDBRemoteCommunicationServerPlatform::GetDomainSocketDir() { FileSpec GDBRemoteCommunicationServerPlatform::GetDomainSocketPath(const char *prefix) { - llvm::SmallString socket_path; - llvm::SmallString socket_name( + llvm::SmallString<128> socket_path; + llvm::SmallString<128> socket_name( (llvm::StringRef(prefix) + ".%%%%%%").str()); FileSpec socket_path_spec(GetDomainSocketDir()); socket_path_spec.AppendPathComponent(socket_name.c_str()); llvm::sys::fs::createUniqueFile(socket_path_spec.GetCString(), socket_path); - return FileSpec(socket_path.c_str(), false); + return FileSpec(socket_path.c_str()); } void GDBRemoteCommunicationServerPlatform::SetPortOffset(uint16_t port_offset) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h index aed5106272d1..df51e0367d1d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerPlatform.h @@ -10,14 +10,10 @@ #ifndef liblldb_GDBRemoteCommunicationServerPlatform_h_ #define liblldb_GDBRemoteCommunicationServerPlatform_h_ -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "GDBRemoteCommunicationServerCommon.h" #include "lldb/Host/Socket.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 07dab751f4b9..e58f47f4befe 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -9,17 +9,13 @@ #include "GDBRemoteRegisterContext.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Target.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" -// Project includes #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" #include "ThreadGDBRemote.h" @@ -462,7 +458,7 @@ bool GDBRemoteRegisterContext::ReadAllRegisterValues( ((ProcessGDBRemote *)process)->GetGDBRemote()); const bool use_g_packet = - gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false; + !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process); GDBRemoteClientBase::Lock lock(gdb_comm, false); if (lock) { @@ -525,7 +521,7 @@ bool GDBRemoteRegisterContext::WriteAllRegisterValues( ((ProcessGDBRemote *)process)->GetGDBRemote()); const bool use_g_packet = - gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false; + !gdb_comm.AvoidGPackets((ProcessGDBRemote *)process); GDBRemoteClientBase::Lock lock(gdb_comm, false); if (lock) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h index 8ef91af55e0f..6e8f3306669f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h @@ -10,12 +10,8 @@ #ifndef lldb_GDBRemoteRegisterContext_h_ #define lldb_GDBRemoteRegisterContext_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "Plugins/Process/Utility/DynamicRegisterInfo.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/ConstString.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index 13ef8e9503f3..54597dc4e7bf 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -9,12 +9,11 @@ #include "lldb/Host/Config.h" -// C Includes #include #include #ifndef LLDB_DISABLE_POSIX #include -#include // for mmap +#include #include #include #endif @@ -22,7 +21,6 @@ #include #include -// C++ Includes #include #include #include @@ -34,7 +32,6 @@ #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/DataFormatters/FormatManager.h" @@ -68,10 +65,11 @@ #include "lldb/Utility/Args.h" #include "lldb/Utility/CleanUp.h" #include "lldb/Utility/FileSpec.h" +#include "lldb/Utility/Reproducer.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" -// Project includes #include "GDBRemoteRegisterContext.h" #ifdef LLDB_ENABLE_ALL #include "Plugins/Platform/MacOSX/PlatformRemoteiOS.h" @@ -90,6 +88,7 @@ #include "llvm/Support/raw_ostream.h" #define DEBUGSERVER_BASENAME "debugserver" +using namespace llvm; using namespace lldb; using namespace lldb_private; using namespace lldb_private::process_gdb_remote; @@ -103,21 +102,21 @@ namespace lldb { // and get the packet history dumped to a file. void DumpProcessGDBRemotePacketHistory(void *p, const char *path) { StreamFile strm; - Status error(strm.GetFile().Open(path, File::eOpenOptionWrite | - File::eOpenOptionCanCreate)); + Status error = FileSystem::Instance().Open(strm.GetFile(), FileSpec(path), + File::eOpenOptionWrite | + File::eOpenOptionCanCreate); if (error.Success()) ((ProcessGDBRemote *)p)->GetGDBRemote().DumpHistory(strm); } -} +} // namespace lldb namespace { -static PropertyDefinition g_properties[] = { - {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, NULL, +static constexpr PropertyDefinition g_properties[] = { + {"packet-timeout", OptionValue::eTypeUInt64, true, 1, NULL, {}, "Specify the default packet timeout in seconds."}, - {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, NULL, - "The file that provides the description for remote target registers."}, - {NULL, OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL}}; + {"target-definition-file", OptionValue::eTypeFileSpec, true, 0, NULL, {}, + "The file that provides the description for remote target registers."}}; enum { ePropertyPacketTimeout, ePropertyTargetDefinitionFile }; @@ -160,7 +159,42 @@ static const ProcessKDPPropertiesSP &GetGlobalPluginProperties() { return g_settings_sp; } -} // anonymous namespace end +class ProcessGDBRemoteProvider + : public repro::Provider { +public: + ProcessGDBRemoteProvider(const FileSpec &directory) : Provider(directory) { + m_info.name = "gdb-remote"; + m_info.files.push_back("gdb-remote.yaml"); + } + + raw_ostream *GetHistoryStream() { + FileSpec history_file = + GetRoot().CopyByAppendingPathComponent("gdb-remote.yaml"); + + std::error_code EC; + m_stream_up = llvm::make_unique(history_file.GetPath(), EC, + sys::fs::OpenFlags::F_None); + return m_stream_up.get(); + } + + void SetCallback(std::function callback) { + m_callback = std::move(callback); + } + + void Keep() override { m_callback(); } + + void Discard() override { m_callback(); } + + static char ID; + +private: + std::function m_callback; + std::unique_ptr m_stream_up; +}; + +char ProcessGDBRemoteProvider::ID = 0; + +} // namespace // TODO Randomly assigning a port is unsafe. We should get an unused // ephemeral port from the kernel and make sure we reserve it before passing it @@ -236,7 +270,7 @@ bool ProcessGDBRemote::CanDebug(lldb::TargetSP target_sp, case ObjectFile::eTypeUnknown: break; } - return exe_module->GetFileSpec().Exists(); + return FileSystem::Instance().Exists(exe_module->GetFileSpec()); } // However, if there is no executable module, we return true since we might // be preparing to attach. @@ -261,8 +295,8 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, m_addr_to_mmap_size(), m_thread_create_bp_sp(), m_waiting_for_attach(false), m_destroy_tried_resuming(false), m_command_sp(), m_breakpoint_pc_offset(0), - m_initial_tid(LLDB_INVALID_THREAD_ID), m_allow_flash_writes(false), - m_erased_flash_ranges() { + m_initial_tid(LLDB_INVALID_THREAD_ID), m_replay_mode(false), + m_allow_flash_writes(false), m_erased_flash_ranges() { m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadShouldExit, "async thread should exit"); m_async_broadcaster.SetEventName(eBroadcastBitAsyncContinue, @@ -270,6 +304,15 @@ ProcessGDBRemote::ProcessGDBRemote(lldb::TargetSP target_sp, m_async_broadcaster.SetEventName(eBroadcastBitAsyncThreadDidExit, "async thread did exit"); + if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator()) { + ProcessGDBRemoteProvider &provider = + g->GetOrCreate(); + // Set the history stream to the stream owned by the provider. + m_gdb_comm.SetHistoryStream(provider.GetHistoryStream()); + // Make sure to clear the stream again when we're finished. + provider.SetCallback([&]() { m_gdb_comm.SetHistoryStream(nullptr); }); + } + Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_ASYNC)); const uint32_t async_event_mask = @@ -442,10 +485,10 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile(); - if (!target_definition_fspec.Exists()) { + if (!FileSystem::Instance().Exists(target_definition_fspec)) { // If the filename doesn't exist, it may be a ~ not having been expanded - // try to resolve it. - target_definition_fspec.ResolvePath(); + FileSystem::Instance().Resolve(target_definition_fspec); } if (target_definition_fspec) { // See if we can get register definitions from a python file @@ -642,7 +685,7 @@ void ProcessGDBRemote::BuildDynamicRegisterInfo(bool force) { m_register_info.Finalize(GetTarget().GetArchitecture()); } -Status ProcessGDBRemote::WillLaunch(Module *module) { +Status ProcessGDBRemote::WillLaunch(lldb_private::Module *module) { return WillLaunchOrAttach(); } @@ -691,7 +734,9 @@ Status ProcessGDBRemote::DoConnectRemote(Stream *strm, if (m_gdb_comm.GetProcessArchitecture().IsValid()) { target.SetArchitecture(m_gdb_comm.GetProcessArchitecture()); } else { - target.SetArchitecture(m_gdb_comm.GetHostArchitecture()); + if (m_gdb_comm.GetHostArchitecture().IsValid()) { + target.SetArchitecture(m_gdb_comm.GetHostArchitecture()); + } } } @@ -756,7 +801,7 @@ Status ProcessGDBRemote::WillLaunchOrAttach() { //---------------------------------------------------------------------- // Process Control //---------------------------------------------------------------------- -Status ProcessGDBRemote::DoLaunch(Module *exe_module, +Status ProcessGDBRemote::DoLaunch(lldb_private::Module *exe_module, ProcessLaunchInfo &launch_info) { Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); Status error; @@ -826,13 +871,13 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module, if (disable_stdio) { // set to /dev/null unless redirected to a file above if (!stdin_file_spec) - stdin_file_spec.SetFile(FileSystem::DEV_NULL, false, + stdin_file_spec.SetFile(FileSystem::DEV_NULL, FileSpec::Style::native); if (!stdout_file_spec) - stdout_file_spec.SetFile(FileSystem::DEV_NULL, false, + stdout_file_spec.SetFile(FileSystem::DEV_NULL, FileSpec::Style::native); if (!stderr_file_spec) - stderr_file_spec.SetFile(FileSystem::DEV_NULL, false, + stderr_file_spec.SetFile(FileSystem::DEV_NULL, FileSpec::Style::native); } else if (platform_sp && platform_sp->IsHost()) { // If the debugserver is local and we aren't disabling STDIO, lets use @@ -841,7 +886,7 @@ Status ProcessGDBRemote::DoLaunch(Module *exe_module, // does a lot of output. if ((!stdin_file_spec || !stdout_file_spec || !stderr_file_spec) && pty.OpenFirstAvailableMaster(O_RDWR | O_NOCTTY, NULL, 0)) { - FileSpec slave_name{pty.GetSlaveName(NULL, 0), false}; + FileSpec slave_name{pty.GetSlaveName(NULL, 0)}; if (!stdin_file_spec) stdin_file_spec = slave_name; @@ -1060,9 +1105,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf("ProcessGDBRemote::%s gdb-remote had process architecture, " "using %s %s", - __FUNCTION__, process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "", process_arch.GetTriple().getTriple().c_str() ? process_arch.GetTriple().getTriple().c_str() : ""); @@ -1071,9 +1117,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf("ProcessGDBRemote::%s gdb-remote did not have process " "architecture, using gdb-remote host architecture %s %s", - __FUNCTION__, process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "", process_arch.GetTriple().getTriple().c_str() ? process_arch.GetTriple().getTriple().c_str() : ""); @@ -1085,9 +1132,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf( "ProcessGDBRemote::%s analyzing target arch, currently %s %s", - __FUNCTION__, target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "", + __FUNCTION__, + target_arch.GetArchitectureName() + ? target_arch.GetArchitectureName() + : "", target_arch.GetTriple().getTriple().c_str() ? target_arch.GetTriple().getTriple().c_str() : ""); @@ -1107,9 +1155,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf("ProcessGDBRemote::%s remote process is ARM/Apple, " "setting target arch to %s %s", - __FUNCTION__, process_arch.GetArchitectureName() - ? process_arch.GetArchitectureName() - : "", + __FUNCTION__, + process_arch.GetArchitectureName() + ? process_arch.GetArchitectureName() + : "", process_arch.GetTriple().getTriple().c_str() ? process_arch.GetTriple().getTriple().c_str() : ""); @@ -1137,9 +1186,10 @@ void ProcessGDBRemote::DidLaunchOrAttach(ArchSpec &process_arch) { if (log) log->Printf("ProcessGDBRemote::%s final target arch after " "adjustments for remote architecture: %s %s", - __FUNCTION__, target_arch.GetArchitectureName() - ? target_arch.GetArchitectureName() - : "", + __FUNCTION__, + target_arch.GetArchitectureName() + ? target_arch.GetArchitectureName() + : "", target_arch.GetTriple().getTriple().c_str() ? target_arch.GetTriple().getTriple().c_str() : ""); @@ -1480,7 +1530,7 @@ Status ProcessGDBRemote::DoResume() { new EventDataBytes(continue_packet.GetString().data(), continue_packet.GetSize())); - if (listener_sp->GetEvent(event_sp, std::chrono::seconds(5)) == false) { + if (!listener_sp->GetEvent(event_sp, std::chrono::seconds(5))) { error.SetErrorString("Resume timed out."); if (log) log->Printf("ProcessGDBRemote::DoResume: Resume timed out."); @@ -1834,7 +1884,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( bool handled = false; bool did_exec = false; if (!reason.empty()) { - if (reason.compare("trace") == 0) { + if (reason == "trace") { addr_t pc = thread_sp->GetRegisterContext()->GetPC(); lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess() ->GetBreakpointSiteList() @@ -1852,7 +1902,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( thread_sp->SetStopInfo( StopInfo::CreateStopReasonToTrace(*thread_sp)); handled = true; - } else if (reason.compare("breakpoint") == 0) { + } else if (reason == "breakpoint") { addr_t pc = thread_sp->GetRegisterContext()->GetPC(); lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess() ->GetBreakpointSiteList() @@ -1873,9 +1923,9 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( thread_sp->SetStopInfo(invalid_stop_info_sp); } } - } else if (reason.compare("trap") == 0) { + } else if (reason == "trap") { // Let the trap just use the standard signal stop reason below... - } else if (reason.compare("watchpoint") == 0) { + } else if (reason == "watchpoint") { StringExtractor desc_extractor(description.c_str()); addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS); uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32); @@ -1907,11 +1957,11 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithWatchpointID( *thread_sp, watch_id, wp_hit_addr)); handled = true; - } else if (reason.compare("exception") == 0) { + } else if (reason == "exception") { thread_sp->SetStopInfo(StopInfo::CreateStopReasonWithException( *thread_sp, description.c_str())); handled = true; - } else if (reason.compare("exec") == 0) { + } else if (reason == "exec") { did_exec = true; thread_sp->SetStopInfo( StopInfo::CreateStopReasonWithExec(*thread_sp)); @@ -1936,7 +1986,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo( } } - if (!handled && signo && did_exec == false) { + if (!handled && signo && !did_exec) { if (signo == SIGTRAP) { // Currently we are going to assume SIGTRAP means we are either // hitting a breakpoint or hardware single stepping. @@ -2652,7 +2702,7 @@ void ProcessGDBRemote::SetLastStopPacket( // We are are not using non-stop mode, there can only be one last stop // reply packet, so clear the list. - if (GetTarget().GetNonStopModeEnabled() == false) + if (!GetTarget().GetNonStopModeEnabled()) m_stop_packet_stack.clear(); // Add this stop packet to the stop packet stack This stack will get popped @@ -3382,6 +3432,43 @@ Status ProcessGDBRemote::DoSignal(int signo) { return error; } +Status ProcessGDBRemote::ConnectToReplayServer(repro::Loader *loader) { + if (!loader) + return Status("No loader provided."); + + auto provider_info = loader->GetProviderInfo("gdb-remote"); + if (!provider_info) + return Status("No provider for gdb-remote."); + + if (provider_info->files.empty()) + return Status("Provider for gdb-remote contains no files."); + + // Construct replay history path. + FileSpec history_file = loader->GetRoot().CopyByAppendingPathComponent( + provider_info->files.front()); + + // Enable replay mode. + m_replay_mode = true; + + // Load replay history. + if (auto error = m_gdb_replay_server.LoadReplayHistory(history_file)) + return Status("Unable to load replay history"); + + // Make a local connection. + if (auto error = GDBRemoteCommunication::ConnectLocally(m_gdb_comm, + m_gdb_replay_server)) + return Status("Unable to connect to replay server"); + + // Start server thread. + m_gdb_replay_server.StartAsyncThread(); + + // Start client thread. + StartAsyncThread(); + + // Do the usual setup. + return ConnectToDebugserver(""); +} + Status ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) { // Make sure we aren't already connected? @@ -3392,6 +3479,9 @@ ProcessGDBRemote::EstablishConnectionIfNeeded(const ProcessInfo &process_info) { if (platform_sp && !platform_sp->IsHost()) return Status("Lost debug server connection"); + if (repro::Loader *loader = repro::Reproducer::Instance().GetLoader()) + return ConnectToReplayServer(loader); + auto error = LaunchAndConnectToDebugserver(process_info); if (error.Fail()) { const char *error_string = error.AsCString(); @@ -3501,7 +3591,7 @@ bool ProcessGDBRemote::MonitorDebugserverProcess( bool exited, // True if the process did exit int signo, // Zero for no signal int exit_status // Exit value of process if signal is zero - ) { +) { // "debugserver_pid" argument passed in is the process ID for debugserver // that we are tracking... Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS)); @@ -4273,8 +4363,9 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, return false; feature_node.ForEachChildElementWithName( - "reg", [&target_info, &dyn_reg_info, &cur_reg_num, ®_offset, - &abi_sp](const XMLNode ®_node) -> bool { + "reg", + [&target_info, &dyn_reg_info, &cur_reg_num, ®_offset, + &abi_sp](const XMLNode ®_node) -> bool { std::string gdb_group; std::string gdb_type; ConstString reg_name; @@ -4436,7 +4527,7 @@ bool ParseRegisters(XMLNode feature_node, GdbServerTargetInfo &target_info, return true; } -} // namespace {} +} // namespace // query the target of gdb-remote for extended target information return: // 'true' on success @@ -4513,12 +4604,19 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfo(ArchSpec &arch_to_use) { // arm (seen from Segger JLink on unspecified arm board) // use that if we don't have anything better. if (!arch_to_use.IsValid() && !target_info.arch.empty()) { - if (target_info.arch == "i386:x86-64") - { + if (target_info.arch == "i386:x86-64") { // We don't have any information about vendor or OS. arch_to_use.SetTriple("x86_64--"); GetTarget().MergeArchitecture(arch_to_use); } + + // SEGGER J-Link jtag boards send this very-generic arch name, + // we'll need to use this if we have absolutely nothing better + // to work with or the register definitions won't be accepted. + if (target_info.arch == "arm") { + arch_to_use.SetTriple("arm--"); + GetTarget().MergeArchitecture(arch_to_use); + } } // Initialize these outside of ParseRegisters, since they should not be @@ -4764,7 +4862,8 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) { if (!modInfo.get_link_map(link_map)) link_map = LLDB_INVALID_ADDRESS; - FileSpec file(mod_name, true); + FileSpec file(mod_name); + FileSystem::Instance().Resolve(file); lldb::ModuleSP module_sp = LoadModuleAtAddress(file, link_map, mod_base, mod_base_is_offset); @@ -4806,7 +4905,7 @@ size_t ProcessGDBRemote::LoadModules(LoadedModuleInfoList &module_list) { return true; lldb::ModuleSP module_copy_sp = module_sp; - target.SetExecutableModule(module_copy_sp, false); + target.SetExecutableModule(module_copy_sp, eLoadDependentsNo); return false; }); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h index 45bb2d4c28e7..14a5237e4345 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h @@ -10,15 +10,12 @@ #ifndef liblldb_ProcessGDBRemote_h_ #define liblldb_ProcessGDBRemote_h_ -// C Includes -// C++ Includes #include #include #include #include #include -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/LoadedModuleInfoList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/ThreadSafeValue.h" @@ -26,6 +23,7 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/ConstString.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/StreamGDBRemote.h" @@ -36,11 +34,15 @@ #include "lldb/lldb-private-forward.h" #include "GDBRemoteCommunicationClient.h" +#include "GDBRemoteCommunicationReplayServer.h" #include "GDBRemoteRegisterContext.h" #include "llvm/ADT/DenseMap.h" namespace lldb_private { +namespace repro { +class Loader; +} namespace process_gdb_remote { class ThreadGDBRemote; @@ -264,6 +266,7 @@ protected: }; GDBRemoteCommunicationClient m_gdb_comm; + GDBRemoteCommunicationReplayServer m_gdb_replay_server; std::atomic m_debugserver_pid; std::vector m_stop_packet_stack; // The stop packet // stack replaces @@ -304,6 +307,7 @@ protected: int64_t m_breakpoint_pc_offset; lldb::tid_t m_initial_tid; // The initial thread ID, given by stub on attach + bool m_replay_mode; bool m_allow_flash_writes; using FlashRangeVector = lldb_private::RangeVector; using FlashRange = FlashRangeVector::Entry; @@ -331,6 +335,8 @@ protected: bool UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) override; + Status ConnectToReplayServer(repro::Loader *loader); + Status EstablishConnectionIfNeeded(const ProcessInfo &process_info); Status LaunchAndConnectToDebugserver(const ProcessInfo &process_info); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h index 3c5801176690..d4981df88d8d 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h @@ -10,11 +10,7 @@ #ifndef liblldb_ProcessGDBRemoteLog_h_ #define liblldb_ProcessGDBRemoteLog_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Log.h" #define GDBR_LOG_PROCESS (1u << 1) diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp index a525c16b9f13..db7dc3eae0ba 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp @@ -10,7 +10,6 @@ #include "ThreadGDBRemote.h" #include "lldb/Breakpoint/Watchpoint.h" -#include "lldb/Core/State.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -20,6 +19,7 @@ #include "lldb/Target/UnixSignals.h" #include "lldb/Target/Unwind.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "ProcessGDBRemote.h" @@ -197,13 +197,10 @@ void ThreadGDBRemote::SetQueueLibdispatchQueueAddress( } bool ThreadGDBRemote::ThreadHasQueueInformation() const { - if (m_thread_dispatch_qaddr != 0 && - m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS && - m_dispatch_queue_t != LLDB_INVALID_ADDRESS && - m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0) { - return true; - } - return false; + return m_thread_dispatch_qaddr != 0 && + m_thread_dispatch_qaddr != LLDB_INVALID_ADDRESS && + m_dispatch_queue_t != LLDB_INVALID_ADDRESS && + m_queue_kind != eQueueKindUnknown && m_queue_serial_number != 0; } LazyBool ThreadGDBRemote::GetAssociatedWithLibdispatchQueue() { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h index 1a5b60aea288..4485a9cdc4c3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h @@ -10,12 +10,8 @@ #ifndef liblldb_ThreadGDBRemote_h_ #define liblldb_ThreadGDBRemote_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/StructuredData.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp index 9a979335e99e..d4053ca70b94 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.cpp @@ -7,20 +7,19 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "MinidumpParser.h" #include "NtStructures.h" #include "RegisterContextMinidump_x86_32.h" -// Other libraries and framework includes -#include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Utility/LLDBAssert.h" +#include "Plugins/Process/Utility/LinuxProcMaps.h" // C includes // C++ includes #include #include #include +#include using namespace lldb_private; using namespace minidump; @@ -80,8 +79,18 @@ UUID MinidumpParser::GetModuleUUID(const MinidumpModule *module) { // PDB70 record const CvRecordPdb70 *pdb70_uuid = nullptr; Status error = consumeObject(cv_record, pdb70_uuid); - if (!error.Fail()) - return UUID::fromData(pdb70_uuid, sizeof(*pdb70_uuid)); + if (!error.Fail()) { + auto arch = GetArchitecture(); + // For Apple targets we only need a 16 byte UUID so that we can match + // the UUID in the Module to actual UUIDs from the built binaries. The + // "Age" field is zero in breakpad minidump files for Apple targets, so + // we restrict the UUID to the "Uuid" field so we have a UUID we can use + // to match. + if (arch.GetTriple().getVendor() == llvm::Triple::Apple) + return UUID::fromData(pdb70_uuid->Uuid, sizeof(pdb70_uuid->Uuid)); + else + return UUID::fromData(pdb70_uuid, sizeof(*pdb70_uuid)); + } } else if (cv_signature == CvSignature::ElfBuildId) return UUID::fromData(cv_record); @@ -98,11 +107,15 @@ llvm::ArrayRef MinidumpParser::GetThreads() { } llvm::ArrayRef -MinidumpParser::GetThreadContext(const MinidumpThread &td) { - if (td.thread_context.rva + td.thread_context.data_size > GetData().size()) +MinidumpParser::GetThreadContext(const MinidumpLocationDescriptor &location) { + if (location.rva + location.data_size > GetData().size()) return {}; + return GetData().slice(location.rva, location.data_size); +} - return GetData().slice(td.thread_context.rva, td.thread_context.data_size); +llvm::ArrayRef +MinidumpParser::GetThreadContext(const MinidumpThread &td) { + return GetThreadContext(td.thread_context); } llvm::ArrayRef @@ -146,11 +159,14 @@ const MinidumpSystemInfo *MinidumpParser::GetSystemInfo() { } ArchSpec MinidumpParser::GetArchitecture() { - ArchSpec arch_spec; + if (m_arch.IsValid()) + return m_arch; + + // Set the architecture in m_arch const MinidumpSystemInfo *system_info = GetSystemInfo(); if (!system_info) - return arch_spec; + return m_arch; // TODO what to do about big endiand flavors of arm ? // TODO set the arm subarch stuff if the minidump has info about it @@ -196,19 +212,28 @@ ArchSpec MinidumpParser::GetArchitecture() { break; case MinidumpOSPlatform::MacOSX: triple.setOS(llvm::Triple::OSType::MacOSX); + triple.setVendor(llvm::Triple::Apple); + break; + case MinidumpOSPlatform::IOS: + triple.setOS(llvm::Triple::OSType::IOS); + triple.setVendor(llvm::Triple::Apple); break; case MinidumpOSPlatform::Android: triple.setOS(llvm::Triple::OSType::Linux); triple.setEnvironment(llvm::Triple::EnvironmentType::Android); break; - default: + default: { triple.setOS(llvm::Triple::OSType::UnknownOS); + std::string csd_version; + if (auto s = GetMinidumpString(system_info->csd_version_rva)) + csd_version = *s; + if (csd_version.find("Linux") != std::string::npos) + triple.setOS(llvm::Triple::OSType::Linux); break; + } } - - arch_spec.SetTriple(triple); - - return arch_spec; + m_arch.SetTriple(triple); + return m_arch; } const MinidumpMiscInfo *MinidumpParser::GetMiscInfo() { @@ -254,36 +279,45 @@ llvm::ArrayRef MinidumpParser::GetModuleList() { std::vector MinidumpParser::GetFilteredModuleList() { llvm::ArrayRef modules = GetModuleList(); - // map module_name -> pair(load_address, pointer to module struct in memory) - llvm::StringMap> lowest_addr; + // map module_name -> filtered_modules index + typedef llvm::StringMap MapType; + MapType module_name_to_filtered_index; std::vector filtered_modules; - + llvm::Optional name; std::string module_name; for (const auto &module : modules) { name = GetMinidumpString(module.module_name_rva); - + if (!name) continue; - + module_name = name.getValue(); + + MapType::iterator iter; + bool inserted; + // See if we have inserted this module aready into filtered_modules. If we + // haven't insert an entry into module_name_to_filtered_index with the + // index where we will insert it if it isn't in the vector already. + std::tie(iter, inserted) = module_name_to_filtered_index.try_emplace( + module_name, filtered_modules.size()); - auto iter = lowest_addr.end(); - bool exists; - std::tie(iter, exists) = lowest_addr.try_emplace( - module_name, std::make_pair(module.base_of_image, &module)); - - if (exists && module.base_of_image < iter->second.first) - iter->second = std::make_pair(module.base_of_image, &module); + if (inserted) { + // This module has not been seen yet, insert it into filtered_modules at + // the index that was inserted into module_name_to_filtered_index using + // "filtered_modules.size()" above. + filtered_modules.push_back(&module); + } else { + // This module has been seen. Modules are sometimes mentioned multiple + // times when they are mapped discontiguously, so find the module with + // the lowest "base_of_image" and use that as the filtered module. + auto dup_module = filtered_modules[iter->second]; + if (module.base_of_image < dup_module->base_of_image) + filtered_modules[iter->second] = &module; + } } - - filtered_modules.reserve(lowest_addr.size()); - for (const auto &module : lowest_addr) { - filtered_modules.push_back(module.second.second); - } - return filtered_modules; } @@ -381,72 +415,153 @@ llvm::ArrayRef MinidumpParser::GetMemory(lldb::addr_t addr, return range->range_ref.slice(offset, overlap); } -llvm::Optional -MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) { - MemoryRegionInfo info; - llvm::ArrayRef data = GetStream(MinidumpStreamType::MemoryInfoList); +static bool +CreateRegionsCacheFromLinuxMaps(MinidumpParser &parser, + std::vector ®ions) { + auto data = parser.GetStream(MinidumpStreamType::LinuxMaps); if (data.empty()) - return llvm::None; + return false; + ParseLinuxMapRegions(llvm::toStringRef(data), + [&](const lldb_private::MemoryRegionInfo ®ion, + const lldb_private::Status &status) -> bool { + if (status.Success()) + regions.push_back(region); + return true; + }); + return !regions.empty(); +} - std::vector mem_info_list = - MinidumpMemoryInfo::ParseMemoryInfoList(data); +static bool +CreateRegionsCacheFromMemoryInfoList(MinidumpParser &parser, + std::vector ®ions) { + auto data = parser.GetStream(MinidumpStreamType::MemoryInfoList); + if (data.empty()) + return false; + auto mem_info_list = MinidumpMemoryInfo::ParseMemoryInfoList(data); if (mem_info_list.empty()) - return llvm::None; - - const auto yes = MemoryRegionInfo::eYes; - const auto no = MemoryRegionInfo::eNo; - - const MinidumpMemoryInfo *next_entry = nullptr; + return false; + constexpr auto yes = MemoryRegionInfo::eYes; + constexpr auto no = MemoryRegionInfo::eNo; + regions.reserve(mem_info_list.size()); for (const auto &entry : mem_info_list) { - const auto head = entry->base_address; - const auto tail = head + entry->region_size; - - if (head <= load_addr && load_addr < tail) { - info.GetRange().SetRangeBase( - (entry->state != uint32_t(MinidumpMemoryInfoState::MemFree)) - ? head - : load_addr); - info.GetRange().SetRangeEnd(tail); - - const uint32_t PageNoAccess = - static_cast(MinidumpMemoryProtectionContants::PageNoAccess); - info.SetReadable((entry->protect & PageNoAccess) == 0 ? yes : no); - - const uint32_t PageWritable = - static_cast(MinidumpMemoryProtectionContants::PageWritable); - info.SetWritable((entry->protect & PageWritable) != 0 ? yes : no); - - const uint32_t PageExecutable = static_cast( - MinidumpMemoryProtectionContants::PageExecutable); - info.SetExecutable((entry->protect & PageExecutable) != 0 ? yes : no); - - const uint32_t MemFree = - static_cast(MinidumpMemoryInfoState::MemFree); - info.SetMapped((entry->state != MemFree) ? yes : no); - - return info; - } else if (head > load_addr && - (next_entry == nullptr || head < next_entry->base_address)) { - // In case there is no region containing load_addr keep track of the - // nearest region after load_addr so we can return the distance to it. - next_entry = entry; - } + MemoryRegionInfo region; + region.GetRange().SetRangeBase(entry->base_address); + region.GetRange().SetByteSize(entry->region_size); + region.SetReadable(entry->isReadable() ? yes : no); + region.SetWritable(entry->isWritable() ? yes : no); + region.SetExecutable(entry->isExecutable() ? yes : no); + region.SetMapped(entry->isMapped() ? yes : no); + regions.push_back(region); } + return !regions.empty(); +} - // No containing region found. Create an unmapped region that extends to the - // next region or LLDB_INVALID_ADDRESS - info.GetRange().SetRangeBase(load_addr); - info.GetRange().SetRangeEnd((next_entry != nullptr) ? next_entry->base_address - : LLDB_INVALID_ADDRESS); - info.SetReadable(no); - info.SetWritable(no); - info.SetExecutable(no); - info.SetMapped(no); +static bool +CreateRegionsCacheFromMemoryList(MinidumpParser &parser, + std::vector ®ions) { + auto data = parser.GetStream(MinidumpStreamType::MemoryList); + if (data.empty()) + return false; + auto memory_list = MinidumpMemoryDescriptor::ParseMemoryList(data); + if (memory_list.empty()) + return false; + regions.reserve(memory_list.size()); + for (const auto &memory_desc : memory_list) { + if (memory_desc.memory.data_size == 0) + continue; + MemoryRegionInfo region; + region.GetRange().SetRangeBase(memory_desc.start_of_memory_range); + region.GetRange().SetByteSize(memory_desc.memory.data_size); + region.SetReadable(MemoryRegionInfo::eYes); + region.SetMapped(MemoryRegionInfo::eYes); + regions.push_back(region); + } + regions.shrink_to_fit(); + return !regions.empty(); +} - // Note that the memory info list doesn't seem to contain ranges in kernel - // space, so if you're walking a stack that has kernel frames, the stack may - // appear truncated. - return info; +static bool +CreateRegionsCacheFromMemory64List(MinidumpParser &parser, + std::vector ®ions) { + llvm::ArrayRef data = + parser.GetStream(MinidumpStreamType::Memory64List); + if (data.empty()) + return false; + llvm::ArrayRef memory64_list; + uint64_t base_rva; + std::tie(memory64_list, base_rva) = + MinidumpMemoryDescriptor64::ParseMemory64List(data); + + if (memory64_list.empty()) + return false; + + regions.reserve(memory64_list.size()); + for (const auto &memory_desc : memory64_list) { + if (memory_desc.data_size == 0) + continue; + MemoryRegionInfo region; + region.GetRange().SetRangeBase(memory_desc.start_of_memory_range); + region.GetRange().SetByteSize(memory_desc.data_size); + region.SetReadable(MemoryRegionInfo::eYes); + region.SetMapped(MemoryRegionInfo::eYes); + regions.push_back(region); + } + regions.shrink_to_fit(); + return !regions.empty(); +} + +MemoryRegionInfo +MinidumpParser::FindMemoryRegion(lldb::addr_t load_addr) const { + auto begin = m_regions.begin(); + auto end = m_regions.end(); + auto pos = std::lower_bound(begin, end, load_addr); + if (pos != end && pos->GetRange().Contains(load_addr)) + return *pos; + + MemoryRegionInfo region; + if (pos == begin) + region.GetRange().SetRangeBase(0); + else { + auto prev = pos - 1; + if (prev->GetRange().Contains(load_addr)) + return *prev; + region.GetRange().SetRangeBase(prev->GetRange().GetRangeEnd()); + } + if (pos == end) + region.GetRange().SetRangeEnd(UINT64_MAX); + else + region.GetRange().SetRangeEnd(pos->GetRange().GetRangeBase()); + region.SetReadable(MemoryRegionInfo::eNo); + region.SetWritable(MemoryRegionInfo::eNo); + region.SetExecutable(MemoryRegionInfo::eNo); + region.SetMapped(MemoryRegionInfo::eNo); + return region; +} + +MemoryRegionInfo +MinidumpParser::GetMemoryRegionInfo(lldb::addr_t load_addr) { + if (!m_parsed_regions) + GetMemoryRegions(); + return FindMemoryRegion(load_addr); +} + +const MemoryRegionInfos &MinidumpParser::GetMemoryRegions() { + if (!m_parsed_regions) { + m_parsed_regions = true; + // We haven't cached our memory regions yet we will create the region cache + // once. We create the region cache using the best source. We start with + // the linux maps since they are the most complete and have names for the + // regions. Next we try the MemoryInfoList since it has + // read/write/execute/map data, and then fall back to the MemoryList and + // Memory64List to just get a list of the memory that is mapped in this + // core file + if (!CreateRegionsCacheFromLinuxMaps(*this, m_regions)) + if (!CreateRegionsCacheFromMemoryInfoList(*this, m_regions)) + if (!CreateRegionsCacheFromMemoryList(*this, m_regions)) + CreateRegionsCacheFromMemory64List(*this, m_regions); + llvm::sort(m_regions.begin(), m_regions.end()); + } + return m_regions; } Status MinidumpParser::Initialize() { @@ -531,10 +646,10 @@ Status MinidumpParser::Initialize() { } // Sort the file map ranges by start offset - std::sort(minidump_map.begin(), minidump_map.end(), - [](const FileRange &a, const FileRange &b) { - return a.offset < b.offset; - }); + llvm::sort(minidump_map.begin(), minidump_map.end(), + [](const FileRange &a, const FileRange &b) { + return a.offset < b.offset; + }); // Check for overlapping streams/data structures for (size_t i = 1; i < minidump_map.size(); ++i) { @@ -554,3 +669,48 @@ Status MinidumpParser::Initialize() { return error; } + +#define ENUM_TO_CSTR(ST) case (uint32_t)MinidumpStreamType::ST: return #ST + +llvm::StringRef +MinidumpParser::GetStreamTypeAsString(uint32_t stream_type) { + switch (stream_type) { + ENUM_TO_CSTR(Unused); + ENUM_TO_CSTR(Reserved0); + ENUM_TO_CSTR(Reserved1); + ENUM_TO_CSTR(ThreadList); + ENUM_TO_CSTR(ModuleList); + ENUM_TO_CSTR(MemoryList); + ENUM_TO_CSTR(Exception); + ENUM_TO_CSTR(SystemInfo); + ENUM_TO_CSTR(ThreadExList); + ENUM_TO_CSTR(Memory64List); + ENUM_TO_CSTR(CommentA); + ENUM_TO_CSTR(CommentW); + ENUM_TO_CSTR(HandleData); + ENUM_TO_CSTR(FunctionTable); + ENUM_TO_CSTR(UnloadedModuleList); + ENUM_TO_CSTR(MiscInfo); + ENUM_TO_CSTR(MemoryInfoList); + ENUM_TO_CSTR(ThreadInfoList); + ENUM_TO_CSTR(HandleOperationList); + ENUM_TO_CSTR(Token); + ENUM_TO_CSTR(JavascriptData); + ENUM_TO_CSTR(SystemMemoryInfo); + ENUM_TO_CSTR(ProcessVMCounters); + ENUM_TO_CSTR(BreakpadInfo); + ENUM_TO_CSTR(AssertionInfo); + ENUM_TO_CSTR(LinuxCPUInfo); + ENUM_TO_CSTR(LinuxProcStatus); + ENUM_TO_CSTR(LinuxLSBRelease); + ENUM_TO_CSTR(LinuxCMDLine); + ENUM_TO_CSTR(LinuxEnviron); + ENUM_TO_CSTR(LinuxAuxv); + ENUM_TO_CSTR(LinuxMaps); + ENUM_TO_CSTR(LinuxDSODebug); + ENUM_TO_CSTR(LinuxProcStat); + ENUM_TO_CSTR(LinuxProcUptime); + ENUM_TO_CSTR(LinuxProcFD); + } + return "unknown stream type"; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.h index 49b1eef14de5..07ea6aa908ff 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpParser.h @@ -1,5 +1,4 @@ -//===-- MinidumpParser.h -----------------------------------------*- C++ -//-*-===// +//===-- MinidumpParser.h -----------------------------------------*- C++-*-===// // // The LLVM Compiler Infrastructure // @@ -11,9 +10,9 @@ #ifndef liblldb_MinidumpParser_h_ #define liblldb_MinidumpParser_h_ -// Project includes #include "MinidumpTypes.h" +#include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/Status.h" @@ -59,6 +58,9 @@ public: llvm::ArrayRef GetThreads(); + llvm::ArrayRef + GetThreadContext(const MinidumpLocationDescriptor &location); + llvm::ArrayRef GetThreadContext(const MinidumpThread &td); llvm::ArrayRef GetThreadContextWow64(const MinidumpThread &td); @@ -87,17 +89,31 @@ public: llvm::ArrayRef GetMemory(lldb::addr_t addr, size_t size); - llvm::Optional GetMemoryRegionInfo(lldb::addr_t); + MemoryRegionInfo GetMemoryRegionInfo(lldb::addr_t load_addr); + + const MemoryRegionInfos &GetMemoryRegions(); // Perform consistency checks and initialize internal data structures Status Initialize(); + static llvm::StringRef GetStreamTypeAsString(uint32_t stream_type); + + const llvm::DenseMap & + GetDirectoryMap() const { + return m_directory_map; + } + private: MinidumpParser(const lldb::DataBufferSP &data_buf_sp); + MemoryRegionInfo FindMemoryRegion(lldb::addr_t load_addr) const; + private: lldb::DataBufferSP m_data_sp; llvm::DenseMap m_directory_map; + ArchSpec m_arch; + MemoryRegionInfos m_regions; + bool m_parsed_regions = false; }; } // end namespace minidump diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp index 049704ba80ca..7b1900e34ef1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.cpp @@ -7,10 +7,8 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "MinidumpTypes.h" -// Other libraries and framework includes // C includes // C++ includes @@ -244,6 +242,8 @@ MinidumpMemoryInfo::ParseMemoryInfoList(llvm::ArrayRef &data) { return {}; std::vector result; + result.reserve(header->num_of_entries); + for (uint64_t i = 0; i < header->num_of_entries; ++i) { result.push_back(reinterpret_cast( data.data() + i * header->size_of_entry)); diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h index e83089865b9e..a5ea215d2548 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/MinidumpTypes.h @@ -10,9 +10,7 @@ #ifndef liblldb_MinidumpTypes_h_ #define liblldb_MinidumpTypes_h_ -// Project includes -// Other libraries and framework includes #include "lldb/Utility/Status.h" #include "llvm/ADT/ArrayRef.h" @@ -98,7 +96,10 @@ enum class MinidumpStreamType : uint32_t { LinuxEnviron = 0x47670007, /* /proc/$x/environ */ LinuxAuxv = 0x47670008, /* /proc/$x/auxv */ LinuxMaps = 0x47670009, /* /proc/$x/maps */ - LinuxDSODebug = 0x4767000A + LinuxDSODebug = 0x4767000A, + LinuxProcStat = 0x4767000B, /* /proc/$x/stat */ + LinuxProcUptime = 0x4767000C, /* uptime */ + LinuxProcFD = 0x4767000D, /* /proc/$x/fb */ }; // for MinidumpSystemInfo.processor_arch @@ -258,25 +259,6 @@ struct MinidumpMemoryInfoListHeader { static_assert(sizeof(MinidumpMemoryInfoListHeader) == 16, "sizeof MinidumpMemoryInfoListHeader is not correct!"); -// Reference: -// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx -struct MinidumpMemoryInfo { - llvm::support::ulittle64_t base_address; - llvm::support::ulittle64_t allocation_base; - llvm::support::ulittle32_t allocation_protect; - llvm::support::ulittle32_t alignment1; - llvm::support::ulittle64_t region_size; - llvm::support::ulittle32_t state; - llvm::support::ulittle32_t protect; - llvm::support::ulittle32_t type; - llvm::support::ulittle32_t alignment2; - - static std::vector - ParseMemoryInfoList(llvm::ArrayRef &data); -}; -static_assert(sizeof(MinidumpMemoryInfo) == 48, - "sizeof MinidumpMemoryInfo is not correct!"); - enum class MinidumpMemoryInfoState : uint32_t { MemCommit = 0x1000, MemFree = 0x10000, @@ -312,6 +294,45 @@ enum class MinidumpMemoryProtectionContants : uint32_t { LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ PageTargetsInvalid) }; +// Reference: +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680386(v=vs.85).aspx +struct MinidumpMemoryInfo { + llvm::support::ulittle64_t base_address; + llvm::support::ulittle64_t allocation_base; + llvm::support::ulittle32_t allocation_protect; + llvm::support::ulittle32_t alignment1; + llvm::support::ulittle64_t region_size; + llvm::support::ulittle32_t state; + llvm::support::ulittle32_t protect; + llvm::support::ulittle32_t type; + llvm::support::ulittle32_t alignment2; + + static std::vector + ParseMemoryInfoList(llvm::ArrayRef &data); + + bool isReadable() const { + const auto mask = MinidumpMemoryProtectionContants::PageNoAccess; + return (static_cast(mask) & protect) == 0; + } + + bool isWritable() const { + const auto mask = MinidumpMemoryProtectionContants::PageWritable; + return (static_cast(mask) & protect) != 0; + } + + bool isExecutable() const { + const auto mask = MinidumpMemoryProtectionContants::PageExecutable; + return (static_cast(mask) & protect) != 0; + } + + bool isMapped() const { + return state != static_cast(MinidumpMemoryInfoState::MemFree); + } +}; + +static_assert(sizeof(MinidumpMemoryInfo) == 48, + "sizeof MinidumpMemoryInfo is not correct!"); + // Reference: // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680517(v=vs.85).aspx struct MinidumpThread { diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp index b43f22382eac..c5cca7ea62c6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.cpp @@ -7,28 +7,34 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "ProcessMinidump.h" #include "ThreadMinidump.h" -// Other libraries and framework includes +#include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/Section.h" -#include "lldb/Core/State.h" -#include "lldb/Target/DynamicLoader.h" +#include "lldb/Interpreter/CommandInterpreter.h" +#include "lldb/Interpreter/CommandObject.h" +#include "lldb/Interpreter/CommandObjectMultiword.h" +#include "lldb/Interpreter/CommandReturnObject.h" +#include "lldb/Interpreter/OptionArgParser.h" +#include "lldb/Interpreter/OptionGroupBoolean.h" +#include "lldb/Target/JITLoaderList.h" #include "lldb/Target/MemoryRegionInfo.h" #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/Target.h" #include "lldb/Target/UnixSignals.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Threading.h" +#include "Plugins/Process/Utility/StopInfoMachException.h" + // C includes // C++ includes @@ -75,7 +81,7 @@ public: section_sp, module->base_of_image); } - ObjectFile *GetObjectFile() override { return nullptr; } +ObjectFile *GetObjectFile() override { return nullptr; } SectionList *GetSectionList() override { return Module::GetUnifiedSectionList(); @@ -100,8 +106,8 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp, lldb::ProcessSP process_sp; // Read enough data for the Minidump header constexpr size_t header_size = sizeof(MinidumpHeader); - auto DataPtr = - DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), header_size, 0); + auto DataPtr = FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), + header_size, 0); if (!DataPtr) return nullptr; @@ -113,7 +119,8 @@ lldb::ProcessSP ProcessMinidump::CreateInstance(lldb::TargetSP target_sp, if (header == nullptr) return nullptr; - auto AllData = DataBufferLLVM::CreateSliceFromPath(crash_file->GetPath(), -1, 0); + auto AllData = + FileSystem::Instance().CreateDataBuffer(crash_file->GetPath(), -1, 0); if (!AllData) return nullptr; @@ -174,19 +181,21 @@ Status ProcessMinidump::DoLoadCore() { switch (arch.GetMachine()) { case llvm::Triple::x86: case llvm::Triple::x86_64: - // supported + case llvm::Triple::arm: + case llvm::Triple::aarch64: + // Any supported architectures must be listed here and also supported in + // ThreadMinidump::CreateRegisterContextForFrame(). break; - default: error.SetErrorStringWithFormat("unsupported minidump architecture: %s", arch.GetArchitectureName()); return error; } + GetTarget().SetArchitecture(arch, true /*set_platform*/); m_thread_list = m_minidump_parser.GetThreads(); m_active_exception = m_minidump_parser.GetExceptionStream(); ReadModuleList(); - GetTarget().SetArchitecture(arch); llvm::Optional pid = m_minidump_parser.GetPid(); if (!pid) { @@ -198,12 +207,6 @@ Status ProcessMinidump::DoLoadCore() { return error; } -DynamicLoader *ProcessMinidump::GetDynamicLoader() { - if (m_dyld_ap.get() == nullptr) - m_dyld_ap.reset(DynamicLoader::FindPlugin(this, nullptr)); - return m_dyld_ap.get(); -} - ConstString ProcessMinidump::GetPluginName() { return GetPluginNameStatic(); } uint32_t ProcessMinidump::GetPluginVersion() { return 1; } @@ -229,6 +232,11 @@ void ProcessMinidump::RefreshStateAfterStop() { if (arch.GetTriple().getOS() == llvm::Triple::Linux) { stop_info = StopInfo::CreateStopReasonWithSignal( *stop_thread, m_active_exception->exception_record.exception_code); + } else if (arch.GetTriple().getVendor() == llvm::Triple::Apple) { + stop_info = StopInfoMachException::CreateStopReasonWithMachException( + *stop_thread, m_active_exception->exception_record.exception_code, 2, + m_active_exception->exception_record.exception_flags, + m_active_exception->exception_record.exception_address, 0); } else { std::string desc; llvm::raw_string_ostream desc_stream(desc); @@ -284,33 +292,36 @@ ArchSpec ProcessMinidump::GetArchitecture() { Status ProcessMinidump::GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) { - Status error; - auto info = m_minidump_parser.GetMemoryRegionInfo(load_addr); - if (!info) { - error.SetErrorString("No valid MemoryRegionInfo found!"); - return error; - } - range_info = info.getValue(); - return error; + range_info = m_minidump_parser.GetMemoryRegionInfo(load_addr); + return Status(); +} + +Status ProcessMinidump::GetMemoryRegions( + lldb_private::MemoryRegionInfos ®ion_list) { + region_list = m_minidump_parser.GetMemoryRegions(); + return Status(); } void ProcessMinidump::Clear() { Process::m_thread_list.Clear(); } bool ProcessMinidump::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list) { - uint32_t num_threads = 0; - if (m_thread_list.size() > 0) - num_threads = m_thread_list.size(); + for (const MinidumpThread& thread : m_thread_list) { + MinidumpLocationDescriptor context_location = thread.thread_context; + + // If the minidump contains an exception context, use it + if (m_active_exception != nullptr && + m_active_exception->thread_id == thread.thread_id) { + context_location = m_active_exception->thread_context; + } - for (lldb::tid_t tid = 0; tid < num_threads; ++tid) { llvm::ArrayRef context; if (!m_is_wow64) - context = m_minidump_parser.GetThreadContext(m_thread_list[tid]); + context = m_minidump_parser.GetThreadContext(context_location); else - context = m_minidump_parser.GetThreadContextWow64(m_thread_list[tid]); + context = m_minidump_parser.GetThreadContextWow64(thread); - lldb::ThreadSP thread_sp( - new ThreadMinidump(*this, m_thread_list[tid], context)); + lldb::ThreadSP thread_sp(new ThreadMinidump(*this, thread, context)); new_thread_list.AddThread(thread_sp); } return new_thread_list.GetSize(false) > 0; @@ -344,8 +355,8 @@ void ProcessMinidump::ReadModuleList() { } const auto uuid = m_minidump_parser.GetModuleUUID(module); - const auto file_spec = - FileSpec(name.getValue(), true, GetArchitecture().GetTriple()); + auto file_spec = FileSpec(name.getValue(), GetArchitecture().GetTriple()); + FileSystem::Instance().Resolve(file_spec); ModuleSpec module_spec(file_spec, uuid); Status error; lldb::ModuleSP module_sp = GetTarget().GetSharedModule(module_spec, &error); @@ -357,6 +368,12 @@ void ProcessMinidump::ReadModuleList() { // This enables most LLDB functionality involving address-to-module // translations (ex. identifing the module for a stack frame PC) and // modules/sections commands (ex. target modules list, ...) + if (log) { + log->Printf("Unable to locate the matching object file, creating a " + "placeholder module for: %s", + name.getValue().c_str()); + } + auto placeholder_module = std::make_shared(module_spec); placeholder_module->CreateImageSection(module, GetTarget()); @@ -387,3 +404,248 @@ bool ProcessMinidump::GetProcessInfo(ProcessInstanceInfo &info) { } return true; } + +// For minidumps there's no runtime generated code so we don't need JITLoader(s) +// Avoiding them will also speed up minidump loading since JITLoaders normally +// try to set up symbolic breakpoints, which in turn may force loading more +// debug information than needed. +JITLoaderList &ProcessMinidump::GetJITLoaders() { + if (!m_jit_loaders_ap) { + m_jit_loaders_ap = llvm::make_unique(); + } + return *m_jit_loaders_ap; +} + +#define INIT_BOOL(VAR, LONG, SHORT, DESC) \ + VAR(LLDB_OPT_SET_1, false, LONG, SHORT, DESC, false, true) +#define APPEND_OPT(VAR) \ + m_option_group.Append(&VAR, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1) + +class CommandObjectProcessMinidumpDump : public CommandObjectParsed { +private: + OptionGroupOptions m_option_group; + OptionGroupBoolean m_dump_all; + OptionGroupBoolean m_dump_directory; + OptionGroupBoolean m_dump_linux_cpuinfo; + OptionGroupBoolean m_dump_linux_proc_status; + OptionGroupBoolean m_dump_linux_lsb_release; + OptionGroupBoolean m_dump_linux_cmdline; + OptionGroupBoolean m_dump_linux_environ; + OptionGroupBoolean m_dump_linux_auxv; + OptionGroupBoolean m_dump_linux_maps; + OptionGroupBoolean m_dump_linux_proc_stat; + OptionGroupBoolean m_dump_linux_proc_uptime; + OptionGroupBoolean m_dump_linux_proc_fd; + OptionGroupBoolean m_dump_linux_all; + + void SetDefaultOptionsIfNoneAreSet() { + if (m_dump_all.GetOptionValue().GetCurrentValue() || + m_dump_linux_all.GetOptionValue().GetCurrentValue() || + m_dump_directory.GetOptionValue().GetCurrentValue() || + m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue() || + m_dump_linux_proc_status.GetOptionValue().GetCurrentValue() || + m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue() || + m_dump_linux_cmdline.GetOptionValue().GetCurrentValue() || + m_dump_linux_environ.GetOptionValue().GetCurrentValue() || + m_dump_linux_auxv.GetOptionValue().GetCurrentValue() || + m_dump_linux_maps.GetOptionValue().GetCurrentValue() || + m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue() || + m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue() || + m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue()) + return; + // If no options were set, then dump everything + m_dump_all.GetOptionValue().SetCurrentValue(true); + } + bool DumpAll() const { + return m_dump_all.GetOptionValue().GetCurrentValue(); + } + bool DumpDirectory() const { + return DumpAll() || + m_dump_directory.GetOptionValue().GetCurrentValue(); + } + bool DumpLinux() const { + return DumpAll() || m_dump_linux_all.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxCPUInfo() const { + return DumpLinux() || + m_dump_linux_cpuinfo.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxProcStatus() const { + return DumpLinux() || + m_dump_linux_proc_status.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxProcStat() const { + return DumpLinux() || + m_dump_linux_proc_stat.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxLSBRelease() const { + return DumpLinux() || + m_dump_linux_lsb_release.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxCMDLine() const { + return DumpLinux() || + m_dump_linux_cmdline.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxEnviron() const { + return DumpLinux() || + m_dump_linux_environ.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxAuxv() const { + return DumpLinux() || + m_dump_linux_auxv.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxMaps() const { + return DumpLinux() || + m_dump_linux_maps.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxProcUptime() const { + return DumpLinux() || + m_dump_linux_proc_uptime.GetOptionValue().GetCurrentValue(); + } + bool DumpLinuxProcFD() const { + return DumpLinux() || + m_dump_linux_proc_fd.GetOptionValue().GetCurrentValue(); + } +public: + + CommandObjectProcessMinidumpDump(CommandInterpreter &interpreter) + : CommandObjectParsed(interpreter, "process plugin dump", + "Dump information from the minidump file.", NULL), + m_option_group(), + INIT_BOOL(m_dump_all, "all", 'a', + "Dump the everything in the minidump."), + INIT_BOOL(m_dump_directory, "directory", 'd', + "Dump the minidump directory map."), + INIT_BOOL(m_dump_linux_cpuinfo, "cpuinfo", 'C', + "Dump linux /proc/cpuinfo."), + INIT_BOOL(m_dump_linux_proc_status, "status", 's', + "Dump linux /proc//status."), + INIT_BOOL(m_dump_linux_lsb_release, "lsb-release", 'r', + "Dump linux /etc/lsb-release."), + INIT_BOOL(m_dump_linux_cmdline, "cmdline", 'c', + "Dump linux /proc//cmdline."), + INIT_BOOL(m_dump_linux_environ, "environ", 'e', + "Dump linux /proc//environ."), + INIT_BOOL(m_dump_linux_auxv, "auxv", 'x', + "Dump linux /proc//auxv."), + INIT_BOOL(m_dump_linux_maps, "maps", 'm', + "Dump linux /proc//maps."), + INIT_BOOL(m_dump_linux_proc_stat, "stat", 'S', + "Dump linux /proc//stat."), + INIT_BOOL(m_dump_linux_proc_uptime, "uptime", 'u', + "Dump linux process uptime."), + INIT_BOOL(m_dump_linux_proc_fd, "fd", 'f', + "Dump linux /proc//fd."), + INIT_BOOL(m_dump_linux_all, "linux", 'l', + "Dump all linux streams.") { + APPEND_OPT(m_dump_all); + APPEND_OPT(m_dump_directory); + APPEND_OPT(m_dump_linux_cpuinfo); + APPEND_OPT(m_dump_linux_proc_status); + APPEND_OPT(m_dump_linux_lsb_release); + APPEND_OPT(m_dump_linux_cmdline); + APPEND_OPT(m_dump_linux_environ); + APPEND_OPT(m_dump_linux_auxv); + APPEND_OPT(m_dump_linux_maps); + APPEND_OPT(m_dump_linux_proc_stat); + APPEND_OPT(m_dump_linux_proc_uptime); + APPEND_OPT(m_dump_linux_proc_fd); + APPEND_OPT(m_dump_linux_all); + m_option_group.Finalize(); + } + + ~CommandObjectProcessMinidumpDump() {} + + Options *GetOptions() override { return &m_option_group; } + + bool DoExecute(Args &command, CommandReturnObject &result) override { + const size_t argc = command.GetArgumentCount(); + if (argc > 0) { + result.AppendErrorWithFormat("'%s' take no arguments, only options", + m_cmd_name.c_str()); + result.SetStatus(eReturnStatusFailed); + return false; + } + SetDefaultOptionsIfNoneAreSet(); + + ProcessMinidump *process = static_cast( + m_interpreter.GetExecutionContext().GetProcessPtr()); + result.SetStatus(eReturnStatusSuccessFinishResult); + Stream &s = result.GetOutputStream(); + MinidumpParser &minidump = process->m_minidump_parser; + if (DumpDirectory()) { + s.Printf("RVA SIZE TYPE MinidumpStreamType\n"); + s.Printf("---------- ---------- ---------- --------------------------\n"); + for (const auto &pair: minidump.GetDirectoryMap()) + s.Printf("0x%8.8x 0x%8.8x 0x%8.8x %s\n", (uint32_t)pair.second.rva, + (uint32_t)pair.second.data_size, pair.first, + MinidumpParser::GetStreamTypeAsString(pair.first).data()); + s.Printf("\n"); + } + auto DumpTextStream = [&](MinidumpStreamType stream_type, + llvm::StringRef label) -> void { + auto bytes = minidump.GetStream(stream_type); + if (!bytes.empty()) { + if (label.empty()) + label = MinidumpParser::GetStreamTypeAsString((uint32_t)stream_type); + s.Printf("%s:\n%s\n\n", label.data(), bytes.data()); + } + }; + auto DumpBinaryStream = [&](MinidumpStreamType stream_type, + llvm::StringRef label) -> void { + auto bytes = minidump.GetStream(stream_type); + if (!bytes.empty()) { + if (label.empty()) + label = MinidumpParser::GetStreamTypeAsString((uint32_t)stream_type); + s.Printf("%s:\n", label.data()); + DataExtractor data(bytes.data(), bytes.size(), eByteOrderLittle, + process->GetAddressByteSize()); + DumpDataExtractor(data, &s, 0, lldb::eFormatBytesWithASCII, 1, + bytes.size(), 16, 0, 0, 0); + s.Printf("\n\n"); + } + }; + + if (DumpLinuxCPUInfo()) + DumpTextStream(MinidumpStreamType::LinuxCPUInfo, "/proc/cpuinfo"); + if (DumpLinuxProcStatus()) + DumpTextStream(MinidumpStreamType::LinuxProcStatus, "/proc/PID/status"); + if (DumpLinuxLSBRelease()) + DumpTextStream(MinidumpStreamType::LinuxLSBRelease, "/etc/lsb-release"); + if (DumpLinuxCMDLine()) + DumpTextStream(MinidumpStreamType::LinuxCMDLine, "/proc/PID/cmdline"); + if (DumpLinuxEnviron()) + DumpTextStream(MinidumpStreamType::LinuxEnviron, "/proc/PID/environ"); + if (DumpLinuxAuxv()) + DumpBinaryStream(MinidumpStreamType::LinuxAuxv, "/proc/PID/auxv"); + if (DumpLinuxMaps()) + DumpTextStream(MinidumpStreamType::LinuxMaps, "/proc/PID/maps"); + if (DumpLinuxProcStat()) + DumpTextStream(MinidumpStreamType::LinuxProcStat, "/proc/PID/stat"); + if (DumpLinuxProcUptime()) + DumpTextStream(MinidumpStreamType::LinuxProcUptime, "uptime"); + if (DumpLinuxProcFD()) + DumpTextStream(MinidumpStreamType::LinuxProcFD, "/proc/PID/fd"); + return true; + } +}; + +class CommandObjectMultiwordProcessMinidump : public CommandObjectMultiword { +public: + CommandObjectMultiwordProcessMinidump(CommandInterpreter &interpreter) + : CommandObjectMultiword(interpreter, "process plugin", + "Commands for operating on a ProcessMinidump process.", + "process plugin []") { + LoadSubCommand("dump", + CommandObjectSP(new CommandObjectProcessMinidumpDump(interpreter))); + } + + ~CommandObjectMultiwordProcessMinidump() {} +}; + +CommandObject *ProcessMinidump::GetPluginCommandObject() { + if (!m_command_sp) + m_command_sp.reset(new CommandObjectMultiwordProcessMinidump( + GetTarget().GetDebugger().GetCommandInterpreter())); + return m_command_sp.get(); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.h index d65ada9009a7..30347b79e1c1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ProcessMinidump.h @@ -10,11 +10,9 @@ #ifndef liblldb_ProcessMinidump_h_ #define liblldb_ProcessMinidump_h_ -// Project includes #include "MinidumpParser.h" #include "MinidumpTypes.h" -// Other libraries and framework includes #include "lldb/Target/Process.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/Target.h" @@ -24,8 +22,6 @@ #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" -// C Includes -// C++ Includes namespace lldb_private { @@ -53,9 +49,11 @@ public: bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override; + CommandObject *GetPluginCommandObject() override; + Status DoLoadCore() override; - DynamicLoader *GetDynamicLoader() override; + DynamicLoader *GetDynamicLoader() override { return nullptr; } ConstString GetPluginName() override; @@ -82,6 +80,9 @@ public: Status GetMemoryRegionInfo(lldb::addr_t load_addr, MemoryRegionInfo &range_info) override; + Status GetMemoryRegions( + lldb_private::MemoryRegionInfos ®ion_list) override; + bool GetProcessInfo(ProcessInstanceInfo &info) override; Status WillResume() override { @@ -102,10 +103,13 @@ protected: void ReadModuleList(); + JITLoaderList &GetJITLoaders() override; + private: FileSpec m_core_file; llvm::ArrayRef m_thread_list; const MinidumpExceptionStream *m_active_exception; + lldb::CommandObjectSP m_command_sp; bool m_is_wow64; }; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp new file mode 100644 index 000000000000..93c3ba70b9e7 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.cpp @@ -0,0 +1,532 @@ +//===-- RegisterContextMinidump_ARM.cpp -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextMinidump_ARM.h" + +#include "Utility/ARM_DWARF_Registers.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/lldb-enumerations.h" + +// C includes +#include + +// C++ includes + +using namespace lldb; +using namespace lldb_private; +using namespace minidump; + +#define INV LLDB_INVALID_REGNUM +#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM::Context, r)) + +#define DEF_R(i) \ + { \ + "r" #i, nullptr, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ + {INV, dwarf_r##i, INV, INV, reg_r##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_R_ARG(i, n) \ + { \ + "r" #i, "arg" #n, 4, OFFSET(r) + i * 4, eEncodingUint, eFormatHex, \ + {INV, dwarf_r##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_r##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_D(i) \ + { \ + "d" #i, nullptr, 8, OFFSET(d) + i * 8, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, dwarf_d##i, INV, INV, reg_d##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_S(i) \ + { \ + "s" #i, nullptr, 4, OFFSET(s) + i * 4, eEncodingIEEE754, eFormatFloat, \ + {INV, dwarf_s##i, INV, INV, reg_s##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_Q(i) \ + { \ + "q" #i, nullptr, 16, OFFSET(q) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, dwarf_q##i, INV, INV, reg_q##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +// Zero based LLDB register numbers for this register context +enum { + // General Purpose Registers + reg_r0, + reg_r1, + reg_r2, + reg_r3, + reg_r4, + reg_r5, + reg_r6, + reg_r7, + reg_r8, + reg_r9, + reg_r10, + reg_r11, + reg_r12, + reg_sp, + reg_lr, + reg_pc, + reg_cpsr, + // Floating Point Registers + reg_fpscr, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_q0, + reg_q1, + reg_q2, + reg_q3, + reg_q4, + reg_q5, + reg_q6, + reg_q7, + reg_q8, + reg_q9, + reg_q10, + reg_q11, + reg_q12, + reg_q13, + reg_q14, + reg_q15, + k_num_regs +}; + +static RegisterInfo g_reg_info_apple_fp = { + "fp", + "r7", + 4, + OFFSET(r) + 7 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_r7, LLDB_REGNUM_GENERIC_FP, INV, reg_r7}, + nullptr, + nullptr, + nullptr, + 0}; + +static RegisterInfo g_reg_info_fp = { + "fp", + "r11", + 4, + OFFSET(r) + 11 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_r11, LLDB_REGNUM_GENERIC_FP, INV, reg_r11}, + nullptr, + nullptr, + nullptr, + 0}; + +// Register info definitions for this register context +static RegisterInfo g_reg_infos[] = { + DEF_R_ARG(0, 1), + DEF_R_ARG(1, 2), + DEF_R_ARG(2, 3), + DEF_R_ARG(3, 4), + DEF_R(4), + DEF_R(5), + DEF_R(6), + DEF_R(7), + DEF_R(8), + DEF_R(9), + DEF_R(10), + DEF_R(11), + DEF_R(12), + {"sp", + "r13", + 4, + OFFSET(r) + 13 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_sp, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "r14", + 4, + OFFSET(r) + 14 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_lr, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + "r15", + 4, + OFFSET(r) + 15 * 4, + eEncodingUint, + eFormatHex, + {INV, dwarf_pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + nullptr, + nullptr, + nullptr, + 0}, + {"cpsr", + "psr", + 4, + OFFSET(cpsr), + eEncodingUint, + eFormatHex, + {INV, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpscr", + nullptr, + 8, + OFFSET(fpscr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpscr}, + nullptr, + nullptr, + nullptr, + 0}, + DEF_D(0), + DEF_D(1), + DEF_D(2), + DEF_D(3), + DEF_D(4), + DEF_D(5), + DEF_D(6), + DEF_D(7), + DEF_D(8), + DEF_D(9), + DEF_D(10), + DEF_D(11), + DEF_D(12), + DEF_D(13), + DEF_D(14), + DEF_D(15), + DEF_D(16), + DEF_D(17), + DEF_D(18), + DEF_D(19), + DEF_D(20), + DEF_D(21), + DEF_D(22), + DEF_D(23), + DEF_D(24), + DEF_D(25), + DEF_D(26), + DEF_D(27), + DEF_D(28), + DEF_D(29), + DEF_D(30), + DEF_D(31), + DEF_S(0), + DEF_S(1), + DEF_S(2), + DEF_S(3), + DEF_S(4), + DEF_S(5), + DEF_S(6), + DEF_S(7), + DEF_S(8), + DEF_S(9), + DEF_S(10), + DEF_S(11), + DEF_S(12), + DEF_S(13), + DEF_S(14), + DEF_S(15), + DEF_S(16), + DEF_S(17), + DEF_S(18), + DEF_S(19), + DEF_S(20), + DEF_S(21), + DEF_S(22), + DEF_S(23), + DEF_S(24), + DEF_S(25), + DEF_S(26), + DEF_S(27), + DEF_S(28), + DEF_S(29), + DEF_S(30), + DEF_S(31), + DEF_Q(0), + DEF_Q(1), + DEF_Q(2), + DEF_Q(3), + DEF_Q(4), + DEF_Q(5), + DEF_Q(6), + DEF_Q(7), + DEF_Q(8), + DEF_Q(9), + DEF_Q(10), + DEF_Q(11), + DEF_Q(12), + DEF_Q(13), + DEF_Q(14), + DEF_Q(15)}; + +constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); + +// ARM general purpose registers. +const uint32_t g_gpr_regnums[] = { + reg_r0, + reg_r1, + reg_r2, + reg_r3, + reg_r4, + reg_r5, + reg_r6, + reg_r7, + reg_r8, + reg_r9, + reg_r10, + reg_r11, + reg_r12, + reg_sp, + reg_lr, + reg_pc, + reg_cpsr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +const uint32_t g_fpu_regnums[] = { + reg_fpscr, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_q0, + reg_q1, + reg_q2, + reg_q3, + reg_q4, + reg_q5, + reg_q6, + reg_q7, + reg_q8, + reg_q9, + reg_q10, + reg_q11, + reg_q12, + reg_q13, + reg_q14, + reg_q15, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 +constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; +constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; + +static RegisterSet g_reg_sets[] = { + {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, + {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, +}; + +constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); + +RegisterContextMinidump_ARM::RegisterContextMinidump_ARM( + Thread &thread, const DataExtractor &data, bool apple) + : RegisterContext(thread, 0), m_apple(apple) { + lldb::offset_t offset = 0; + m_regs.context_flags = data.GetU32(&offset); + for (unsigned i = 0; i < llvm::array_lengthof(m_regs.r); ++i) + m_regs.r[i] = data.GetU32(&offset); + m_regs.cpsr = data.GetU32(&offset); + m_regs.fpscr = data.GetU64(&offset); + for (unsigned i = 0; i < llvm::array_lengthof(m_regs.d); ++i) + m_regs.d[i] = data.GetU64(&offset); + lldbassert(k_num_regs == k_num_reg_infos); +} + +size_t RegisterContextMinidump_ARM::GetRegisterCount() { return k_num_regs; } + +const RegisterInfo * +RegisterContextMinidump_ARM::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_reg_infos) { + if (m_apple) { + if (reg == reg_r7) + return &g_reg_info_apple_fp; + } else { + if (reg == reg_r11) + return &g_reg_info_fp; + } + return &g_reg_infos[reg]; + } + return nullptr; +} + +size_t RegisterContextMinidump_ARM::GetRegisterSetCount() { + return k_num_reg_sets; +} + +const RegisterSet *RegisterContextMinidump_ARM::GetRegisterSet(size_t set) { + if (set < k_num_reg_sets) + return &g_reg_sets[set]; + return nullptr; +} + +const char *RegisterContextMinidump_ARM::GetRegisterName(unsigned reg) { + if (reg < k_num_reg_infos) + return g_reg_infos[reg].name; + return nullptr; +} + +bool RegisterContextMinidump_ARM::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + reg_value.SetFromMemoryData( + reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); +} + +bool RegisterContextMinidump_ARM::WriteRegister(const RegisterInfo *, + const RegisterValue &) { + return false; +} + +uint32_t RegisterContextMinidump_ARM::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + for (size_t i = 0; i < k_num_regs; ++i) { + if (g_reg_infos[i].kinds[kind] == num) + return i; + } + return LLDB_INVALID_REGNUM; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h new file mode 100644 index 000000000000..959611a1491d --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM.h @@ -0,0 +1,93 @@ +//===-- RegisterContextMinidump_ARM.h ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextMinidump_ARM_h_ +#define liblldb_RegisterContextMinidump_ARM_h_ + +#include "MinidumpTypes.h" + +#include "Plugins/Process/Utility/RegisterInfoInterface.h" + +#include "lldb/Target/RegisterContext.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" + +// C includes +// C++ includes + +namespace lldb_private { + +namespace minidump { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +class RegisterContextMinidump_ARM : public lldb_private::RegisterContext { +public: + RegisterContextMinidump_ARM(lldb_private::Thread &thread, + const DataExtractor &data, bool apple); + + ~RegisterContextMinidump_ARM() override = default; + + void InvalidateAllRegisters() override { + // Do nothing... registers are always valid... + } + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // Reference: see breakpad/crashpad source + struct QRegValue { + uint64_t lo; + uint64_t hi; + }; + + struct Context { + uint32_t context_flags; + uint32_t r[16]; + uint32_t cpsr; + uint64_t fpscr; + union { + uint64_t d[32]; + uint32_t s[32]; + QRegValue q[16]; + }; + uint32_t extra[8]; + }; + +protected: + enum class Flags : uint32_t { + ARM_Flag = 0x40000000, + Integer = ARM_Flag | 0x00000002, + FloatingPoint = ARM_Flag | 0x00000004, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) + }; + Context m_regs; + const bool m_apple; // True if this is an Apple ARM where FP is R7 +}; + +} // end namespace minidump +} // end namespace lldb_private +#endif // liblldb_RegisterContextMinidump_ARM_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp new file mode 100644 index 000000000000..3582e7d01867 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.cpp @@ -0,0 +1,834 @@ +//===-- RegisterContextMinidump_ARM64.cpp -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "RegisterContextMinidump_ARM64.h" + +#include "Utility/ARM64_DWARF_Registers.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/DataExtractor.h" +#include "lldb/lldb-enumerations.h" + +// C includes +#include + +// C++ includes + +using namespace lldb; +using namespace lldb_private; +using namespace minidump; + +#define INV LLDB_INVALID_REGNUM +#define OFFSET(r) (offsetof(RegisterContextMinidump_ARM64::Context, r)) + +#define DEF_X(i) \ + { \ + "x" #i, nullptr, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ + {INV, arm64_dwarf::x##i, INV, INV, reg_x##i}, nullptr, nullptr, \ + nullptr, 0 \ + } + +#define DEF_W(i) \ + { \ + "w" #i, nullptr, 4, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ + {INV, INV, INV, INV, reg_w##i}, nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_X_ARG(i, n) \ + { \ + "x" #i, "arg" #n, 8, OFFSET(x) + i * 8, eEncodingUint, eFormatHex, \ + {INV, arm64_dwarf::x##i, LLDB_REGNUM_GENERIC_ARG1 + i, INV, reg_x##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_V(i) \ + { \ + "v" #i, nullptr, 16, OFFSET(v) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, arm64_dwarf::v##i, INV, INV, reg_v##i}, \ + nullptr, nullptr, nullptr, 0 \ + } + +#define DEF_D(i) \ + { \ + "d" #i, nullptr, 8, OFFSET(v) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_d##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +#define DEF_S(i) \ + { \ + "s" #i, nullptr, 4, OFFSET(v) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_s##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +#define DEF_H(i) \ + { \ + "h" #i, nullptr, 2, OFFSET(v) + i * 16, eEncodingVector, \ + eFormatVectorOfUInt8, {INV, INV, INV, INV, reg_h##i}, nullptr, \ + nullptr, nullptr, 0 \ + } + +// Zero based LLDB register numbers for this register context +enum { + // General Purpose Registers + reg_x0 = 0, + reg_x1, + reg_x2, + reg_x3, + reg_x4, + reg_x5, + reg_x6, + reg_x7, + reg_x8, + reg_x9, + reg_x10, + reg_x11, + reg_x12, + reg_x13, + reg_x14, + reg_x15, + reg_x16, + reg_x17, + reg_x18, + reg_x19, + reg_x20, + reg_x21, + reg_x22, + reg_x23, + reg_x24, + reg_x25, + reg_x26, + reg_x27, + reg_x28, + reg_fp, + reg_lr, + reg_sp, + reg_pc, + reg_w0, + reg_w1, + reg_w2, + reg_w3, + reg_w4, + reg_w5, + reg_w6, + reg_w7, + reg_w8, + reg_w9, + reg_w10, + reg_w11, + reg_w12, + reg_w13, + reg_w14, + reg_w15, + reg_w16, + reg_w17, + reg_w18, + reg_w19, + reg_w20, + reg_w21, + reg_w22, + reg_w23, + reg_w24, + reg_w25, + reg_w26, + reg_w27, + reg_w28, + reg_w29, + reg_w30, + reg_w31, + reg_cpsr, + // Floating Point Registers + reg_fpsr, + reg_fpcr, + reg_v0, + reg_v1, + reg_v2, + reg_v3, + reg_v4, + reg_v5, + reg_v6, + reg_v7, + reg_v8, + reg_v9, + reg_v10, + reg_v11, + reg_v12, + reg_v13, + reg_v14, + reg_v15, + reg_v16, + reg_v17, + reg_v18, + reg_v19, + reg_v20, + reg_v21, + reg_v22, + reg_v23, + reg_v24, + reg_v25, + reg_v26, + reg_v27, + reg_v28, + reg_v29, + reg_v30, + reg_v31, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_h0, + reg_h1, + reg_h2, + reg_h3, + reg_h4, + reg_h5, + reg_h6, + reg_h7, + reg_h8, + reg_h9, + reg_h10, + reg_h11, + reg_h12, + reg_h13, + reg_h14, + reg_h15, + reg_h16, + reg_h17, + reg_h18, + reg_h19, + reg_h20, + reg_h21, + reg_h22, + reg_h23, + reg_h24, + reg_h25, + reg_h26, + reg_h27, + reg_h28, + reg_h29, + reg_h30, + reg_h31, + k_num_regs +}; + +// Register info definitions for this register context +static RegisterInfo g_reg_infos[] = { + DEF_X_ARG(0, 1), + DEF_X_ARG(1, 2), + DEF_X_ARG(2, 3), + DEF_X_ARG(3, 4), + DEF_X_ARG(4, 5), + DEF_X_ARG(5, 6), + DEF_X_ARG(6, 7), + DEF_X_ARG(7, 8), + DEF_X(8), + DEF_X(9), + DEF_X(10), + DEF_X(11), + DEF_X(12), + DEF_X(13), + DEF_X(14), + DEF_X(15), + DEF_X(16), + DEF_X(17), + DEF_X(18), + DEF_X(19), + DEF_X(20), + DEF_X(21), + DEF_X(22), + DEF_X(23), + DEF_X(24), + DEF_X(25), + DEF_X(26), + DEF_X(27), + DEF_X(28), + {"fp", + "x29", + 8, + OFFSET(x) + 29 * 8, + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x29, LLDB_REGNUM_GENERIC_FP, INV, reg_fp}, + nullptr, + nullptr, + nullptr, + 0}, + {"lr", + "x30", + 8, + OFFSET(x) + 30 * 8, + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x30, LLDB_REGNUM_GENERIC_RA, INV, reg_lr}, + nullptr, + nullptr, + nullptr, + 0}, + {"sp", + "x31", + 8, + OFFSET(x) + 31 * 8, + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::x31, LLDB_REGNUM_GENERIC_SP, INV, reg_sp}, + nullptr, + nullptr, + nullptr, + 0}, + {"pc", + nullptr, + 8, + OFFSET(pc), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::pc, LLDB_REGNUM_GENERIC_PC, INV, reg_pc}, + nullptr, + nullptr, + nullptr, + 0}, + // w0 - w31 + DEF_W(0), + DEF_W(1), + DEF_W(2), + DEF_W(3), + DEF_W(4), + DEF_W(5), + DEF_W(6), + DEF_W(7), + DEF_W(8), + DEF_W(9), + DEF_W(10), + DEF_W(11), + DEF_W(12), + DEF_W(13), + DEF_W(14), + DEF_W(15), + DEF_W(16), + DEF_W(17), + DEF_W(18), + DEF_W(19), + DEF_W(20), + DEF_W(21), + DEF_W(22), + DEF_W(23), + DEF_W(24), + DEF_W(25), + DEF_W(26), + DEF_W(27), + DEF_W(28), + DEF_W(29), + DEF_W(30), + DEF_W(31), + {"cpsr", + "psr", + 4, + OFFSET(cpsr), + eEncodingUint, + eFormatHex, + {INV, arm64_dwarf::cpsr, LLDB_REGNUM_GENERIC_FLAGS, INV, reg_cpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpsr", + nullptr, + 4, + OFFSET(fpsr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpsr}, + nullptr, + nullptr, + nullptr, + 0}, + {"fpcr", + nullptr, + 4, + OFFSET(fpcr), + eEncodingUint, + eFormatHex, + {INV, INV, INV, INV, reg_fpcr}, + nullptr, + nullptr, + nullptr, + 0}, + // v0 - v31 + DEF_V(0), + DEF_V(1), + DEF_V(2), + DEF_V(3), + DEF_V(4), + DEF_V(5), + DEF_V(6), + DEF_V(7), + DEF_V(8), + DEF_V(9), + DEF_V(10), + DEF_V(11), + DEF_V(12), + DEF_V(13), + DEF_V(14), + DEF_V(15), + DEF_V(16), + DEF_V(17), + DEF_V(18), + DEF_V(19), + DEF_V(20), + DEF_V(21), + DEF_V(22), + DEF_V(23), + DEF_V(24), + DEF_V(25), + DEF_V(26), + DEF_V(27), + DEF_V(28), + DEF_V(29), + DEF_V(30), + DEF_V(31), + // d0 - d31 + DEF_D(0), + DEF_D(1), + DEF_D(2), + DEF_D(3), + DEF_D(4), + DEF_D(5), + DEF_D(6), + DEF_D(7), + DEF_D(8), + DEF_D(9), + DEF_D(10), + DEF_D(11), + DEF_D(12), + DEF_D(13), + DEF_D(14), + DEF_D(15), + DEF_D(16), + DEF_D(17), + DEF_D(18), + DEF_D(19), + DEF_D(20), + DEF_D(21), + DEF_D(22), + DEF_D(23), + DEF_D(24), + DEF_D(25), + DEF_D(26), + DEF_D(27), + DEF_D(28), + DEF_D(29), + DEF_D(30), + DEF_D(31), + // s0 - s31 + DEF_S(0), + DEF_S(1), + DEF_S(2), + DEF_S(3), + DEF_S(4), + DEF_S(5), + DEF_S(6), + DEF_S(7), + DEF_S(8), + DEF_S(9), + DEF_S(10), + DEF_S(11), + DEF_S(12), + DEF_S(13), + DEF_S(14), + DEF_S(15), + DEF_S(16), + DEF_S(17), + DEF_S(18), + DEF_S(19), + DEF_S(20), + DEF_S(21), + DEF_S(22), + DEF_S(23), + DEF_S(24), + DEF_S(25), + DEF_S(26), + DEF_S(27), + DEF_S(28), + DEF_S(29), + DEF_S(30), + DEF_S(31), + // h0 - h31 + DEF_H(0), + DEF_H(1), + DEF_H(2), + DEF_H(3), + DEF_H(4), + DEF_H(5), + DEF_H(6), + DEF_H(7), + DEF_H(8), + DEF_H(9), + DEF_H(10), + DEF_H(11), + DEF_H(12), + DEF_H(13), + DEF_H(14), + DEF_H(15), + DEF_H(16), + DEF_H(17), + DEF_H(18), + DEF_H(19), + DEF_H(20), + DEF_H(21), + DEF_H(22), + DEF_H(23), + DEF_H(24), + DEF_H(25), + DEF_H(26), + DEF_H(27), + DEF_H(28), + DEF_H(29), + DEF_H(30), + DEF_H(31), +}; + +constexpr size_t k_num_reg_infos = llvm::array_lengthof(g_reg_infos); + +// ARM64 general purpose registers. +const uint32_t g_gpr_regnums[] = { + reg_x0, + reg_x1, + reg_x2, + reg_x3, + reg_x4, + reg_x5, + reg_x6, + reg_x7, + reg_x8, + reg_x9, + reg_x10, + reg_x11, + reg_x12, + reg_x13, + reg_x14, + reg_x15, + reg_x16, + reg_x17, + reg_x18, + reg_x19, + reg_x20, + reg_x21, + reg_x22, + reg_x23, + reg_x24, + reg_x25, + reg_x26, + reg_x27, + reg_x28, + reg_fp, + reg_lr, + reg_sp, + reg_w0, + reg_w1, + reg_w2, + reg_w3, + reg_w4, + reg_w5, + reg_w6, + reg_w7, + reg_w8, + reg_w9, + reg_w10, + reg_w11, + reg_w12, + reg_w13, + reg_w14, + reg_w15, + reg_w16, + reg_w17, + reg_w18, + reg_w19, + reg_w20, + reg_w21, + reg_w22, + reg_w23, + reg_w24, + reg_w25, + reg_w26, + reg_w27, + reg_w28, + reg_w29, + reg_w30, + reg_w31, + reg_pc, + reg_cpsr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; +const uint32_t g_fpu_regnums[] = { + reg_v0, + reg_v1, + reg_v2, + reg_v3, + reg_v4, + reg_v5, + reg_v6, + reg_v7, + reg_v8, + reg_v9, + reg_v10, + reg_v11, + reg_v12, + reg_v13, + reg_v14, + reg_v15, + reg_v16, + reg_v17, + reg_v18, + reg_v19, + reg_v20, + reg_v21, + reg_v22, + reg_v23, + reg_v24, + reg_v25, + reg_v26, + reg_v27, + reg_v28, + reg_v29, + reg_v30, + reg_v31, + reg_d0, + reg_d1, + reg_d2, + reg_d3, + reg_d4, + reg_d5, + reg_d6, + reg_d7, + reg_d8, + reg_d9, + reg_d10, + reg_d11, + reg_d12, + reg_d13, + reg_d14, + reg_d15, + reg_d16, + reg_d17, + reg_d18, + reg_d19, + reg_d20, + reg_d21, + reg_d22, + reg_d23, + reg_d24, + reg_d25, + reg_d26, + reg_d27, + reg_d28, + reg_d29, + reg_d30, + reg_d31, + reg_s0, + reg_s1, + reg_s2, + reg_s3, + reg_s4, + reg_s5, + reg_s6, + reg_s7, + reg_s8, + reg_s9, + reg_s10, + reg_s11, + reg_s12, + reg_s13, + reg_s14, + reg_s15, + reg_s16, + reg_s17, + reg_s18, + reg_s19, + reg_s20, + reg_s21, + reg_s22, + reg_s23, + reg_s24, + reg_s25, + reg_s26, + reg_s27, + reg_s28, + reg_s29, + reg_s30, + reg_s31, + reg_h0, + reg_h1, + reg_h2, + reg_h3, + reg_h4, + reg_h5, + reg_h6, + reg_h7, + reg_h8, + reg_h9, + reg_h10, + reg_h11, + reg_h12, + reg_h13, + reg_h14, + reg_h15, + reg_h16, + reg_h17, + reg_h18, + reg_h19, + reg_h20, + reg_h21, + reg_h22, + reg_h23, + reg_h24, + reg_h25, + reg_h26, + reg_h27, + reg_h28, + reg_h29, + reg_h30, + reg_h31, + reg_fpsr, + reg_fpcr, + LLDB_INVALID_REGNUM // register sets need to end with this flag +}; + +// Skip the last LLDB_INVALID_REGNUM in each count below by subtracting 1 +constexpr size_t k_num_gpr_regs = llvm::array_lengthof(g_gpr_regnums) - 1; +constexpr size_t k_num_fpu_regs = llvm::array_lengthof(g_fpu_regnums) - 1; + +static RegisterSet g_reg_sets[] = { + {"General Purpose Registers", "gpr", k_num_gpr_regs, g_gpr_regnums}, + {"Floating Point Registers", "fpu", k_num_fpu_regs, g_fpu_regnums}, +}; + +constexpr size_t k_num_reg_sets = llvm::array_lengthof(g_reg_sets); + +RegisterContextMinidump_ARM64::RegisterContextMinidump_ARM64( + Thread &thread, const DataExtractor &data) + : RegisterContext(thread, 0) { + lldb::offset_t offset = 0; + m_regs.context_flags = data.GetU64(&offset); + for (unsigned i = 0; i < 32; ++i) + m_regs.x[i] = data.GetU64(&offset); + m_regs.pc = data.GetU64(&offset); + m_regs.cpsr = data.GetU32(&offset); + m_regs.fpsr = data.GetU32(&offset); + m_regs.fpcr = data.GetU32(&offset); + auto regs_data = data.GetData(&offset, sizeof(m_regs.v)); + if (regs_data) + memcpy(m_regs.v, regs_data, sizeof(m_regs.v)); + assert(k_num_regs == k_num_reg_infos); +} +size_t RegisterContextMinidump_ARM64::GetRegisterCount() { return k_num_regs; } + +const RegisterInfo * +RegisterContextMinidump_ARM64::GetRegisterInfoAtIndex(size_t reg) { + if (reg < k_num_reg_infos) + return &g_reg_infos[reg]; + return nullptr; +} + +size_t RegisterContextMinidump_ARM64::GetRegisterSetCount() { + return k_num_reg_sets; +} + +const RegisterSet *RegisterContextMinidump_ARM64::GetRegisterSet(size_t set) { + if (set < k_num_reg_sets) + return &g_reg_sets[set]; + return nullptr; +} + +const char *RegisterContextMinidump_ARM64::GetRegisterName(unsigned reg) { + if (reg < k_num_reg_infos) + return g_reg_infos[reg].name; + return nullptr; +} + +bool RegisterContextMinidump_ARM64::ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) { + Status error; + reg_value.SetFromMemoryData( + reg_info, (const uint8_t *)&m_regs + reg_info->byte_offset, + reg_info->byte_size, lldb::eByteOrderLittle, error); + return error.Success(); +} + +bool RegisterContextMinidump_ARM64::WriteRegister(const RegisterInfo *, + const RegisterValue &) { + return false; +} + +uint32_t RegisterContextMinidump_ARM64::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + for (size_t i = 0; i < k_num_regs; ++i) { + if (g_reg_infos[i].kinds[kind] == num) + return i; + } + return LLDB_INVALID_REGNUM; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h new file mode 100644 index 000000000000..ee47b1577e52 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_ARM64.h @@ -0,0 +1,83 @@ +//===-- RegisterContextMinidump_ARM64.h -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_RegisterContextMinidump_ARM64_h_ +#define liblldb_RegisterContextMinidump_ARM64_h_ + +#include "MinidumpTypes.h" + +#include "Plugins/Process/Utility/RegisterInfoInterface.h" +#include "lldb/Target/RegisterContext.h" + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" + +// C includes +// C++ includes + +namespace lldb_private { + +namespace minidump { + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +class RegisterContextMinidump_ARM64 : public lldb_private::RegisterContext { +public: + RegisterContextMinidump_ARM64(lldb_private::Thread &thread, + const DataExtractor &data); + + ~RegisterContextMinidump_ARM64() override = default; + + void InvalidateAllRegisters() override { + // Do nothing... registers are always valid... + } + + size_t GetRegisterCount() override; + + const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; + + size_t GetRegisterSetCount() override; + + const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; + + const char *GetRegisterName(unsigned reg); + + bool ReadRegister(const RegisterInfo *reg_info, + RegisterValue ®_value) override; + + bool WriteRegister(const RegisterInfo *reg_info, + const RegisterValue ®_value) override; + + uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, + uint32_t num) override; + + // Reference: see breakpad/crashpad source + struct Context { + uint64_t context_flags; + uint64_t x[32]; + uint64_t pc; + uint32_t cpsr; + uint32_t fpsr; + uint32_t fpcr; + uint8_t v[32 * 16]; // 32 128-bit floating point registers + }; + +protected: + enum class Flags : uint32_t { + ARM64_Flag = 0x80000000, + Integer = ARM64_Flag | 0x00000002, + FloatingPoint = ARM64_Flag | 0x00000004, + LLVM_MARK_AS_BITMASK_ENUM(/* LargestValue = */ FloatingPoint) + }; + Context m_regs; +}; + +} // end namespace minidump +} // end namespace lldb_private +#endif // liblldb_RegisterContextMinidump_ARM64_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp index 7605f8b143af..1fdbb5e3f1e5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.cpp @@ -7,10 +7,8 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "RegisterContextMinidump_x86_32.h" -// Other libraries and framework includes #include "lldb/Utility/DataBufferHeap.h" // C includes diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h index e18bb3b4f5d9..38c2ffca4938 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_32.h @@ -10,10 +10,8 @@ #ifndef liblldb_RegisterContextMinidump_x86_32_h_ #define liblldb_RegisterContextMinidump_x86_32_h_ -// Project includes #include "MinidumpTypes.h" -// Other libraries and framework includes #include "Plugins/Process/Utility/RegisterInfoInterface.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp index ba1cb6dbf3ef..eaa155de8eb9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.cpp @@ -7,10 +7,8 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "RegisterContextMinidump_x86_64.h" -// Other libraries and framework includes #include "lldb/Utility/DataBufferHeap.h" // C includes diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h index 9ba2ee9f29ad..30ce9065e141 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/RegisterContextMinidump_x86_64.h @@ -10,10 +10,8 @@ #ifndef liblldb_RegisterContextMinidump_h_ #define liblldb_RegisterContextMinidump_h_ -// Project includes #include "MinidumpTypes.h" -// Other libraries and framework includes #include "Plugins/Process/Utility/RegisterInfoInterface.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp index 3fafb6134e7f..f4c136577719 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.cpp @@ -7,14 +7,14 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "ThreadMinidump.h" #include "ProcessMinidump.h" +#include "RegisterContextMinidump_ARM.h" +#include "RegisterContextMinidump_ARM64.h" #include "RegisterContextMinidump_x86_32.h" #include "RegisterContextMinidump_x86_64.h" -// Other libraries and framework includes #include "Plugins/Process/Utility/RegisterContextLinux_i386.h" #include "Plugins/Process/Utility/RegisterContextLinux_x86_64.h" #include "Plugins/Process/elf-core/RegisterContextPOSIXCore_x86_64.h" @@ -27,8 +27,6 @@ #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" -// C Includes -// C++ Includes using namespace lldb; using namespace lldb_private; @@ -54,7 +52,6 @@ RegisterContextSP ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { RegisterContextSP reg_ctx_sp; uint32_t concrete_frame_idx = 0; - Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_THREAD)); if (frame) concrete_frame_idx = frame->GetConcreteFrameIndex(); @@ -88,15 +85,22 @@ ThreadMinidump::CreateRegisterContextForFrame(StackFrame *frame) { *this, reg_interface, gpregset, {})); break; } - default: + case llvm::Triple::aarch64: { + DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), + lldb::eByteOrderLittle, 8); + m_thread_reg_ctx_sp.reset(new RegisterContextMinidump_ARM64(*this, data)); break; } - - if (!reg_interface) { - if (log) - log->Printf("elf-core::%s:: Architecture(%d) not supported", - __FUNCTION__, arch.GetMachine()); - assert(false && "Architecture not supported"); + case llvm::Triple::arm: { + DataExtractor data(m_gpregset_data.data(), m_gpregset_data.size(), + lldb::eByteOrderLittle, 8); + const bool apple = arch.GetTriple().getVendor() == llvm::Triple::Apple; + m_thread_reg_ctx_sp.reset( + new RegisterContextMinidump_ARM(*this, data, apple)); + break; + } + default: + break; } reg_ctx_sp = m_thread_reg_ctx_sp; diff --git a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.h b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.h index 74ac44f74dcf..45364facaa56 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.h +++ b/contrib/llvm/tools/lldb/source/Plugins/Process/minidump/ThreadMinidump.h @@ -10,14 +10,10 @@ #ifndef liblldb_ThreadMinidump_h_ #define liblldb_ThreadMinidump_h_ -// Project includes #include "MinidumpTypes.h" -// Other libraries and framework includes #include "lldb/Target/Thread.h" -// C Includes -// C++ Includes namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h index 824579472b5e..8937d9843f87 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/None/ScriptInterpreterNone.h @@ -10,10 +10,6 @@ #ifndef liblldb_ScriptInterpreterNone_h_ #define liblldb_ScriptInterpreterNone_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Interpreter/ScriptInterpreter.h" namespace lldb_private { diff --git a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp index 90d8ab97fb73..7e96dd9893c8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp @@ -222,9 +222,7 @@ PythonBytes::~PythonBytes() {} bool PythonBytes::Check(PyObject *py_obj) { if (!py_obj) return false; - if (PyBytes_Check(py_obj)) - return true; - return false; + return PyBytes_Check(py_obj); } void PythonBytes::Reset(PyRefType type, PyObject *py_obj) { @@ -294,9 +292,7 @@ PythonByteArray::~PythonByteArray() {} bool PythonByteArray::Check(PyObject *py_obj) { if (!py_obj) return false; - if (PyByteArray_Check(py_obj)) - return true; - return false; + return PyByteArray_Check(py_obj); } void PythonByteArray::Reset(PyRefType type, PyObject *py_obj) { @@ -939,7 +935,8 @@ PythonFile::PythonFile() : PythonObject() {} PythonFile::PythonFile(File &file, const char *mode) { Reset(file, mode); } PythonFile::PythonFile(const char *path, const char *mode) { - lldb_private::File file(path, GetOptionsFromMode(mode)); + lldb_private::File file; + FileSystem::Instance().Open(file, FileSpec(path), GetOptionsFromMode(mode)); Reset(file, mode); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h index beeb64782367..7cd98df28ee0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h @@ -15,10 +15,6 @@ // LLDB Python header must be included first #include "lldb-python.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Flags.h" #include "lldb/Host/File.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp index b8eb36a2baf6..41cb443d4f1e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -27,6 +27,7 @@ #include #include "lldb/API/SBValue.h" +#include "lldb/API/SBFrame.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Breakpoint/WatchpointOptions.h" @@ -91,6 +92,10 @@ static ScriptInterpreterPython::SWIGPythonCallModuleInit g_swig_call_module_init = nullptr; static ScriptInterpreterPython::SWIGPythonCreateOSPlugin g_swig_create_os_plugin = nullptr; +static ScriptInterpreterPython::SWIGPythonCreateFrameRecognizer + g_swig_create_frame_recognizer = nullptr; +static ScriptInterpreterPython::SWIGPythonGetRecognizedArguments + g_swig_get_recognized_arguments = nullptr; static ScriptInterpreterPython::SWIGPythonScriptKeyword_Process g_swig_run_script_keyword_process = nullptr; static ScriptInterpreterPython::SWIGPythonScriptKeyword_Thread @@ -107,6 +112,10 @@ static ScriptInterpreterPython::SWIGPythonCreateScriptedThreadPlan g_swig_thread_plan_script = nullptr; static ScriptInterpreterPython::SWIGPythonCallThreadPlan g_swig_call_thread_plan = nullptr; +static ScriptInterpreterPython::SWIGPythonCreateScriptedBreakpointResolver + g_swig_bkpt_resolver_script = nullptr; +static ScriptInterpreterPython::SWIGPythonCallBreakpointResolver + g_swig_call_bkpt_resolver = nullptr; static bool g_initialized = false; @@ -128,6 +137,9 @@ public: InitializePythonHome(); + // Register _lldb as a built-in module. + PyImport_AppendInittab("_lldb", g_swig_init_callback); + // Python < 3.2 and Python >= 3.2 reversed the ordering requirements for // calling `Py_Initialize` and `PyEval_InitThreads`. < 3.2 requires that you // call `PyEval_InitThreads` first, and >= 3.2 requires that you call it last. @@ -196,7 +208,7 @@ ScriptInterpreterPython::Locker::Locker(ScriptInterpreterPython *py_interpreter, m_python_interpreter(py_interpreter) { DoAcquireLock(); if ((on_entry & InitSession) == InitSession) { - if (DoInitSession(on_entry, in, out, err) == false) { + if (!DoInitSession(on_entry, in, out, err)) { // Don't teardown the session if we didn't init it. m_teardown_session = false; } @@ -817,11 +829,15 @@ bool ScriptInterpreterPython::ExecuteOneLine( error_file_sp); } else { input_file_sp.reset(new StreamFile()); - input_file_sp->GetFile().Open(FileSystem::DEV_NULL, - File::eOpenOptionRead); + FileSystem::Instance().Open(input_file_sp->GetFile(), + FileSpec(FileSystem::DEV_NULL), + File::eOpenOptionRead); + output_file_sp.reset(new StreamFile()); - output_file_sp->GetFile().Open(FileSystem::DEV_NULL, - File::eOpenOptionWrite); + FileSystem::Instance().Open(output_file_sp->GetFile(), + FileSpec(FileSystem::DEV_NULL), + File::eOpenOptionWrite); + error_file_sp = output_file_sp; } @@ -1491,6 +1507,62 @@ bool ScriptInterpreterPython::GenerateTypeSynthClass(StringList &user_input, return true; } +StructuredData::GenericSP ScriptInterpreterPython::CreateFrameRecognizer( + const char *class_name) { + if (class_name == nullptr || class_name[0] == '\0') + return StructuredData::GenericSP(); + + void *ret_val; + + { + Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, + Locker::FreeLock); + ret_val = + g_swig_create_frame_recognizer(class_name, m_dictionary_name.c_str()); + } + + return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); +} + +lldb::ValueObjectListSP ScriptInterpreterPython::GetRecognizedArguments( + const StructuredData::ObjectSP &os_plugin_object_sp, + lldb::StackFrameSP frame_sp) { + Locker py_lock(this, Locker::AcquireLock | Locker::NoSTDIN, Locker::FreeLock); + + if (!os_plugin_object_sp) return ValueObjectListSP(); + + StructuredData::Generic *generic = os_plugin_object_sp->GetAsGeneric(); + if (!generic) return nullptr; + + PythonObject implementor(PyRefType::Borrowed, + (PyObject *)generic->GetValue()); + + if (!implementor.IsAllocated()) return ValueObjectListSP(); + + PythonObject py_return( + PyRefType::Owned, + (PyObject *)g_swig_get_recognized_arguments(implementor.get(), frame_sp)); + + // if it fails, print the error but otherwise go on + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } + if (py_return.get()) { + PythonList result_list(PyRefType::Borrowed, py_return.get()); + ValueObjectListSP result = ValueObjectListSP(new ValueObjectList()); + for (size_t i = 0; i < result_list.GetSize(); i++) { + PyObject *item = result_list.GetItemAtIndex(i).get(); + lldb::SBValue *sb_value_ptr = + (lldb::SBValue *)g_swig_cast_to_sbvalue(item); + auto valobj_sp = g_swig_get_valobj_sp_from_sbvalue(sb_value_ptr); + if (valobj_sp) result->Append(valobj_sp); + } + return result; + } + return ValueObjectListSP(); +} + StructuredData::GenericSP ScriptInterpreterPython::OSPlugin_CreatePluginObject( const char *class_name, lldb::ProcessSP process_sp) { if (class_name == nullptr || class_name[0] == '\0') @@ -1868,10 +1940,88 @@ lldb::StateType ScriptInterpreterPython::ScriptedThreadPlanGetRunState( return lldb::eStateRunning; } +StructuredData::GenericSP +ScriptInterpreterPython::CreateScriptedBreakpointResolver( + const char *class_name, + StructuredDataImpl *args_data, + lldb::BreakpointSP &bkpt_sp) { + + if (class_name == nullptr || class_name[0] == '\0') + return StructuredData::GenericSP(); + + if (!bkpt_sp.get()) + return StructuredData::GenericSP(); + + Debugger &debugger = bkpt_sp->GetTarget().GetDebugger(); + ScriptInterpreter *script_interpreter = + debugger.GetCommandInterpreter().GetScriptInterpreter(); + ScriptInterpreterPython *python_interpreter = + static_cast(script_interpreter); + + if (!script_interpreter) + return StructuredData::GenericSP(); + + void *ret_val; + + { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + + ret_val = g_swig_bkpt_resolver_script( + class_name, python_interpreter->m_dictionary_name.c_str(), + args_data, bkpt_sp); + } + + return StructuredData::GenericSP(new StructuredPythonObject(ret_val)); +} + +bool +ScriptInterpreterPython::ScriptedBreakpointResolverSearchCallback( + StructuredData::GenericSP implementor_sp, + SymbolContext *sym_ctx) { + bool should_continue = false; + + if (implementor_sp) { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + should_continue + = g_swig_call_bkpt_resolver(implementor_sp->GetValue(), "__callback__", + sym_ctx); + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } + } + return should_continue; +} + +lldb::SearchDepth +ScriptInterpreterPython::ScriptedBreakpointResolverSearchDepth( + StructuredData::GenericSP implementor_sp) { + int depth_as_int = lldb::eSearchDepthModule; + if (implementor_sp) { + Locker py_lock(this, + Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN); + depth_as_int + = g_swig_call_bkpt_resolver(implementor_sp->GetValue(), "__get_depth__", nullptr); + if (PyErr_Occurred()) { + PyErr_Print(); + PyErr_Clear(); + } + } + if (depth_as_int == lldb::eSearchDepthInvalid) + return lldb::eSearchDepthModule; + + if (depth_as_int <= lldb::kLastSearchDepthKind) + return (lldb::SearchDepth) depth_as_int; + else + return lldb::eSearchDepthModule; +} + StructuredData::ObjectSP ScriptInterpreterPython::LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) { - if (!file_spec.Exists()) { + if (!FileSystem::Instance().Exists(file_spec)) { error.SetErrorString("no such file"); return StructuredData::ObjectSP(); } @@ -2603,7 +2753,8 @@ bool ScriptInterpreterPython::LoadScriptingModule( lldb::DebuggerSP debugger_sp = m_interpreter.GetDebugger().shared_from_this(); { - FileSpec target_file(pathname, true); + FileSpec target_file(pathname); + FileSystem::Instance().Resolve(target_file); std::string basename(target_file.GetFilename().GetCString()); StreamString command_stream; @@ -2687,7 +2838,7 @@ bool ScriptInterpreterPython::LoadScriptingModule( bool was_imported = (was_imported_globally || was_imported_locally); - if (was_imported == true && can_reload == false) { + if (was_imported && !can_reload) { error.SetErrorString("module already imported"); return false; } @@ -3100,6 +3251,8 @@ void ScriptInterpreterPython::InitializeInterpreter( SWIGPythonCallCommandObject swig_call_command_object, SWIGPythonCallModuleInit swig_call_module_init, SWIGPythonCreateOSPlugin swig_create_os_plugin, + SWIGPythonCreateFrameRecognizer swig_create_frame_recognizer, + SWIGPythonGetRecognizedArguments swig_get_recognized_arguments, SWIGPythonScriptKeyword_Process swig_run_script_keyword_process, SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread, SWIGPythonScriptKeyword_Target swig_run_script_keyword_target, @@ -3107,7 +3260,9 @@ void ScriptInterpreterPython::InitializeInterpreter( SWIGPythonScriptKeyword_Value swig_run_script_keyword_value, SWIGPython_GetDynamicSetting swig_plugin_get, SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script, - SWIGPythonCallThreadPlan swig_call_thread_plan) { + SWIGPythonCallThreadPlan swig_call_thread_plan, + SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script, + SWIGPythonCallBreakpointResolver swig_call_bkpt_resolver) { g_swig_init_callback = swig_init_callback; g_swig_breakpoint_callback = swig_breakpoint_callback; g_swig_watchpoint_callback = swig_watchpoint_callback; @@ -3126,6 +3281,8 @@ void ScriptInterpreterPython::InitializeInterpreter( g_swig_call_command_object = swig_call_command_object; g_swig_call_module_init = swig_call_module_init; g_swig_create_os_plugin = swig_create_os_plugin; + g_swig_create_frame_recognizer = swig_create_frame_recognizer; + g_swig_get_recognized_arguments = swig_get_recognized_arguments; g_swig_run_script_keyword_process = swig_run_script_keyword_process; g_swig_run_script_keyword_thread = swig_run_script_keyword_thread; g_swig_run_script_keyword_target = swig_run_script_keyword_target; @@ -3134,6 +3291,8 @@ void ScriptInterpreterPython::InitializeInterpreter( g_swig_plugin_get = swig_plugin_get; g_swig_thread_plan_script = swig_thread_plan_script; g_swig_call_thread_plan = swig_call_thread_plan; + g_swig_bkpt_resolver_script = swig_bkpt_resolver_script; + g_swig_call_bkpt_resolver = swig_call_bkpt_resolver; } void ScriptInterpreterPython::InitializePrivate() { diff --git a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h index b13979dc069b..a047359883ce 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h +++ b/contrib/llvm/tools/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h @@ -16,14 +16,10 @@ #else -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes -// Project includes #include "PythonDataObjects.h" #include "lldb/Breakpoint/BreakpointOptions.h" #include "lldb/Core/IOHandler.h" @@ -81,10 +77,25 @@ public: const char *method_name, Event *event_sp, bool &got_error); + typedef void *(*SWIGPythonCreateScriptedBreakpointResolver)( + const char *python_class_name, const char *session_dictionary_name, + lldb_private::StructuredDataImpl *args_impl, + lldb::BreakpointSP &bkpt_sp); + + typedef unsigned int (*SWIGPythonCallBreakpointResolver)(void *implementor, + const char *method_name, + lldb_private::SymbolContext *sym_ctx); + typedef void *(*SWIGPythonCreateOSPlugin)(const char *python_class_name, const char *session_dictionary_name, const lldb::ProcessSP &process_sp); + typedef void *(*SWIGPythonCreateFrameRecognizer)( + const char *python_class_name, const char *session_dictionary_name); + + typedef void *(*SWIGPythonGetRecognizedArguments)( + void *implementor, const lldb::StackFrameSP &frame_sp); + typedef size_t (*SWIGPythonCalculateNumChildren)(void *implementor, uint32_t max); @@ -208,6 +219,26 @@ public: lldb::StateType ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp, bool &script_error) override; + + StructuredData::GenericSP + CreateScriptedBreakpointResolver(const char *class_name, + StructuredDataImpl *args_data, + lldb::BreakpointSP &bkpt_sp) override; + bool + ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP + implementor_sp, + SymbolContext *sym_ctx) override; + + lldb::SearchDepth + ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP + implementor_sp) override; + + StructuredData::GenericSP + CreateFrameRecognizer(const char *class_name) override; + + lldb::ValueObjectListSP + GetRecognizedArguments(const StructuredData::ObjectSP &implementor, + lldb::StackFrameSP frame_sp) override; StructuredData::GenericSP OSPlugin_CreatePluginObject(const char *class_name, @@ -404,6 +435,8 @@ public: SWIGPythonCallCommandObject swig_call_command_object, SWIGPythonCallModuleInit swig_call_module_init, SWIGPythonCreateOSPlugin swig_create_os_plugin, + SWIGPythonCreateFrameRecognizer swig_create_frame_recognizer, + SWIGPythonGetRecognizedArguments swig_get_recognized_arguments, SWIGPythonScriptKeyword_Process swig_run_script_keyword_process, SWIGPythonScriptKeyword_Thread swig_run_script_keyword_thread, SWIGPythonScriptKeyword_Target swig_run_script_keyword_target, @@ -411,7 +444,9 @@ public: SWIGPythonScriptKeyword_Value swig_run_script_keyword_value, SWIGPython_GetDynamicSetting swig_plugin_get, SWIGPythonCreateScriptedThreadPlan swig_thread_plan_script, - SWIGPythonCallThreadPlan swig_call_thread_plan); + SWIGPythonCallThreadPlan swig_call_thread_plan, + SWIGPythonCreateScriptedBreakpointResolver swig_bkpt_resolver_script, + SWIGPythonCallBreakpointResolver swig_call_breakpoint_resolver); const char *GetDictionaryName() { return m_dictionary_name.c_str(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp b/contrib/llvm/tools/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp index e33e26507fb1..6e3792bff9c4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/StructuredData/DarwinLog/StructuredDataDarwinLog.cpp @@ -112,14 +112,14 @@ void SetGlobalEnableOptions(const DebuggerSP &debugger_sp, /// Code to handle the StructuredDataDarwinLog settings //------------------------------------------------------------------ -static PropertyDefinition g_properties[] = { +static constexpr PropertyDefinition g_properties[] = { { "enable-on-startup", // name OptionValue::eTypeBoolean, // type true, // global false, // default uint value nullptr, // default cstring value - nullptr, // enum values + {}, // enum values "Enable Darwin os_log collection when debugged process is launched " "or attached." // description }, @@ -129,13 +129,11 @@ static PropertyDefinition g_properties[] = { true, // global 0, // default uint value "", // default cstring value - nullptr, // enum values + {}, // enum values "Specify the options to 'plugin structured-data darwin-log enable' " "that should be applied when automatically enabling logging on " "startup/attach." // description - }, - // Last entry sentinel. - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + }}; enum { ePropertyEnableOnStartup = 0, ePropertyAutoEnableOptions = 1 }; @@ -402,23 +400,23 @@ static void RegisterFilterOperations() { /// This resets the logging with whatever settings are currently set. // ------------------------------------------------------------------------- -static OptionDefinition g_enable_option_table[] = { +static constexpr OptionDefinition g_enable_option_table[] = { // Source stream include/exclude options (the first-level filter). This one // should be made as small as possible as everything that goes through here // must be processed by the process monitor. {LLDB_OPT_SET_ALL, false, "any-process", 'a', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Specifies log messages from other related processes should be " "included."}, {LLDB_OPT_SET_ALL, false, "debug", 'd', OptionParser::eNoArgument, nullptr, - nullptr, 0, eArgTypeNone, + {}, 0, eArgTypeNone, "Specifies debug-level log messages should be included. Specifying" " --debug implies --info."}, {LLDB_OPT_SET_ALL, false, "info", 'i', OptionParser::eNoArgument, nullptr, - nullptr, 0, eArgTypeNone, + {}, 0, eArgTypeNone, "Specifies info-level log messages should be included."}, {LLDB_OPT_SET_ALL, false, "filter", 'f', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgRawInput, + nullptr, {}, 0, eArgRawInput, // There doesn't appear to be a great way for me to have these multi-line, // formatted tables in help. This looks mostly right but there are extra // linefeeds added at seemingly random spots, and indentation isn't @@ -452,52 +450,52 @@ static OptionDefinition g_enable_option_table[] = { "Prefer character classes like [[:digit:]] to \\d and the like, as " "getting the backslashes escaped through properly is error-prone."}, {LLDB_OPT_SET_ALL, false, "live-stream", 'l', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether logging events are live-streamed or buffered. " "True indicates live streaming, false indicates buffered. The " "default is true (live streaming). Live streaming will deliver " "log messages with less delay, but buffered capture mode has less " "of an observer effect."}, {LLDB_OPT_SET_ALL, false, "no-match-accepts", 'n', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether a log message that doesn't match any filter rule " "is accepted or rejected, where true indicates accept. The " "default is true."}, {LLDB_OPT_SET_ALL, false, "echo-to-stderr", 'e', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify whether os_log()/NSLog() messages are echoed to the " "target program's stderr. When DarwinLog is enabled, we shut off " "the mirroring of os_log()/NSLog() to the program's stderr. " "Setting this flag to true will restore the stderr mirroring." "The default is false."}, {LLDB_OPT_SET_ALL, false, "broadcast-events", 'b', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Specify if the plugin should broadcast events. Broadcasting " "log events is a requirement for displaying the log entries in " "LLDB command-line. It is also required if LLDB clients want to " "process log events. The default is true."}, // Message formatting options {LLDB_OPT_SET_ALL, false, "timestamp-relative", 'r', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Include timestamp in the message header when printing a log " "message. The timestamp is relative to the first displayed " "message."}, {LLDB_OPT_SET_ALL, false, "subsystem", 's', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, - "Include the subsystem in the the message header when displaying " + nullptr, {}, 0, eArgTypeNone, + "Include the subsystem in the message header when displaying " "a log message."}, {LLDB_OPT_SET_ALL, false, "category", 'c', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Include the category in the message header when displaying " "a log message."}, {LLDB_OPT_SET_ALL, false, "activity-chain", 'C', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Include the activity parent-child chain in the message header " "when displaying a log message. The activity hierarchy is " "displayed as {grandparent-activity}:" "{parent-activity}:{activity}[:...]."}, {LLDB_OPT_SET_ALL, false, "all-fields", 'A', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Shortcut to specify that all header fields should be displayed."}}; class EnableOptions : public Options { @@ -1679,7 +1677,7 @@ void StructuredDataDarwinLog::AddInitCompletionHook(Process &process) { // Build up the module list. FileSpecList module_spec_list; auto module_file_spec = - FileSpec(GetGlobalProperties()->GetLoggingModuleName(), false); + FileSpec(GetGlobalProperties()->GetLoggingModuleName()); module_spec_list.Append(module_file_spec); // We aren't specifying a source file set. diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp new file mode 100644 index 000000000000..2cca7a66b014 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -0,0 +1,223 @@ +//===-- SymbolFileBreakpad.cpp ----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h" +#include "Plugins/ObjectFile/Breakpad/ObjectFileBreakpad.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/Section.h" +#include "lldb/Host/FileSystem.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/TypeMap.h" +#include "lldb/Utility/Log.h" +#include "llvm/ADT/StringExtras.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::breakpad; + +namespace { +class LineIterator { +public: + // begin iterator for sections of given type + LineIterator(ObjectFile &obj, ConstString section_type) + : m_obj(&obj), m_section_type(section_type), m_next_section_idx(0) { + ++*this; + } + + // end iterator + explicit LineIterator(ObjectFile &obj) + : m_obj(&obj), + m_next_section_idx(m_obj->GetSectionList()->GetNumSections(0)) {} + + friend bool operator!=(const LineIterator &lhs, const LineIterator &rhs) { + assert(lhs.m_obj == rhs.m_obj); + if (lhs.m_next_section_idx != rhs.m_next_section_idx) + return true; + if (lhs.m_next_text.data() != rhs.m_next_text.data()) + return true; + assert(lhs.m_current_text == rhs.m_current_text); + assert(rhs.m_next_text == rhs.m_next_text); + return false; + } + + const LineIterator &operator++(); + llvm::StringRef operator*() const { return m_current_text; } + +private: + ObjectFile *m_obj; + ConstString m_section_type; + uint32_t m_next_section_idx; + llvm::StringRef m_current_text; + llvm::StringRef m_next_text; +}; +} // namespace + +const LineIterator &LineIterator::operator++() { + const SectionList &list = *m_obj->GetSectionList(); + size_t num_sections = list.GetNumSections(0); + while (m_next_text.empty() && m_next_section_idx < num_sections) { + Section § = *list.GetSectionAtIndex(m_next_section_idx++); + if (sect.GetName() != m_section_type) + continue; + DataExtractor data; + m_obj->ReadSectionData(§, data); + m_next_text = + llvm::StringRef(reinterpret_cast(data.GetDataStart()), + data.GetByteSize()); + } + std::tie(m_current_text, m_next_text) = m_next_text.split('\n'); + return *this; +} + +static llvm::iterator_range lines(ObjectFile &obj, + ConstString section_type) { + return llvm::make_range(LineIterator(obj, section_type), LineIterator(obj)); +} + +void SymbolFileBreakpad::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); +} + +void SymbolFileBreakpad::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +ConstString SymbolFileBreakpad::GetPluginNameStatic() { + static ConstString g_name("breakpad"); + return g_name; +} + +uint32_t SymbolFileBreakpad::CalculateAbilities() { + if (!m_obj_file) + return 0; + if (m_obj_file->GetPluginName() != ObjectFileBreakpad::GetPluginNameStatic()) + return 0; + + return CompileUnits | Functions; +} + +uint32_t SymbolFileBreakpad::GetNumCompileUnits() { + // TODO + return 0; +} + +CompUnitSP SymbolFileBreakpad::ParseCompileUnitAtIndex(uint32_t index) { + // TODO + return nullptr; +} + +size_t SymbolFileBreakpad::ParseFunctions(CompileUnit &comp_unit) { + // TODO + return 0; +} + +bool SymbolFileBreakpad::ParseLineTable(CompileUnit &comp_unit) { + // TODO + return 0; +} + +uint32_t +SymbolFileBreakpad::ResolveSymbolContext(const Address &so_addr, + SymbolContextItem resolve_scope, + SymbolContext &sc) { + // TODO + return 0; +} + +uint32_t SymbolFileBreakpad::FindFunctions( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + FunctionNameType name_type_mask, bool include_inlines, bool append, + SymbolContextList &sc_list) { + // TODO + if (!append) + sc_list.Clear(); + return sc_list.GetSize(); +} + +uint32_t SymbolFileBreakpad::FindFunctions(const RegularExpression ®ex, + bool include_inlines, bool append, + SymbolContextList &sc_list) { + // TODO + if (!append) + sc_list.Clear(); + return sc_list.GetSize(); +} + +uint32_t SymbolFileBreakpad::FindTypes( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, + llvm::DenseSet &searched_symbol_files, TypeMap &types) { + if (!append) + types.Clear(); + return types.GetSize(); +} + +size_t +SymbolFileBreakpad::FindTypes(const std::vector &context, + bool append, TypeMap &types) { + if (!append) + types.Clear(); + return types.GetSize(); +} + +void SymbolFileBreakpad::AddSymbols(Symtab &symtab) { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Module &module = *m_obj_file->GetModule(); + addr_t base = module.GetObjectFile()->GetBaseAddress().GetFileAddress(); + if (base == LLDB_INVALID_ADDRESS) { + LLDB_LOG(log, "Unable to fetch the base address of object file. Skipping " + "symtab population."); + return; + } + + const SectionList &list = *module.GetSectionList(); + for (llvm::StringRef line : lines(*m_obj_file, ConstString("PUBLIC"))) { + // PUBLIC [m] address param_size name + // skip PUBLIC keyword + line = getToken(line).second; + llvm::StringRef token; + std::tie(token, line) = getToken(line); + if (token == "m") + std::tie(token, line) = getToken(line); + + addr_t address; + if (!to_integer(token, address, 16)) + continue; + address += base; + + // skip param_size + line = getToken(line).second; + + llvm::StringRef name = line.trim(); + + SectionSP section_sp = list.FindSectionContainingFileAddress(address); + if (!section_sp) { + LLDB_LOG(log, + "Ignoring symbol {0}, whose address ({1}) is outside of the " + "object file. Mismatched symbol file?", + name, address); + continue; + } + + symtab.AddSymbol(Symbol( + /*symID*/ 0, Mangled(name, /*is_mangled*/ false), eSymbolTypeCode, + /*is_global*/ true, /*is_debug*/ false, /*is_trampoline*/ false, + /*is_artificial*/ false, + AddressRange(section_sp, address - section_sp->GetFileAddress(), 0), + /*size_is_valid*/ 0, /*contains_linker_annotations*/ false, + /*flags*/ 0)); + } + + // TODO: Process FUNC records as well. + + symtab.CalculateSymbolSizes(); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h new file mode 100644 index 000000000000..68e8d11c7dd7 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -0,0 +1,146 @@ +//===-- SymbolFileBreakpad.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H +#define LLDB_PLUGINS_SYMBOLFILE_BREAKPAD_SYMBOLFILEBREAKPAD_H + +#include "lldb/Symbol/SymbolFile.h" + +namespace lldb_private { + +namespace breakpad { + +class SymbolFileBreakpad : public SymbolFile { +public: + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); + static void Terminate(); + static void DebuggerInitialize(Debugger &debugger) {} + static ConstString GetPluginNameStatic(); + + static const char *GetPluginDescriptionStatic() { + return "Breakpad debug symbol file reader."; + } + + static SymbolFile *CreateInstance(ObjectFile *obj_file) { + return new SymbolFileBreakpad(obj_file); + } + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolFileBreakpad(ObjectFile *object_file) : SymbolFile(object_file) {} + + ~SymbolFileBreakpad() override {} + + uint32_t CalculateAbilities() override; + + void InitializeObject() override {} + + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ + + uint32_t GetNumCompileUnits() override; + + lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; + + lldb::LanguageType ParseLanguage(CompileUnit &comp_unit) override { + return lldb::eLanguageTypeUnknown; + } + + size_t ParseFunctions(CompileUnit &comp_unit) override; + + bool ParseLineTable(CompileUnit &comp_unit) override; + + bool ParseDebugMacros(CompileUnit &comp_unit) override { return false; } + + bool ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) override { + return false; + } + size_t ParseTypes(CompileUnit &cu) override { return 0; } + + bool + ParseImportedModules(const SymbolContext &sc, + std::vector &imported_modules) override { + return false; + } + + size_t ParseBlocksRecursive(Function &func) override { return 0; } + + uint32_t FindGlobalVariables(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + uint32_t max_matches, + VariableList &variables) override { + return 0; + } + + size_t ParseVariablesForContext(const SymbolContext &sc) override { + return 0; + } + Type *ResolveTypeUID(lldb::user_id_t type_uid) override { return nullptr; } + llvm::Optional GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override { + return llvm::None; + } + + bool CompleteType(CompilerType &compiler_type) override { return false; } + uint32_t ResolveSymbolContext(const Address &so_addr, + lldb::SymbolContextItem resolve_scope, + SymbolContext &sc) override; + + size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, + TypeList &type_list) override { + return 0; + } + + uint32_t FindFunctions(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + lldb::FunctionNameType name_type_mask, + bool include_inlines, bool append, + SymbolContextList &sc_list) override; + + uint32_t FindFunctions(const RegularExpression ®ex, bool include_inlines, + bool append, SymbolContextList &sc_list) override; + + uint32_t FindTypes(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, bool append, + uint32_t max_matches, + llvm::DenseSet &searched_symbol_files, + TypeMap &types) override; + + size_t FindTypes(const std::vector &context, bool append, + TypeMap &types) override; + + TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override { + return nullptr; + } + + CompilerDeclContext + FindNamespace(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx) override { + return CompilerDeclContext(); + } + + void AddSymbols(Symtab &symtab) override; + + ConstString GetPluginName() override { return GetPluginNameStatic(); } + uint32_t GetPluginVersion() override { return 1; } + +private: +}; + +} // namespace breakpad +} // namespace lldb_private + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index ae7c770d6ef7..24d5f26745dc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -12,10 +12,16 @@ #include "DWARFDefines.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" class DWARFDIE; +namespace lldb_private { +class CompileUnit; +class ExecutionContext; +} +class SymbolFileDWARF; class DWARFASTParser { public: @@ -27,7 +33,7 @@ public: bool *type_is_new_ptr) = 0; virtual lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, + ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die) = 0; virtual bool @@ -45,6 +51,10 @@ public: virtual std::vector GetDIEForDeclContext(lldb_private::CompilerDeclContext decl_context) = 0; + + static llvm::Optional + ParseChildArrayInfo(const DWARFDIE &parent_die, + const lldb_private::ExecutionContext *exe_ctx = nullptr); }; #endif // SymbolFileDWARF_DWARFASTParser_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index fe6f1be3ca48..70d48e5f1dfa 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -125,7 +125,7 @@ ClangASTImporter &DWARFASTParserClang::GetClangASTImporter() { } /// Detect a forward declaration that is nested in a DW_TAG_module. -static bool isClangModuleFwdDecl(const DWARFDIE &Die) { +static bool IsClangModuleFwdDecl(const DWARFDIE &Die) { if (!Die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0)) return false; auto Parent = Die.GetParent(); @@ -142,30 +142,31 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWO(const DWARFDIE &die, Log *log) { if (!dwo_module_sp) return TypeSP(); - // This type comes from an external DWO module. - std::vector dwo_context; - die.GetDWOContext(dwo_context); + // If this type comes from a Clang module, look in the DWARF section + // of the pcm file in the module cache. Clang generates DWO skeleton + // units as breadcrumbs to find them. + std::vector decl_context; + die.GetDeclContext(decl_context); TypeMap dwo_types; - if (!dwo_module_sp->GetSymbolVendor()->FindTypes(dwo_context, true, + if (!dwo_module_sp->GetSymbolVendor()->FindTypes(decl_context, true, dwo_types)) { - if (!isClangModuleFwdDecl(die)) + if (!IsClangModuleFwdDecl(die)) return TypeSP(); // Since this this type is defined in one of the Clang modules imported by // this symbol file, search all of them. - auto *SymFile = die.GetCU()->GetSymbolFileDWARF(); - for (const auto &NameModule : SymFile->getExternalTypeModules()) { - if (!NameModule.second) + auto *sym_file = die.GetCU()->GetSymbolFileDWARF(); + for (const auto &name_module : sym_file->getExternalTypeModules()) { + if (!name_module.second) continue; - SymbolVendor *SymVendor = NameModule.second->GetSymbolVendor(); - if (SymVendor->FindTypes(dwo_context, true, dwo_types)) + SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor(); + if (sym_vendor->FindTypes(decl_context, true, dwo_types)) break; } } - const size_t num_dwo_types = dwo_types.GetSize(); - if (num_dwo_types != 1) + if (dwo_types.GetSize() != 1) return TypeSP(); // We found a real definition for this type in the Clang module, so lets use @@ -307,14 +308,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, decl.SetColumn(form_value.Unsigned()); break; case DW_AT_name: - type_name_cstr = form_value.AsCString(); - // Work around a bug in llvm-gcc where they give a name to a - // reference type which doesn't include the "&"... - if (tag == DW_TAG_reference_type) { - if (strchr(type_name_cstr, '&') == NULL) - type_name_cstr = NULL; - } if (type_name_cstr) type_name_const_str.SetCString(type_name_cstr); break; @@ -421,8 +415,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || - encoding_data_type == Type::eEncodingIsTypedefUID) && - sc.comp_unit != NULL) { + encoding_data_type == Type::eEncodingIsTypedefUID)) { if (tag == DW_TAG_pointer_type) { DWARFDIE target_die = die.GetReferencedDIE(DW_AT_type); @@ -558,16 +551,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_decl_file: - if (die.GetCU()->DW_AT_decl_file_attributes_are_invalid()) { - // llvm-gcc outputs invalid DW_AT_decl_file attributes that - // always point to the compile unit file, so we clear this - // invalid value so that we can still unique types - // efficiently. - decl.SetFile(FileSpec("", false)); - } else - decl.SetFile( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( - form_value.Unsigned())); + decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + form_value.Unsigned())); break; case DW_AT_decl_line: @@ -671,7 +656,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, } if (byte_size_valid && byte_size == 0 && type_name_cstr && - die.HasChildren() == false && + !die.HasChildren() && sc.comp_unit->GetLanguage() == eLanguageTypeObjC) { // Work around an issue with clang at the moment where forward // declarations for objective C classes are emitted as: @@ -909,7 +894,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, // has child classes or types that require the class to be created // for use as their decl contexts the class will be ready to accept // these child definitions. - if (die.HasChildren() == false) { + if (!die.HasChildren()) { // No children for this struct/union/class, lets finish it if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) { ClangASTContext::CompleteTagDeclarationDefinition(clang_type); @@ -1308,10 +1293,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, if (die.HasChildren()) { bool skip_artificial = true; - ParseChildParameters(sc, containing_decl_ctx, die, skip_artificial, - is_static, is_variadic, has_template_params, - function_param_types, function_param_decls, - type_quals); + ParseChildParameters(*sc.comp_unit, containing_decl_ctx, die, + skip_artificial, is_static, is_variadic, + has_template_params, function_param_types, + function_param_decls, type_quals); } bool ignore_containing_context = false; @@ -1748,16 +1733,19 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, Type *element_type = dwarf->ResolveTypeUID(type_die_ref); if (element_type) { - std::vector element_orders; - ParseChildArrayInfo(sc, die, first_index, element_orders, - byte_stride, bit_stride); + auto array_info = ParseChildArrayInfo(die); + if (array_info) { + first_index = array_info->first_index; + byte_stride = array_info->byte_stride; + bit_stride = array_info->bit_stride; + } if (byte_stride == 0 && bit_stride == 0) byte_stride = element_type->GetByteSize(); CompilerType array_element_type = element_type->GetForwardCompilerType(); if (ClangASTContext::IsCXXClassType(array_element_type) && - array_element_type.GetCompleteType() == false) { + !array_element_type.GetCompleteType()) { ModuleSP module_sp = die.GetModule(); if (module_sp) { if (die.GetCU()->GetProducer() == eProducerClang) @@ -1800,12 +1788,11 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, } uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride; - if (element_orders.size() > 0) { + if (array_info && array_info->element_orders.size() > 0) { uint64_t num_elements = 0; - std::vector::const_reverse_iterator pos; - std::vector::const_reverse_iterator end = - element_orders.rend(); - for (pos = element_orders.rbegin(); pos != end; ++pos) { + auto end = array_info->element_orders.rend(); + for (auto pos = array_info->element_orders.rbegin(); pos != end; + ++pos) { num_elements = *pos; clang_type = m_ast.CreateArrayType(array_element_type, num_elements, is_vector); @@ -1824,6 +1811,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, NULL, DIERef(type_die_form).GetUID(dwarf), Type::eEncodingIsUID, &decl, clang_type, Type::eResolveStateFull)); type_sp->SetEncodingType(element_type); + m_ast.SetMetadataAsUserID(clang_type.GetOpaqueQualType(), + die.GetID()); } } } break; @@ -1861,12 +1850,14 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc, clang_type = ClangASTContext::CreateMemberPointerType( class_clang_type, pointee_clang_type); - byte_size = clang_type.GetByteSize(nullptr); - - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, - byte_size, NULL, LLDB_INVALID_UID, - Type::eEncodingIsUID, NULL, clang_type, - Type::eResolveStateForward)); + if (llvm::Optional clang_type_size = + clang_type.GetByteSize(nullptr)) { + byte_size = *clang_type_size; + type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, + byte_size, NULL, LLDB_INVALID_UID, + Type::eEncodingIsUID, NULL, clang_type, + Type::eResolveStateForward)); + } } break; @@ -2056,7 +2047,10 @@ bool DWARFASTParserClang::ParseTemplateDIE( clang_type.IsIntegerOrEnumerationType(is_signed); if (tag == DW_TAG_template_value_parameter && uval64_valid) { - llvm::APInt apint(clang_type.GetBitSize(nullptr), uval64, is_signed); + llvm::Optional size = clang_type.GetBitSize(nullptr); + if (!size) + return false; + llvm::APInt apint(*size, uval64, is_signed); template_param_infos.args.push_back( clang::TemplateArgument(*ast, llvm::APSInt(apint, !is_signed), ClangUtil::GetQualType(clang_type))); @@ -2108,95 +2102,6 @@ bool DWARFASTParserClang::ParseTemplateParameterInfos( return template_param_infos.args.size() == template_param_infos.names.size(); } -// Checks whether m1 is an overload of m2 (as opposed to an override). This is -// called by addOverridesForMethod to distinguish overrides (which share a -// vtable entry) from overloads (which require distinct entries). -static bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) { - // FIXME: This should detect covariant return types, but currently doesn't. - lldbassert(&m1->getASTContext() == &m2->getASTContext() && - "Methods should have the same AST context"); - clang::ASTContext &context = m1->getASTContext(); - - const auto *m1Type = - llvm::cast( - context.getCanonicalType(m1->getType())); - - const auto *m2Type = - llvm::cast( - context.getCanonicalType(m2->getType())); - - auto compareArgTypes = - [&context](const clang::QualType &m1p, const clang::QualType &m2p) { - return context.hasSameType(m1p.getUnqualifiedType(), - m2p.getUnqualifiedType()); - }; - - // FIXME: In C++14 and later, we can just pass m2Type->param_type_end() - // as a fourth parameter to std::equal(). - return (m1->getNumParams() != m2->getNumParams()) || - !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(), - m2Type->param_type_begin(), compareArgTypes); -} - -// If decl is a virtual method, walk the base classes looking for methods that -// decl overrides. This table of overridden methods is used by IRGen to -// determine the vtable layout for decl's parent class. -static void addOverridesForMethod(clang::CXXMethodDecl *decl) { - if (!decl->isVirtual()) - return; - - clang::CXXBasePaths paths; - - auto find_overridden_methods = - [decl](const clang::CXXBaseSpecifier *specifier, clang::CXXBasePath &path) { - if (auto *base_record = - llvm::dyn_cast( - specifier->getType()->getAs()->getDecl())) { - - clang::DeclarationName name = decl->getDeclName(); - - // If this is a destructor, check whether the base class destructor is - // virtual. - if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) - if (auto *baseDtorDecl = base_record->getDestructor()) { - if (baseDtorDecl->isVirtual()) { - path.Decls = baseDtorDecl; - return true; - } else - return false; - } - - // Otherwise, search for name in the base class. - for (path.Decls = base_record->lookup(name); !path.Decls.empty(); - path.Decls = path.Decls.slice(1)) { - if (auto *method_decl = - llvm::dyn_cast(path.Decls.front())) - if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { - path.Decls = method_decl; - return true; - } - } - } - - return false; - }; - - if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) { - for (auto *overridden_decl : paths.found_decls()) - decl->addOverriddenMethod( - llvm::cast(overridden_decl)); - } -} - -// If clang_type is a CXXRecordDecl, builds the method override list for each -// of its virtual methods. -static void addMethodOverrides(ClangASTContext &ast, CompilerType &clang_type) { - if (auto *record = - ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType())) - for (auto *method : record->methods()) - addOverridesForMethod(method); -} - bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, CompilerType &clang_type) { @@ -2287,14 +2192,14 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, } SymbolContext sc(die.GetLLDBCompileUnit()); - std::vector base_classes; + std::vector> bases; std::vector member_accessibilities; bool is_a_class = false; // Parse members and base classes first DWARFDIECollection member_function_dies; DelayedPropertyList delayed_properties; - ParseChildMembers(sc, die, clang_type, class_language, base_classes, + ParseChildMembers(sc, die, clang_type, class_language, bases, member_accessibilities, member_function_dies, delayed_properties, default_accessibility, is_a_class, layout_info); @@ -2358,17 +2263,17 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, &member_accessibilities.front(), member_accessibilities.size()); } - if (!base_classes.empty()) { + if (!bases.empty()) { // Make sure all base classes refer to complete types and not forward // declarations. If we don't do this, clang will crash with an - // assertion in the call to clang_type.SetBaseClassesForClassType() - for (auto &base_class : base_classes) { + // assertion in the call to clang_type.TransferBaseClasses() + for (const auto &base_class : bases) { clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo(); if (type_source_info) { CompilerType base_class_type( &m_ast, type_source_info->getType().getAsOpaquePtr()); - if (base_class_type.GetCompleteType() == false) { + if (!base_class_type.GetCompleteType()) { auto module = dwarf->GetObjectFile()->GetModule(); module->ReportError(":: Class '%s' has a base class '%s' which " "does not have a complete definition.", @@ -2381,7 +2286,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, // We have no choice other than to pretend that the base class // is complete. If we don't do this, clang will crash when we // call setBases() inside of - // "clang_type.SetBaseClassesForClassType()" below. Since we + // "clang_type.TransferBaseClasses()" below. Since we // provide layout assistance, all ivars in this class and other // classes will be fine, this is the best we can do short of // crashing. @@ -2393,19 +2298,14 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die, } } } - m_ast.SetBaseClassesForClassType(clang_type.GetOpaqueQualType(), - &base_classes.front(), - base_classes.size()); - // Clang will copy each CXXBaseSpecifier in "base_classes" so we have - // to free them all. - ClangASTContext::DeleteBaseClassSpecifiers(&base_classes.front(), - base_classes.size()); + m_ast.TransferBaseClasses(clang_type.GetOpaqueQualType(), + std::move(bases)); } } } - addMethodOverrides(m_ast, clang_type); + m_ast.AddMethodOverridesForCXXRecordType(clang_type.GetOpaqueQualType()); ClangASTContext::BuildIndirectFields(clang_type); ClangASTContext::CompleteTagDeclarationDefinition(clang_type); @@ -2604,9 +2504,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators( if (name && name[0] && got_value) { m_ast.AddEnumerationValueToEnumerationType( - clang_type.GetOpaqueQualType(), - m_ast.GetEnumerationIntegerType(clang_type.GetOpaqueQualType()), - decl, name, enum_value, enumerator_byte_size * 8); + clang_type, decl, name, enum_value, enumerator_byte_size * 8); ++enumerators_added; } } @@ -2663,7 +2561,7 @@ protected: }; #endif -Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, +Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit, const DWARFDIE &die) { DWARFRangeList func_ranges; const char *name = NULL; @@ -2724,9 +2622,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(die, nullptr); - ParseChildParameters(sc, containing_decl_ctx, die, true, is_static, - is_variadic, has_template_params, param_types, - param_decls, type_quals); + ParseChildParameters(comp_unit, containing_decl_ctx, die, true, + is_static, is_variadic, has_template_params, + param_types, param_decls, type_quals); sstr << "("; for (size_t i = 0; i < param_types.size(); i++) { if (i > 0) @@ -2747,7 +2645,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, std::unique_ptr decl_ap; if (decl_file != 0 || decl_line != 0 || decl_column != 0) decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), + comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); SymbolFileDWARF *dwarf = die.GetDWARF(); @@ -2758,7 +2656,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, if (dwarf->FixupAddress(func_range.GetBaseAddress())) { const user_id_t func_user_id = die.GetID(); - func_sp.reset(new Function(sc.comp_unit, + func_sp.reset(new Function(&comp_unit, func_user_id, // UserID is the DIE offset func_user_id, func_name, func_type, func_range)); // first address range @@ -2766,7 +2664,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, if (func_sp.get() != NULL) { if (frame_base.IsValid()) func_sp->GetFrameBaseExpression() = frame_base; - sc.comp_unit->AddFunction(func_sp); + comp_unit.AddFunction(func_sp); return func_sp.get(); } } @@ -2778,7 +2676,7 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(const SymbolContext &sc, bool DWARFASTParserClang::ParseChildMembers( const SymbolContext &sc, const DWARFDIE &parent_die, CompilerType &class_clang_type, const LanguageType class_language, - std::vector &base_classes, + std::vector> &base_classes, std::vector &member_accessibilities, DWARFDIECollection &member_function_dies, DelayedPropertyList &delayed_properties, AccessType &default_accessibility, @@ -2977,15 +2875,6 @@ bool DWARFASTParserClang::ParseChildMembers( class_language == eLanguageTypeObjC_plus_plus) accessibility = eAccessNone; - if (member_idx == 0 && !is_artificial && name && - (strstr(name, "_vptr$") == name)) { - // Not all compilers will mark the vtable pointer member as - // artificial (llvm-gcc). We can't have the virtual members in our - // classes otherwise it throws off all child offsets since we end up - // having and extra pointer sized member in our class layouts. - is_artificial = true; - } - // Handle static members if (is_external && member_byte_offset == UINT32_MAX) { Type *var_type = die.ResolveTypeUID(DIERef(encoding_form)); @@ -3000,7 +2889,7 @@ bool DWARFASTParserClang::ParseChildMembers( break; } - if (is_artificial == false) { + if (!is_artificial) { Type *member_type = die.ResolveTypeUID(DIERef(encoding_form)); clang::FieldDecl *field_decl = NULL; @@ -3141,7 +3030,7 @@ bool DWARFASTParserClang::ParseChildMembers( if (anon_field_info.IsValid()) { clang::FieldDecl *unnamed_bitfield_decl = ClangASTContext::AddFieldToRecordType( - class_clang_type, NULL, + class_clang_type, llvm::StringRef(), m_ast.GetBuiltinTypeForEncodingAndBitSize( eEncodingSint, word_width), accessibility, anon_field_info.bit_size); @@ -3198,7 +3087,7 @@ bool DWARFASTParserClang::ParseChildMembers( } if (ClangASTContext::IsCXXClassType(member_clang_type) && - member_clang_type.GetCompleteType() == false) { + !member_clang_type.GetCompleteType()) { if (die.GetCU()->GetProducer() == eProducerClang) module_sp->ReportError( "DWARF DIE at 0x%8.8x (class %s) has a member variable " @@ -3383,9 +3272,14 @@ bool DWARFASTParserClang::ParseChildMembers( if (class_language == eLanguageTypeObjC) { ast->SetObjCSuperClass(class_clang_type, base_class_clang_type); } else { - base_classes.push_back(ast->CreateBaseClassSpecifier( - base_class_clang_type.GetOpaqueQualType(), accessibility, - is_virtual, is_base_of_class)); + std::unique_ptr result = + ast->CreateBaseClassSpecifier( + base_class_clang_type.GetOpaqueQualType(), accessibility, + is_virtual, is_base_of_class); + if (!result) + break; + + base_classes.push_back(std::move(result)); if (is_virtual) { // Do not specify any offset for virtual inheritance. The DWARF @@ -3419,7 +3313,7 @@ bool DWARFASTParserClang::ParseChildMembers( } size_t DWARFASTParserClang::ParseChildParameters( - const SymbolContext &sc, clang::DeclContext *containing_decl_ctx, + CompileUnit &comp_unit, clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die, bool skip_artificial, bool &is_static, bool &is_variadic, bool &has_template_params, std::vector &function_param_types, @@ -3451,7 +3345,7 @@ size_t DWARFASTParserClang::ParseChildParameters( if (attributes.ExtractFormValueAtIndex(i, form_value)) { switch (attr) { case DW_AT_decl_file: - decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex( + decl.SetFile(comp_unit.GetSupportFiles().GetFileSpecAtIndex( form_value.Unsigned())); break; case DW_AT_decl_line: @@ -3517,8 +3411,9 @@ size_t DWARFASTParserClang::ParseChildParameters( function_param_types.push_back(type->GetForwardCompilerType()); clang::ParmVarDecl *param_var_decl = - m_ast.CreateParameterDeclaration( - name, type->GetForwardCompilerType(), storage); + m_ast.CreateParameterDeclaration(containing_decl_ctx, name, + type->GetForwardCompilerType(), + storage); assert(param_var_decl); function_param_decls.push_back(param_var_decl); @@ -3551,12 +3446,12 @@ size_t DWARFASTParserClang::ParseChildParameters( return arg_idx; } -void DWARFASTParserClang::ParseChildArrayInfo( - const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, - std::vector &element_orders, uint32_t &byte_stride, - uint32_t &bit_stride) { +llvm::Optional +DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, + const ExecutionContext *exe_ctx) { + SymbolFile::ArrayInfo array_info; if (!parent_die) - return; + return llvm::None; for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); die = die.GetSibling()) { @@ -3580,15 +3475,31 @@ void DWARFASTParserClang::ParseChildArrayInfo( break; case DW_AT_count: - num_elements = form_value.Unsigned(); + if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { + if (var_die.Tag() == DW_TAG_variable) + if (exe_ctx) { + if (auto frame = exe_ctx->GetFrameSP()) { + Status error; + lldb::VariableSP var_sp; + auto valobj_sp = frame->GetValueForVariableExpressionPath( + var_die.GetName(), eNoDynamicValues, 0, var_sp, + error); + if (valobj_sp) { + num_elements = valobj_sp->GetValueAsUnsigned(0); + break; + } + } + } + } else + num_elements = form_value.Unsigned(); break; case DW_AT_bit_stride: - bit_stride = form_value.Unsigned(); + array_info.bit_stride = form_value.Unsigned(); break; case DW_AT_byte_stride: - byte_stride = form_value.Unsigned(); + array_info.byte_stride = form_value.Unsigned(); break; case DW_AT_lower_bound: @@ -3622,11 +3533,12 @@ void DWARFASTParserClang::ParseChildArrayInfo( num_elements = upper_bound - lower_bound + 1; } - element_orders.push_back(num_elements); + array_info.element_orders.push_back(num_elements); } } break; } } + return array_info; } Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h index 57c1fc07b2b6..63e058d7bf21 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h @@ -10,15 +10,11 @@ #ifndef SymbolFileDWARF_DWARFASTParserClang_h_ #define SymbolFileDWARF_DWARFASTParserClang_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "clang/AST/CharUnits.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" -// Project includes #include "DWARFASTParser.h" #include "DWARFDefines.h" #include "lldb/Core/ClangForward.h" @@ -26,8 +22,12 @@ #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangASTImporter.h" +namespace lldb_private { +class CompileUnit; +} class DWARFDebugInfoEntry; class DWARFDIECollection; +class SymbolFileDWARF; class DWARFASTParserClang : public DWARFASTParser { public: @@ -41,7 +41,7 @@ public: bool *type_is_new_ptr) override; lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, + ParseFunctionFromDWARF(lldb_private::CompileUnit &comp_unit, const DWARFDIE &die) override; bool @@ -80,19 +80,19 @@ protected: lldb_private::ClangASTContext::TemplateParameterInfos &template_param_infos); - bool - ParseChildMembers(const lldb_private::SymbolContext &sc, const DWARFDIE &die, - lldb_private::CompilerType &class_compiler_type, - const lldb::LanguageType class_language, - std::vector &base_classes, - std::vector &member_accessibilities, - DWARFDIECollection &member_function_dies, - DelayedPropertyList &delayed_properties, - lldb::AccessType &default_accessibility, bool &is_a_class, - lldb_private::ClangASTImporter::LayoutInfo &layout_info); + bool ParseChildMembers( + const lldb_private::SymbolContext &sc, const DWARFDIE &die, + lldb_private::CompilerType &class_compiler_type, + const lldb::LanguageType class_language, + std::vector> &base_classes, + std::vector &member_accessibilities, + DWARFDIECollection &member_function_dies, + DelayedPropertyList &delayed_properties, + lldb::AccessType &default_accessibility, bool &is_a_class, + lldb_private::ClangASTImporter::LayoutInfo &layout_info); size_t - ParseChildParameters(const lldb_private::SymbolContext &sc, + ParseChildParameters(lldb_private::CompileUnit &comp_unit, clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die, bool skip_artificial, bool &is_static, bool &is_variadic, @@ -101,11 +101,6 @@ protected: std::vector &function_param_decls, unsigned &type_quals); - void ParseChildArrayInfo(const lldb_private::SymbolContext &sc, - const DWARFDIE &parent_die, int64_t &first_index, - std::vector &element_orders, - uint32_t &byte_stride, uint32_t &bit_stride); - size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc, lldb_private::CompilerType &compiler_type, bool is_signed, uint32_t enumerator_byte_size, diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp deleted file mode 100644 index 328212e4b684..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.cpp +++ /dev/null @@ -1,772 +0,0 @@ -//===-- DWARFASTParserGo.cpp ---------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "DWARFASTParserGo.h" - -#include "DWARFASTParserGo.h" -#include "DWARFDIE.h" -#include "DWARFDIECollection.h" -#include "DWARFDebugInfo.h" -#include "DWARFDeclContext.h" -#include "DWARFDefines.h" -#include "SymbolFileDWARF.h" -#include "SymbolFileDWARFDebugMap.h" -#include "UniqueDWARFASTType.h" - -#include "clang/Basic/Specifiers.h" - -#include "lldb/Core/Module.h" -#include "lldb/Core/Value.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/TypeList.h" - -//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN - -#ifdef ENABLE_DEBUG_PRINTF -#include -#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__) -#else -#define DEBUG_PRINTF(fmt, ...) -#endif - -#define DW_AT_go_kind 0x2900 -#define DW_AT_go_key 0x2901 -#define DW_AT_go_elem 0x2902 - -using namespace lldb; -using namespace lldb_private; -DWARFASTParserGo::DWARFASTParserGo(GoASTContext &ast) : m_ast(ast) {} - -DWARFASTParserGo::~DWARFASTParserGo() {} - -TypeSP DWARFASTParserGo::ParseTypeFromDWARF( - const lldb_private::SymbolContext &sc, const DWARFDIE &die, - lldb_private::Log *log, bool *type_is_new_ptr) { - TypeSP type_sp; - - if (type_is_new_ptr) - *type_is_new_ptr = false; - - if (die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - if (log) { - dwarf->GetObjectFile()->GetModule()->LogMessage( - log, "DWARFASTParserGo::ParseTypeFromDWARF (die = 0x%8.8x) %s name = " - "'%s')", - die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName()); - } - - Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE()); - TypeList *type_list = dwarf->GetTypeList(); - if (type_ptr == NULL) { - if (type_is_new_ptr) - *type_is_new_ptr = true; - - const dw_tag_t tag = die.Tag(); - - bool is_forward_declaration = false; - DWARFAttributes attributes; - const char *type_name_cstr = NULL; - ConstString type_name_const_str; - Type::ResolveState resolve_state = Type::eResolveStateUnresolved; - uint64_t byte_size = 0; - uint64_t go_kind = 0; - Declaration decl; - - Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID; - CompilerType compiler_type; - DWARFFormValue form_value; - - dw_attr_t attr; - - switch (tag) { - case DW_TAG_base_type: - case DW_TAG_pointer_type: - case DW_TAG_typedef: - case DW_TAG_unspecified_type: { - // Set a bit that lets us know that we are currently parsing this - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - const size_t num_attributes = die.GetAttributes(attributes); - lldb::user_id_t encoding_uid = LLDB_INVALID_UID; - - if (num_attributes > 0) { - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - if (type_name_cstr) - type_name_const_str.SetCString(type_name_cstr); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_encoding: - // = form_value.Unsigned(); - break; - case DW_AT_type: - encoding_uid = form_value.Reference(); - break; - case DW_AT_go_kind: - go_kind = form_value.Unsigned(); - break; - default: - // Do we care about DW_AT_go_key or DW_AT_go_elem? - break; - } - } - } - } - - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", - die.GetID(), DW_TAG_value_to_name(tag), type_name_cstr, - encoding_uid); - - switch (tag) { - default: - break; - - case DW_TAG_unspecified_type: - resolve_state = Type::eResolveStateFull; - compiler_type = m_ast.CreateVoidType(type_name_const_str); - break; - - case DW_TAG_base_type: - resolve_state = Type::eResolveStateFull; - compiler_type = - m_ast.CreateBaseType(go_kind, type_name_const_str, byte_size); - break; - - case DW_TAG_pointer_type: - encoding_data_type = Type::eEncodingIsPointerUID; - break; - case DW_TAG_typedef: - encoding_data_type = Type::eEncodingIsTypedefUID; - CompilerType impl; - Type *type = dwarf->ResolveTypeUID(encoding_uid); - if (type) { - if (go_kind == 0 && type->GetName() == type_name_const_str) { - // Go emits extra typedefs as a forward declaration. Ignore - // these. - dwarf->m_die_to_type[die.GetDIE()] = type; - return type->shared_from_this(); - } - impl = type->GetForwardCompilerType(); - compiler_type = - m_ast.CreateTypedefType(go_kind, type_name_const_str, impl); - } - break; - } - - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, - byte_size, NULL, encoding_uid, - encoding_data_type, &decl, compiler_type, - resolve_state)); - - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - } break; - - case DW_TAG_structure_type: { - // Set a bit that lets us know that we are currently parsing this - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - bool byte_size_valid = false; - - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - type_name_const_str.SetCString(type_name_cstr); - break; - - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - byte_size_valid = true; - break; - - case DW_AT_go_kind: - go_kind = form_value.Unsigned(); - break; - - // TODO: Should we use SLICETYPE's DW_AT_go_elem? - default: - break; - } - } - } - } - - // TODO(ribrdb): Do we need this? - - // UniqueDWARFASTType is large, so don't create a local variables on - // the stack, put it on the heap. This function is often called - // recursively and clang isn't good and sharing the stack space for - // variables in different blocks. - std::unique_ptr unique_ast_entry_ap( - new UniqueDWARFASTType()); - - // Only try and unique the type if it has a name. - if (type_name_const_str && - dwarf->GetUniqueDWARFASTTypeMap().Find( - type_name_const_str, die, decl, - byte_size_valid ? byte_size : -1, *unique_ast_entry_ap)) { - // We have already parsed this type or from another compile unit. GCC - // loves to use the "one definition rule" which can result in - // multiple definitions of the same class over and over in each - // compile unit. - type_sp = unique_ast_entry_ap->m_type_sp; - if (type_sp) { - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - return type_sp; - } - } - - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), - DW_TAG_value_to_name(tag), type_name_cstr); - - bool compiler_type_was_created = false; - compiler_type.SetCompilerType( - &m_ast, - dwarf->m_forward_decl_die_to_clang_type.lookup(die.GetDIE())); - if (!compiler_type) { - compiler_type_was_created = true; - compiler_type = - m_ast.CreateStructType(go_kind, type_name_const_str, byte_size); - } - - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, - byte_size, NULL, LLDB_INVALID_UID, - Type::eEncodingIsUID, &decl, compiler_type, - Type::eResolveStateForward)); - - // Add our type to the unique type map so we don't end up creating many - // copies of the same type over and over in the ASTContext for our - // module - unique_ast_entry_ap->m_type_sp = type_sp; - unique_ast_entry_ap->m_die = die; - unique_ast_entry_ap->m_declaration = decl; - unique_ast_entry_ap->m_byte_size = byte_size; - dwarf->GetUniqueDWARFASTTypeMap().Insert(type_name_const_str, - *unique_ast_entry_ap); - - if (!is_forward_declaration) { - // Always start the definition for a class type so that if the class - // has child classes or types that require the class to be created - // for use as their decl contexts the class will be ready to accept - // these child definitions. - if (die.HasChildren() == false) { - // No children for this struct/union/class, lets finish it - m_ast.CompleteStructType(compiler_type); - } else if (compiler_type_was_created) { - // Leave this as a forward declaration until we need to know the - // details of the type. lldb_private::Type will automatically call - // the SymbolFile virtual function - // "SymbolFileDWARF::CompleteType(Type *)" When the definition - // needs to be defined. - dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] = - compiler_type.GetOpaqueQualType(); - dwarf->m_forward_decl_clang_type_to_die[compiler_type - .GetOpaqueQualType()] = - die.GetDIERef(); - // SetHasExternalStorage (compiler_type.GetOpaqueQualType(), true); - } - } - } break; - - case DW_TAG_subprogram: - case DW_TAG_subroutine_type: { - // Set a bit that lets us know that we are currently parsing this - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - bool is_variadic = false; - clang::StorageClass storage = - clang::SC_None; //, Extern, Static, PrivateExtern - - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - type_name_const_str.SetCString(type_name_cstr); - break; - - case DW_AT_external: - if (form_value.Unsigned()) { - if (storage == clang::SC_None) - storage = clang::SC_Extern; - else - storage = clang::SC_PrivateExtern; - } - break; - - case DW_AT_high_pc: - case DW_AT_low_pc: - break; - } - } - } - } - - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), - DW_TAG_value_to_name(tag), type_name_cstr); - - std::vector function_param_types; - - // Parse the function children for the parameters - - if (die.HasChildren()) { - ParseChildParameters(sc, die, is_variadic, function_param_types); - } - - // compiler_type will get the function prototype clang type after this - // call - compiler_type = m_ast.CreateFunctionType( - type_name_const_str, function_param_types.data(), - function_param_types.size(), is_variadic); - - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, 0, NULL, - LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, - compiler_type, Type::eResolveStateFull)); - assert(type_sp.get()); - } break; - - case DW_TAG_array_type: { - // Set a bit that lets us know that we are currently parsing this - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - lldb::user_id_t type_die_offset = DW_INVALID_OFFSET; - int64_t first_index = 0; - uint32_t byte_stride = 0; - uint32_t bit_stride = 0; - const size_t num_attributes = die.GetAttributes(attributes); - - if (num_attributes > 0) { - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name_cstr = form_value.AsCString(); - type_name_const_str.SetCString(type_name_cstr); - break; - - case DW_AT_type: - type_die_offset = form_value.Reference(); - break; - case DW_AT_byte_size: - break; // byte_size = form_value.Unsigned(); break; - case DW_AT_go_kind: - go_kind = form_value.Unsigned(); - break; - default: - break; - } - } - } - - DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(), - DW_TAG_value_to_name(tag), type_name_cstr); - - Type *element_type = dwarf->ResolveTypeUID(type_die_offset); - - if (element_type) { - std::vector element_orders; - ParseChildArrayInfo(sc, die, first_index, element_orders, - byte_stride, bit_stride); - if (byte_stride == 0) - byte_stride = element_type->GetByteSize(); - CompilerType array_element_type = - element_type->GetForwardCompilerType(); - if (element_orders.size() > 0) { - if (element_orders.size() > 1) - printf("golang: unsupported multi-dimensional array %s\n", - type_name_cstr); - compiler_type = m_ast.CreateArrayType( - type_name_const_str, array_element_type, element_orders[0]); - } else { - compiler_type = m_ast.CreateArrayType(type_name_const_str, - array_element_type, 0); - } - type_sp.reset(new Type(die.GetID(), dwarf, type_name_const_str, - byte_stride, NULL, type_die_offset, - Type::eEncodingIsUID, &decl, compiler_type, - Type::eResolveStateFull)); - type_sp->SetEncodingType(element_type); - } - } - } break; - - default: - dwarf->GetObjectFile()->GetModule()->ReportError( - "{0x%8.8x}: unhandled type tag 0x%4.4x (%s), " - "please file a bug and attach the file at the " - "start of this error message", - die.GetOffset(), tag, DW_TAG_value_to_name(tag)); - break; - } - - if (type_sp.get()) { - DWARFDIE sc_parent_die = - SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); - - SymbolContextScope *symbol_context_scope = NULL; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { - symbol_context_scope = sc.comp_unit; - } else if (sc.function != NULL && sc_parent_die) { - symbol_context_scope = - sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); - if (symbol_context_scope == NULL) - symbol_context_scope = sc.function; - } - - if (symbol_context_scope != NULL) { - type_sp->SetSymbolContextScope(symbol_context_scope); - } - - // We are ready to put this type into the uniqued list up at the module - // level - type_list->Insert(type_sp); - - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - } - } else if (type_ptr != DIE_IS_BEING_PARSED) { - type_sp = type_ptr->shared_from_this(); - } - } - return type_sp; -} - -size_t DWARFASTParserGo::ParseChildParameters( - const SymbolContext &sc, - - const DWARFDIE &parent_die, bool &is_variadic, - std::vector &function_param_types) { - if (!parent_die) - return 0; - - size_t arg_idx = 0; - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { - - dw_tag_t tag = die.Tag(); - switch (tag) { - case DW_TAG_formal_parameter: { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - Declaration decl; - DWARFFormValue param_type_die_offset; - - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - // = form_value.AsCString(); - break; - case DW_AT_type: - param_type_die_offset = form_value; - break; - case DW_AT_location: - // if (form_value.BlockData()) - // { - // const DWARFDataExtractor& - // debug_info_data = - // debug_info(); - // uint32_t block_length = - // form_value.Unsigned(); - // DWARFDataExtractor - // location(debug_info_data, - // form_value.BlockData() - - // debug_info_data.GetDataStart(), - // block_length); - // } - // else - // { - // } - // break; - default: - break; - } - } - } - - Type *type = parent_die.ResolveTypeUID(DIERef(param_type_die_offset)); - if (type) { - function_param_types.push_back(type->GetForwardCompilerType()); - } - } - arg_idx++; - } break; - - case DW_TAG_unspecified_parameters: - is_variadic = true; - break; - - default: - break; - } - } - return arg_idx; -} - -void DWARFASTParserGo::ParseChildArrayInfo( - const SymbolContext &sc, const DWARFDIE &parent_die, int64_t &first_index, - std::vector &element_orders, uint32_t &byte_stride, - uint32_t &bit_stride) { - if (!parent_die) - return; - - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { - const dw_tag_t tag = die.Tag(); - switch (tag) { - case DW_TAG_subrange_type: { - DWARFAttributes attributes; - const size_t num_child_attributes = die.GetAttributes(attributes); - if (num_child_attributes > 0) { - uint64_t num_elements = 0; - uint32_t i; - for (i = 0; i < num_child_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_count: - num_elements = form_value.Unsigned(); - break; - - default: - case DW_AT_type: - break; - } - } - } - - element_orders.push_back(num_elements); - } - } break; - } - } -} - -bool DWARFASTParserGo::CompleteTypeFromDWARF(const DWARFDIE &die, - lldb_private::Type *type, - CompilerType &compiler_type) { - if (!die) - return false; - - const dw_tag_t tag = die.Tag(); - - SymbolFileDWARF *dwarf = die.GetDWARF(); - Log *log = - nullptr; // (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION)); - if (log) - dwarf->GetObjectFile()->GetModule()->LogMessageVerboseBacktrace( - log, "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...", - die.GetID(), DW_TAG_value_to_name(tag), type->GetName().AsCString()); - assert(compiler_type); - DWARFAttributes attributes; - - switch (tag) { - case DW_TAG_structure_type: { - { - if (die.HasChildren()) { - SymbolContext sc(die.GetLLDBCompileUnit()); - - ParseChildMembers(sc, die, compiler_type); - } - } - m_ast.CompleteStructType(compiler_type); - return (bool)compiler_type; - } - - default: - assert(false && "not a forward go type decl!"); - break; - } - - return false; -} - -size_t DWARFASTParserGo::ParseChildMembers(const SymbolContext &sc, - const DWARFDIE &parent_die, - CompilerType &class_compiler_type) { - size_t count = 0; - uint32_t member_idx = 0; - - ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule(); - GoASTContext *ast = - llvm::dyn_cast_or_null(class_compiler_type.GetTypeSystem()); - if (ast == nullptr) - return 0; - - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { - dw_tag_t tag = die.Tag(); - - switch (tag) { - case DW_TAG_member: { - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - if (num_attributes > 0) { - Declaration decl; - const char *name = NULL; - - DWARFFormValue encoding_uid; - uint32_t member_byte_offset = UINT32_MAX; - uint32_t i; - for (i = 0; i < num_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - name = form_value.AsCString(); - break; - case DW_AT_type: - encoding_uid = form_value; - break; - case DW_AT_data_member_location: - if (form_value.BlockData()) { - Value initialValue(0); - Value memberOffset(0); - const DWARFDataExtractor &debug_info_data = die.GetData(); - uint32_t block_length = form_value.Unsigned(); - uint32_t block_offset = - form_value.BlockData() - debug_info_data.GetDataStart(); - if (DWARFExpression::Evaluate( - NULL, // ExecutionContext * - NULL, // RegisterContext * - module_sp, debug_info_data, die.GetCU(), block_offset, - block_length, eRegisterKindDWARF, &initialValue, NULL, - memberOffset, NULL)) { - member_byte_offset = memberOffset.ResolveValue(NULL).UInt(); - } - } else { - // With DWARF 3 and later, if the value is an integer constant, - // this form value is the offset in bytes from the beginning of - // the containing entity. - member_byte_offset = form_value.Unsigned(); - } - break; - - default: - break; - } - } - } - - Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid)); - if (member_type) { - CompilerType member_go_type = member_type->GetFullCompilerType(); - ConstString name_const_str(name); - m_ast.AddFieldToStruct(class_compiler_type, name_const_str, - member_go_type, member_byte_offset); - } - } - ++member_idx; - } break; - - default: - break; - } - } - - return count; -} - -Function *DWARFASTParserGo::ParseFunctionFromDWARF(const SymbolContext &sc, - const DWARFDIE &die) { - DWARFRangeList func_ranges; - const char *name = NULL; - const char *mangled = NULL; - int decl_file = 0; - int decl_line = 0; - int decl_column = 0; - int call_file = 0; - int call_line = 0; - int call_column = 0; - DWARFExpression frame_base(die.GetCU()); - - assert(die.Tag() == DW_TAG_subprogram); - - if (die.Tag() != DW_TAG_subprogram) - return NULL; - - if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, - decl_column, call_file, call_line, call_column, - &frame_base)) { - // Union of all ranges in the function DIE (if the function is - // discontiguous) - AddressRange func_range; - lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0); - lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0); - if (lowest_func_addr != LLDB_INVALID_ADDRESS && - lowest_func_addr <= highest_func_addr) { - ModuleSP module_sp(die.GetModule()); - func_range.GetBaseAddress().ResolveAddressUsingFileSections( - lowest_func_addr, module_sp->GetSectionList()); - if (func_range.GetBaseAddress().IsValid()) - func_range.SetByteSize(highest_func_addr - lowest_func_addr); - } - - if (func_range.GetBaseAddress().IsValid()) { - Mangled func_name; - func_name.SetValue(ConstString(name), false); - - FunctionSP func_sp; - std::unique_ptr decl_ap; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column)); - - SymbolFileDWARF *dwarf = die.GetDWARF(); - // Supply the type _only_ if it has already been parsed - Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE()); - - assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); - - if (dwarf->FixupAddress(func_range.GetBaseAddress())) { - const user_id_t func_user_id = die.GetID(); - func_sp.reset(new Function(sc.comp_unit, - func_user_id, // UserID is the DIE offset - func_user_id, func_name, func_type, - func_range)); // first address range - - if (func_sp.get() != NULL) { - if (frame_base.IsValid()) - func_sp->GetFrameBaseExpression() = frame_base; - sc.comp_unit->AddFunction(func_sp); - return func_sp.get(); - } - } - } - } - return NULL; -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h deleted file mode 100644 index 2a7c3871a309..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserGo.h +++ /dev/null @@ -1,84 +0,0 @@ -//===-- DWARFASTParserGo.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef SymbolFileDWARF_DWARFASTParserGo_h_ -#define SymbolFileDWARF_DWARFASTParserGo_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" - -// Project includes -#include "DWARFASTParser.h" -#include "DWARFDIE.h" -#include "DWARFDefines.h" -#include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/GoASTContext.h" - -class DWARFDebugInfoEntry; -class DWARFDIECollection; - -class DWARFASTParserGo : public DWARFASTParser { -public: - DWARFASTParserGo(lldb_private::GoASTContext &ast); - - ~DWARFASTParserGo() override; - - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; - - lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die) override; - - bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &go_type) override; - - lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDeclContext(); - } - - lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDeclContext(); - } - - lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDecl(); - } - - std::vector GetDIEForDeclContext( - lldb_private::CompilerDeclContext decl_context) override { - return std::vector(); - } - -private: - size_t ParseChildParameters( - const lldb_private::SymbolContext &sc, const DWARFDIE &parent_die, - bool &is_variadic, - std::vector &function_param_types); - void ParseChildArrayInfo(const lldb_private::SymbolContext &sc, - const DWARFDIE &parent_die, int64_t &first_index, - std::vector &element_orders, - uint32_t &byte_stride, uint32_t &bit_stride); - - size_t ParseChildMembers(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, - lldb_private::CompilerType &class_compiler_type); - - lldb_private::GoASTContext &m_ast; -}; - -#endif // SymbolFileDWARF_DWARFASTParserGo_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp deleted file mode 100644 index 476394487985..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.cpp +++ /dev/null @@ -1,510 +0,0 @@ -//===-- DWARFASTParserJava.cpp ----------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "DWARFASTParserJava.h" -#include "DWARFAttribute.h" -#include "DWARFUnit.h" -#include "DWARFDebugInfoEntry.h" -#include "DWARFDebugInfoEntry.h" -#include "DWARFDeclContext.h" -#include "SymbolFileDWARF.h" - -#include "lldb/Core/Module.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/SymbolContextScope.h" -#include "lldb/Symbol/TypeList.h" - -using namespace lldb; -using namespace lldb_private; - -DWARFASTParserJava::DWARFASTParserJava(JavaASTContext &ast) : m_ast(ast) {} - -DWARFASTParserJava::~DWARFASTParserJava() {} - -TypeSP DWARFASTParserJava::ParseBaseTypeFromDIE(const DWARFDIE &die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - ConstString type_name; - uint64_t byte_size = 0; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name.SetCString(form_value.AsCString()); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_encoding: - break; - default: - assert(false && "Unsupported attribute for DW_TAG_base_type"); - } - } - } - - Declaration decl; - CompilerType compiler_type = m_ast.CreateBaseType(type_name); - return std::make_shared(die.GetID(), dwarf, type_name, byte_size, - nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, - decl, compiler_type, Type::eResolveStateFull); -} - -TypeSP DWARFASTParserJava::ParseArrayTypeFromDIE(const DWARFDIE &die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - ConstString linkage_name; - DWARFFormValue type_attr_value; - lldb::addr_t data_offset = LLDB_INVALID_ADDRESS; - DWARFExpression length_expression(die.GetCU()); - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_linkage_name: - linkage_name.SetCString(form_value.AsCString()); - break; - case DW_AT_type: - type_attr_value = form_value; - break; - case DW_AT_data_member_location: - data_offset = form_value.Unsigned(); - break; - case DW_AT_declaration: - break; - default: - assert(false && "Unsupported attribute for DW_TAG_array_type"); - } - } - } - - for (DWARFDIE child_die = die.GetFirstChild(); child_die.IsValid(); - child_die = child_die.GetSibling()) { - if (child_die.Tag() == DW_TAG_subrange_type) { - DWARFAttributes attributes; - const size_t num_attributes = child_die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_count: - if (form_value.BlockData()) - length_expression.CopyOpcodeData( - form_value.BlockData(), form_value.Unsigned(), - child_die.GetCU()->GetByteOrder(), - child_die.GetCU()->GetAddressByteSize()); - break; - default: - assert(false && "Unsupported attribute for DW_TAG_subrange_type"); - } - } - } - } else { - assert(false && "Unsupported child for DW_TAG_array_type"); - } - } - - DIERef type_die_ref(type_attr_value); - Type *element_type = dwarf->ResolveTypeUID(type_die_ref); - if (!element_type) - return nullptr; - - CompilerType element_compiler_type = element_type->GetForwardCompilerType(); - CompilerType array_compiler_type = m_ast.CreateArrayType( - linkage_name, element_compiler_type, length_expression, data_offset); - - Declaration decl; - TypeSP type_sp(new Type(die.GetID(), dwarf, array_compiler_type.GetTypeName(), - -1, nullptr, type_die_ref.GetUID(dwarf), - Type::eEncodingIsUID, &decl, array_compiler_type, - Type::eResolveStateFull)); - type_sp->SetEncodingType(element_type); - return type_sp; -} - -TypeSP DWARFASTParserJava::ParseReferenceTypeFromDIE(const DWARFDIE &die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - Declaration decl; - DWARFFormValue type_attr_value; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_type: - type_attr_value = form_value; - break; - default: - assert(false && "Unsupported attribute for DW_TAG_array_type"); - } - } - } - - DIERef type_die_ref(type_attr_value); - Type *pointee_type = dwarf->ResolveTypeUID(type_die_ref); - if (!pointee_type) - return nullptr; - - CompilerType pointee_compiler_type = pointee_type->GetForwardCompilerType(); - CompilerType reference_compiler_type = - m_ast.CreateReferenceType(pointee_compiler_type); - TypeSP type_sp( - new Type(die.GetID(), dwarf, reference_compiler_type.GetTypeName(), -1, - nullptr, type_die_ref.GetUID(dwarf), Type::eEncodingIsUID, &decl, - reference_compiler_type, Type::eResolveStateFull)); - type_sp->SetEncodingType(pointee_type); - return type_sp; -} - -lldb::TypeSP DWARFASTParserJava::ParseClassTypeFromDIE(const DWARFDIE &die, - bool &is_new_type) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - Declaration decl; - ConstString name; - ConstString linkage_name; - bool is_forward_declaration = false; - uint32_t byte_size = 0; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - name.SetCString(form_value.AsCString()); - break; - case DW_AT_declaration: - is_forward_declaration = form_value.Boolean(); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_linkage_name: - linkage_name.SetCString(form_value.AsCString()); - break; - default: - assert(false && "Unsupported attribute for DW_TAG_class_type"); - } - } - } - - UniqueDWARFASTType unique_ast_entry; - if (name) { - std::string qualified_name; - if (die.GetQualifiedName(qualified_name)) { - name.SetCString(qualified_name.c_str()); - if (dwarf->GetUniqueDWARFASTTypeMap().Find(name, die, Declaration(), -1, - unique_ast_entry)) { - if (unique_ast_entry.m_type_sp) { - dwarf->GetDIEToType()[die.GetDIE()] = - unique_ast_entry.m_type_sp.get(); - is_new_type = false; - return unique_ast_entry.m_type_sp; - } - } - } - } - - if (is_forward_declaration) { - DWARFDeclContext die_decl_ctx; - die.GetDWARFDeclContext(die_decl_ctx); - - TypeSP type_sp = dwarf->FindDefinitionTypeForDWARFDeclContext(die_decl_ctx); - if (type_sp) { - // We found a real definition for this type elsewhere so lets use it - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); - is_new_type = false; - return type_sp; - } - } - - CompilerType compiler_type( - &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE())); - if (!compiler_type) - compiler_type = m_ast.CreateObjectType(name, linkage_name, byte_size); - - is_new_type = true; - TypeSP type_sp(new Type(die.GetID(), dwarf, name, - -1, // byte size isn't specified - nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, - &decl, compiler_type, Type::eResolveStateForward)); - - // Add our type to the unique type map - unique_ast_entry.m_type_sp = type_sp; - unique_ast_entry.m_die = die; - unique_ast_entry.m_declaration = decl; - unique_ast_entry.m_byte_size = -1; - dwarf->GetUniqueDWARFASTTypeMap().Insert(name, unique_ast_entry); - - if (!is_forward_declaration) { - // Leave this as a forward declaration until we need to know the details of - // the type - dwarf->GetForwardDeclDieToClangType()[die.GetDIE()] = - compiler_type.GetOpaqueQualType(); - dwarf->GetForwardDeclClangTypeToDie()[compiler_type.GetOpaqueQualType()] = - die.GetDIERef(); - } - return type_sp; -} - -lldb::TypeSP DWARFASTParserJava::ParseTypeFromDWARF( - const lldb_private::SymbolContext &sc, const DWARFDIE &die, - lldb_private::Log *log, bool *type_is_new_ptr) { - if (type_is_new_ptr) - *type_is_new_ptr = false; - - if (!die) - return nullptr; - - SymbolFileDWARF *dwarf = die.GetDWARF(); - - Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE()); - if (type_ptr == DIE_IS_BEING_PARSED) - return nullptr; - if (type_ptr != nullptr) - return type_ptr->shared_from_this(); - - TypeSP type_sp; - if (type_is_new_ptr) - *type_is_new_ptr = true; - - switch (die.Tag()) { - case DW_TAG_base_type: { - type_sp = ParseBaseTypeFromDIE(die); - break; - } - case DW_TAG_array_type: { - type_sp = ParseArrayTypeFromDIE(die); - break; - } - case DW_TAG_class_type: { - bool is_new_type = false; - type_sp = ParseClassTypeFromDIE(die, is_new_type); - if (!is_new_type) - return type_sp; - break; - } - case DW_TAG_reference_type: { - type_sp = ParseReferenceTypeFromDIE(die); - break; - } - } - - if (!type_sp) - return nullptr; - - DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); - - SymbolContextScope *symbol_context_scope = nullptr; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { - symbol_context_scope = sc.comp_unit; - } else if (sc.function != nullptr && sc_parent_die) { - symbol_context_scope = - sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); - if (symbol_context_scope == nullptr) - symbol_context_scope = sc.function; - } - - if (symbol_context_scope != nullptr) - type_sp->SetSymbolContextScope(symbol_context_scope); - - dwarf->GetTypeList()->Insert(type_sp); - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - - return type_sp; -} - -lldb_private::Function *DWARFASTParserJava::ParseFunctionFromDWARF( - const lldb_private::SymbolContext &sc, const DWARFDIE &die) { - assert(die.Tag() == DW_TAG_subprogram); - - const char *name = nullptr; - const char *mangled = nullptr; - int decl_file = 0; - int decl_line = 0; - int decl_column = 0; - int call_file = 0; - int call_line = 0; - int call_column = 0; - DWARFRangeList func_ranges; - DWARFExpression frame_base(die.GetCU()); - - if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, - decl_column, call_file, call_line, call_column, - &frame_base)) { - // Union of all ranges in the function DIE (if the function is - // discontiguous) - AddressRange func_range; - lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0); - lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0); - if (lowest_func_addr != LLDB_INVALID_ADDRESS && - lowest_func_addr <= highest_func_addr) { - ModuleSP module_sp(die.GetModule()); - func_range.GetBaseAddress().ResolveAddressUsingFileSections( - lowest_func_addr, module_sp->GetSectionList()); - if (func_range.GetBaseAddress().IsValid()) - func_range.SetByteSize(highest_func_addr - lowest_func_addr); - } - - if (func_range.GetBaseAddress().IsValid()) { - std::unique_ptr decl_ap; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column)); - - if (die.GetDWARF()->FixupAddress(func_range.GetBaseAddress())) { - FunctionSP func_sp(new Function(sc.comp_unit, die.GetID(), die.GetID(), - Mangled(ConstString(name), false), - nullptr, // No function types in java - func_range)); - if (frame_base.IsValid()) - func_sp->GetFrameBaseExpression() = frame_base; - sc.comp_unit->AddFunction(func_sp); - - return func_sp.get(); - } - } - } - return nullptr; -} - -bool DWARFASTParserJava::CompleteTypeFromDWARF( - const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &java_type) { - switch (die.Tag()) { - case DW_TAG_class_type: { - if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 0) { - if (die.HasChildren()) - ParseChildMembers(die, java_type); - m_ast.CompleteObjectType(java_type); - return java_type.IsValid(); - } - } break; - default: - assert(false && "Not a forward java type declaration!"); - break; - } - return false; -} - -void DWARFASTParserJava::ParseChildMembers(const DWARFDIE &parent_die, - CompilerType &compiler_type) { - DWARFUnit *dwarf_cu = parent_die.GetCU(); - for (DWARFDIE die = parent_die.GetFirstChild(); die.IsValid(); - die = die.GetSibling()) { - switch (die.Tag()) { - case DW_TAG_member: { - const char *name = nullptr; - DWARFFormValue encoding_uid; - uint32_t member_byte_offset = UINT32_MAX; - DWARFExpression member_location_expression(dwarf_cu); - - DWARFAttributes attributes; - size_t num_attributes = die.GetAttributes(attributes); - for (size_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attributes.AttributeAtIndex(i)) { - case DW_AT_name: - name = form_value.AsCString(); - break; - case DW_AT_type: - encoding_uid = form_value; - break; - case DW_AT_data_member_location: - if (form_value.BlockData()) - member_location_expression.CopyOpcodeData( - form_value.BlockData(), form_value.Unsigned(), - dwarf_cu->GetByteOrder(), dwarf_cu->GetAddressByteSize()); - else - member_byte_offset = form_value.Unsigned(); - break; - case DW_AT_artificial: - static_cast(form_value.Boolean()); - break; - case DW_AT_accessibility: - // TODO: Handle when needed - break; - default: - assert(false && "Unhandled attribute for DW_TAG_member"); - break; - } - } - } - - if (strcmp(name, ".dynamic_type") == 0) - m_ast.SetDynamicTypeId(compiler_type, member_location_expression); - else { - if (Type *member_type = die.ResolveTypeUID(DIERef(encoding_uid))) - m_ast.AddMemberToObject(compiler_type, ConstString(name), - member_type->GetFullCompilerType(), - member_byte_offset); - } - break; - } - case DW_TAG_inheritance: { - DWARFFormValue encoding_uid; - uint32_t member_byte_offset = UINT32_MAX; - - DWARFAttributes attributes; - size_t num_attributes = die.GetAttributes(attributes); - for (size_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attributes.AttributeAtIndex(i)) { - case DW_AT_type: - encoding_uid = form_value; - break; - case DW_AT_data_member_location: - member_byte_offset = form_value.Unsigned(); - break; - case DW_AT_accessibility: - // In java all base class is public so we can ignore this attribute - break; - default: - assert(false && "Unhandled attribute for DW_TAG_member"); - break; - } - } - } - if (Type *base_type = die.ResolveTypeUID(DIERef(encoding_uid))) - m_ast.AddBaseClassToObject(compiler_type, - base_type->GetFullCompilerType(), - member_byte_offset); - break; - } - default: - break; - } - } -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h deleted file mode 100644 index 01d81833d517..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserJava.h +++ /dev/null @@ -1,81 +0,0 @@ -//===-- DWARFASTParserJava.h ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef SymbolFileDWARF_DWARFASTParserJava_h_ -#define SymbolFileDWARF_DWARFASTParserJava_h_ - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallVector.h" - -// Project includes -#include "DWARFASTParser.h" -#include "DWARFDIE.h" -#include "DWARFDefines.h" -#include "lldb/Core/PluginInterface.h" -#include "lldb/Symbol/JavaASTContext.h" - -class DWARFDebugInfoEntry; -class DWARFDIECollection; - -class DWARFASTParserJava : public DWARFASTParser { -public: - DWARFASTParserJava(lldb_private::JavaASTContext &ast); - ~DWARFASTParserJava() override; - - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; - - lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die) override; - - bool CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &java_type) override; - - lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDeclContext(); - } - - lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDeclContext(); - } - - lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDecl(); - } - - std::vector GetDIEForDeclContext( - lldb_private::CompilerDeclContext decl_context) override { - return std::vector(); - } - - void ParseChildMembers(const DWARFDIE &parent_die, - lldb_private::CompilerType &class_compiler_type); - -private: - lldb_private::JavaASTContext &m_ast; - - lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die); - - lldb::TypeSP ParseArrayTypeFromDIE(const DWARFDIE &die); - - lldb::TypeSP ParseReferenceTypeFromDIE(const DWARFDIE &die); - - lldb::TypeSP ParseClassTypeFromDIE(const DWARFDIE &die, bool &is_new_type); -}; - -#endif // SymbolFileDWARF_DWARFASTParserJava_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp deleted file mode 100644 index 3ef5c2eb8626..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.cpp +++ /dev/null @@ -1,210 +0,0 @@ -//===-- DWARFASTParserOCaml.cpp ---------------------------------*- C++ -*-===// - -#include "DWARFASTParserOCaml.h" - -#include "lldb/Core/Module.h" -#include "lldb/Symbol/CompileUnit.h" -#include "lldb/Symbol/Function.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Symbol/TypeList.h" -#include "lldb/Utility/Log.h" -#include "lldb/Utility/Status.h" - -using namespace lldb; -using namespace lldb_private; - -DWARFASTParserOCaml::DWARFASTParserOCaml(OCamlASTContext &ast) : m_ast(ast) {} - -DWARFASTParserOCaml::~DWARFASTParserOCaml() {} - -TypeSP DWARFASTParserOCaml::ParseBaseTypeFromDIE(const DWARFDIE &die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - dwarf->m_die_to_type[die.GetDIE()] = DIE_IS_BEING_PARSED; - - ConstString type_name; - uint64_t byte_size = 0; - - DWARFAttributes attributes; - const size_t num_attributes = die.GetAttributes(attributes); - for (uint32_t i = 0; i < num_attributes; ++i) { - DWARFFormValue form_value; - dw_attr_t attr = attributes.AttributeAtIndex(i); - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - type_name.SetCString(form_value.AsCString()); - break; - case DW_AT_byte_size: - byte_size = form_value.Unsigned(); - break; - case DW_AT_encoding: - break; - default: - assert(false && "Unsupported attribute for DW_TAG_base_type"); - } - } - } - - Declaration decl; - CompilerType compiler_type = m_ast.CreateBaseType(type_name, byte_size); - return std::make_shared(die.GetID(), dwarf, type_name, byte_size, - nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, - decl, compiler_type, Type::eResolveStateFull); -} - -lldb::TypeSP DWARFASTParserOCaml::ParseTypeFromDWARF(const SymbolContext &sc, - const DWARFDIE &die, - Log *log, - bool *type_is_new_ptr) { - if (type_is_new_ptr) - *type_is_new_ptr = false; - - if (!die) - return nullptr; - - SymbolFileDWARF *dwarf = die.GetDWARF(); - - Type *type_ptr = dwarf->m_die_to_type.lookup(die.GetDIE()); - if (type_ptr == DIE_IS_BEING_PARSED) - return nullptr; - if (type_ptr != nullptr) - return type_ptr->shared_from_this(); - - TypeSP type_sp; - if (type_is_new_ptr) - *type_is_new_ptr = true; - - switch (die.Tag()) { - case DW_TAG_base_type: { - type_sp = ParseBaseTypeFromDIE(die); - break; - } - case DW_TAG_array_type: { - break; - } - case DW_TAG_class_type: { - break; - } - case DW_TAG_reference_type: { - break; - } - } - - if (!type_sp) - return nullptr; - - DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); - dw_tag_t sc_parent_tag = sc_parent_die.Tag(); - - SymbolContextScope *symbol_context_scope = nullptr; - if (sc_parent_tag == DW_TAG_compile_unit || - sc_parent_tag == DW_TAG_partial_unit) { - symbol_context_scope = sc.comp_unit; - } else if (sc.function != nullptr && sc_parent_die) { - symbol_context_scope = - sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID()); - if (symbol_context_scope == nullptr) - symbol_context_scope = sc.function; - } - - if (symbol_context_scope != nullptr) - type_sp->SetSymbolContextScope(symbol_context_scope); - - dwarf->GetTypeList()->Insert(type_sp); - dwarf->m_die_to_type[die.GetDIE()] = type_sp.get(); - - return type_sp; -} - -Function *DWARFASTParserOCaml::ParseFunctionFromDWARF(const SymbolContext &sc, - const DWARFDIE &die) { - DWARFRangeList func_ranges; - const char *name = NULL; - const char *mangled = NULL; - int decl_file = 0; - int decl_line = 0; - int decl_column = 0; - int call_file = 0; - int call_line = 0; - int call_column = 0; - DWARFExpression frame_base(die.GetCU()); - - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE)); - - if (die) { - SymbolFileDWARF *dwarf = die.GetDWARF(); - if (log) { - dwarf->GetObjectFile()->GetModule()->LogMessage( - log, "DWARFASTParserOCaml::ParseFunctionFromDWARF (die = 0x%8.8x) %s " - "name = '%s')", - die.GetOffset(), DW_TAG_value_to_name(die.Tag()), die.GetName()); - } - } - - assert(die.Tag() == DW_TAG_subprogram); - - if (die.Tag() != DW_TAG_subprogram) - return NULL; - - if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line, - decl_column, call_file, call_line, call_column, - &frame_base)) { - AddressRange func_range; - lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0); - lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0); - if (lowest_func_addr != LLDB_INVALID_ADDRESS && - lowest_func_addr <= highest_func_addr) { - ModuleSP module_sp(die.GetModule()); - func_range.GetBaseAddress().ResolveAddressUsingFileSections( - lowest_func_addr, module_sp->GetSectionList()); - if (func_range.GetBaseAddress().IsValid()) - func_range.SetByteSize(highest_func_addr - lowest_func_addr); - } - - if (func_range.GetBaseAddress().IsValid()) { - Mangled func_name; - - func_name.SetValue(ConstString(name), true); - - FunctionSP func_sp; - std::unique_ptr decl_ap; - if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), - decl_line, decl_column)); - - SymbolFileDWARF *dwarf = die.GetDWARF(); - Type *func_type = dwarf->m_die_to_type.lookup(die.GetDIE()); - - assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED); - - if (dwarf->FixupAddress(func_range.GetBaseAddress())) { - const user_id_t func_user_id = die.GetID(); - func_sp.reset(new Function(sc.comp_unit, - func_user_id, // UserID is the DIE offset - func_user_id, func_name, func_type, - func_range)); // first address range - - if (func_sp.get() != NULL) { - if (frame_base.IsValid()) - func_sp->GetFrameBaseExpression() = frame_base; - sc.comp_unit->AddFunction(func_sp); - return func_sp.get(); - } - } - } - } - - return NULL; -} - -lldb_private::CompilerDeclContext -DWARFASTParserOCaml::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) { - return CompilerDeclContext(); -} - -lldb_private::CompilerDeclContext -DWARFASTParserOCaml::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) { - return CompilerDeclContext(); -} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h deleted file mode 100644 index 09cb5e14934f..000000000000 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h +++ /dev/null @@ -1,59 +0,0 @@ -//===-- DWARFASTParserOCaml.h -----------------------------------*- C++ -*-===// - -#ifndef SymbolFileDWARF_DWARFASTParserOCaml_h_ -#define SymbolFileDWARF_DWARFASTParserOCaml_h_ - -#include "DWARFASTParser.h" -#include "DWARFDIE.h" -#include "DWARFDebugInfo.h" -#include "DWARFDefines.h" -#include "SymbolFileDWARF.h" - -#include "lldb/Symbol/OCamlASTContext.h" - -class DWARFDebugInfoEntry; -class DWARFDIECollection; - -class DWARFASTParserOCaml : public DWARFASTParser { -public: - DWARFASTParserOCaml(lldb_private::OCamlASTContext &ast); - - virtual ~DWARFASTParserOCaml(); - - lldb::TypeSP ParseBaseTypeFromDIE(const DWARFDIE &die); - - lldb::TypeSP ParseTypeFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die, lldb_private::Log *log, - bool *type_is_new_ptr) override; - - lldb_private::Function * - ParseFunctionFromDWARF(const lldb_private::SymbolContext &sc, - const DWARFDIE &die) override; - - bool - CompleteTypeFromDWARF(const DWARFDIE &die, lldb_private::Type *type, - lldb_private::CompilerType &compiler_type) override { - return false; - } - - lldb_private::CompilerDecl - GetDeclForUIDFromDWARF(const DWARFDIE &die) override { - return lldb_private::CompilerDecl(); - } - - lldb_private::CompilerDeclContext - GetDeclContextForUIDFromDWARF(const DWARFDIE &die) override; - - lldb_private::CompilerDeclContext - GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) override; - - std::vector GetDIEForDeclContext( - lldb_private::CompilerDeclContext decl_context) override { - return {}; - } - -protected: - lldb_private::OCamlASTContext &m_ast; -}; - -#endif // SymbolFileDWARF_DWARFASTParserOCaml_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp index a765be0b46d0..d78b9ab10f5a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -41,9 +41,13 @@ bool DWARFAbbreviationDeclaration::Extract(const DWARFDataExtractor &data, while (data.ValidOffset(*offset_ptr)) { dw_attr_t attr = data.GetULEB128(offset_ptr); dw_form_t form = data.GetULEB128(offset_ptr); + DWARFFormValue::ValueType val; + + if (form == DW_FORM_implicit_const) + val.value.sval = data.GetULEB128(offset_ptr); if (attr && form) - m_attributes.push_back(DWARFAttribute(attr, form)); + m_attributes.push_back(DWARFAttribute(attr, form, val)); else break; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h index b2296c455d6a..afce52558f45 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h @@ -35,20 +35,11 @@ public: dw_form_t GetFormByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0; } - bool GetAttrAndFormByIndex(uint32_t idx, dw_attr_t &attr, - dw_form_t &form) const { - if (m_attributes.size() > idx) { - m_attributes[idx].get(attr, form); - return true; - } - attr = form = 0; - return false; - } - // idx is assumed to be valid when calling GetAttrAndFormByIndexUnchecked() - void GetAttrAndFormByIndexUnchecked(uint32_t idx, dw_attr_t &attr, - dw_form_t &form) const { - m_attributes[idx].get(attr, form); + // idx is assumed to be valid when calling GetAttrAndFormByIndex() + void GetAttrAndFormValueByIndex(uint32_t idx, dw_attr_t &attr, + DWARFFormValue &form_value) const { + m_attributes[idx].get(attr, form_value.FormRef(), form_value.ValueRef()); } dw_form_t GetFormByIndexUnchecked(uint32_t idx) const { return m_attributes[idx].get_form(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp index 2586d1f18530..dd830eb7b9dd 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -26,10 +26,10 @@ uint32_t DWARFAttributes::FindAttributeIndex(dw_attr_t attr) const { return UINT32_MAX; } -void DWARFAttributes::Append(const DWARFUnit *cu, - dw_offset_t attr_die_offset, dw_attr_t attr, - dw_form_t form) { - AttributeValue attr_value = {cu, attr_die_offset, {attr, form}}; +void DWARFAttributes::Append(const DWARFUnit *cu, dw_offset_t attr_die_offset, + dw_attr_t attr, dw_form_t form) { + AttributeValue attr_value = { + cu, attr_die_offset, {attr, form, DWARFFormValue::ValueType()}}; m_infos.push_back(attr_value); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h index db4324cf7725..2399861d7fc3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h @@ -11,15 +11,17 @@ #define SymbolFileDWARF_DWARFAttribute_h_ #include "DWARFDefines.h" +#include "DWARFFormValue.h" #include "llvm/ADT/SmallVector.h" #include class DWARFUnit; -class DWARFFormValue; class DWARFAttribute { public: - DWARFAttribute(dw_attr_t attr, dw_form_t form) : m_attr(attr), m_form(form) {} + DWARFAttribute(dw_attr_t attr, dw_form_t form, + DWARFFormValue::ValueType value) + : m_attr(attr), m_form(form), m_value(value) {} void set(dw_attr_t attr, dw_form_t form) { m_attr = attr; @@ -29,9 +31,11 @@ public: void set_form(dw_form_t form) { m_form = form; } dw_attr_t get_attr() const { return m_attr; } dw_form_t get_form() const { return m_form; } - void get(dw_attr_t &attr, dw_form_t &form) const { + void get(dw_attr_t &attr, dw_form_t &form, + DWARFFormValue::ValueType &val) const { attr = m_attr; form = m_form; + val = m_value; } bool operator==(const DWARFAttribute &rhs) const { return m_attr == rhs.m_attr && m_form == rhs.m_form; @@ -43,6 +47,7 @@ public: protected: dw_attr_t m_attr; dw_form_t m_form; + DWARFFormValue::ValueType m_value; }; class DWARFAttributes { diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 8541f1cfe1f6..b9a7231286e3 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -34,8 +34,18 @@ DWARFUnitSP DWARFCompileUnit::Extract(SymbolFileDWARF *dwarf2Data, cu_sp->m_length = debug_info.GetDWARFInitialLength(offset_ptr); cu_sp->m_is_dwarf64 = debug_info.IsDWARF64(); cu_sp->m_version = debug_info.GetU16(offset_ptr); - abbr_offset = debug_info.GetDWARFOffset(offset_ptr); - cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + + if (cu_sp->m_version == 5) { + cu_sp->m_unit_type = debug_info.GetU8(offset_ptr); + cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + + if (cu_sp->m_unit_type == llvm::dwarf::DW_UT_skeleton) + cu_sp->m_dwo_id = debug_info.GetU64(offset_ptr); + } else { + abbr_offset = debug_info.GetDWARFOffset(offset_ptr); + cu_sp->m_addr_size = debug_info.GetU8(offset_ptr); + } bool length_OK = debug_info.ValidOffset(cu_sp->GetNextCompileUnitOffset() - 1); @@ -65,6 +75,23 @@ void DWARFCompileUnit::Dump(Stream *s) const { GetNextCompileUnitOffset()); } +uint32_t DWARFCompileUnit::GetHeaderByteSize() const { + if (m_version < 5) + return m_is_dwarf64 ? 23 : 11; + + switch (m_unit_type) { + case llvm::dwarf::DW_UT_compile: + case llvm::dwarf::DW_UT_partial: + return 12; + case llvm::dwarf::DW_UT_skeleton: + case llvm::dwarf::DW_UT_split_compile: + return 20; + case llvm::dwarf::DW_UT_type: + case llvm::dwarf::DW_UT_split_type: + return 24; + } + llvm_unreachable("invalid UnitType."); +} const lldb_private::DWARFDataExtractor &DWARFCompileUnit::GetData() const { return m_dwarf->get_debug_info_data(); diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index d20f31505ed4..b92a155e0335 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -35,9 +35,7 @@ public: /// @return /// Byte size of the compile unit header //------------------------------------------------------------------ - uint32_t GetHeaderByteSize() const override { - return m_is_dwarf64 ? 23 : 11; - } + uint32_t GetHeaderByteSize() const override; private: DWARFCompileUnit(SymbolFileDWARF *dwarf2Data); diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index d9754e911017..22b70b2d6852 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -166,13 +166,13 @@ void DWARFDIE::GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const { } } -void DWARFDIE::GetDWOContext(std::vector &context) const { +void DWARFDIE::GetDeclContext(std::vector &context) const { const dw_tag_t tag = Tag(); if (tag == DW_TAG_compile_unit || tag == DW_TAG_partial_unit) return; DWARFDIE parent = GetParent(); if (parent) - parent.GetDWOContext(context); + parent.GetDeclContext(context); switch (tag) { case DW_TAG_module: context.push_back( diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h index ecbf4912634e..b0d06a886ac1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h @@ -90,7 +90,10 @@ public: void GetDWARFDeclContext(DWARFDeclContext &dwarf_decl_ctx) const; - void GetDWOContext(std::vector &context) const; + /// Return this DIE's decl context as it is needed to look up types + /// in Clang's -gmodules debug info format. + void + GetDeclContext(std::vector &context) const; //---------------------------------------------------------------------- // Getting attribute values from the DIE. diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h index ce0bfb3931d5..1f342035f135 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDataExtractor.h @@ -10,7 +10,6 @@ #ifndef liblldb_DWARFDataExtractor_h_ #define liblldb_DWARFDataExtractor_h_ -// Other libraries and framework includes. #include "lldb/Core/dwarf.h" #include "lldb/Utility/DataExtractor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h index 6524cb3ce483..e7a8635f0532 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAranges.h @@ -19,7 +19,7 @@ class SymbolFileDWARF; class DWARFDebugAranges { protected: - typedef lldb_private::RangeDataArray + typedef lldb_private::RangeDataVector RangeToDIE; public: diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index d32aef6e162c..7531aeac709a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -40,9 +40,8 @@ bool DWARFDebugInfoEntry::FastExtract( m_offset = *offset_ptr; m_parent_idx = 0; m_sibling_idx = 0; - m_empty_children = false; const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr); - assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); + lldbassert(abbr_idx <= UINT16_MAX); m_abbr_idx = abbr_idx; // assert (fixed_form_sizes); // For best performance this should be @@ -119,21 +118,33 @@ bool DWARFDebugInfoEntry::FastExtract( break; // 1 byte values + case DW_FORM_addrx1: case DW_FORM_data1: case DW_FORM_flag: case DW_FORM_ref1: + case DW_FORM_strx1: form_size = 1; break; // 2 byte values + case DW_FORM_addrx2: case DW_FORM_data2: case DW_FORM_ref2: + case DW_FORM_strx2: form_size = 2; break; + // 3 byte values + case DW_FORM_addrx3: + case DW_FORM_strx3: + form_size = 3; + break; + // 4 byte values + case DW_FORM_addrx4: case DW_FORM_data4: case DW_FORM_ref4: + case DW_FORM_strx4: form_size = 4; break; @@ -145,11 +156,14 @@ bool DWARFDebugInfoEntry::FastExtract( break; // signed or unsigned LEB 128 values + case DW_FORM_addrx: + case DW_FORM_rnglistx: case DW_FORM_sdata: case DW_FORM_udata: case DW_FORM_ref_udata: case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: + case DW_FORM_strx: debug_info_data.Skip_LEB128(&offset); break; @@ -166,6 +180,10 @@ bool DWARFDebugInfoEntry::FastExtract( debug_info_data.GetU32(&offset); break; + case DW_FORM_implicit_const: + form_size = 0; + break; + default: *offset_ptr = m_offset; return false; @@ -208,7 +226,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, m_offset = offset; const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset); - assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE)); + lldbassert(abbr_idx <= UINT16_MAX); m_abbr_idx = abbr_idx; if (abbr_idx) { const DWARFAbbreviationDeclaration *abbrevDecl = @@ -225,15 +243,14 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, // Skip all data in the .debug_info for the attributes const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i = 0; i < numAttributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); + for (uint32_t i = 0; i < numAttributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); + dw_form_t form = form_value.Form(); if (isCompileUnitTag && ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) { - DWARFFormValue form_value(cu, form); if (form_value.ExtractValue(debug_info_data, &offset)) { if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc) const_cast(cu)->SetBaseAddress( @@ -279,6 +296,7 @@ bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data, // 0 sized form case DW_FORM_flag_present: + case DW_FORM_implicit_const: form_size = 0; break; @@ -370,6 +388,13 @@ void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data, Dump(dwarf2Data, cu, s, recurse_depth); } +static dw_offset_t GetRangesOffset(const DWARFDebugRangesBase *debug_ranges, + DWARFFormValue &form_value) { + if (form_value.Form() == DW_FORM_rnglistx) + return debug_ranges->GetOffset(form_value.Unsigned()); + return form_value.Unsigned(); +} + //---------------------------------------------------------------------- // GetDIENamesAndRanges // @@ -409,14 +434,13 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( return false; const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; bool do_offset = false; - for (i = 0; i < numAttributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); - DWARFFormValue form_value(cu, form); + for (uint32_t i = 0; i < numAttributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); + if (form_value.ExtractValue(debug_info_data, &offset)) { switch (attr) { case DW_AT_low_pc: @@ -446,20 +470,15 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( break; case DW_AT_ranges: { - const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - if (debug_ranges) { - debug_ranges->FindRanges(cu->GetRangesBase(), form_value.Unsigned(), ranges); - // All DW_AT_ranges are relative to the base address of the compile - // unit. We add the compile unit base address to make sure all the - // addresses are properly fixed up. - ranges.Slide(cu->GetBaseAddress()); - } else { + const DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges(); + if (debug_ranges) + debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), ranges); + else cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError( "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64 ") attribute yet DWARF has no .debug_ranges, please file a bug " "and attach the file at the start of this error message", m_offset, form_value.Unsigned()); - } } break; case DW_AT_name: @@ -521,7 +540,7 @@ bool DWARFDebugInfoEntry::GetDIENamesAndRanges( block_length); } else { const DWARFDataExtractor &debug_loc_data = - dwarf2Data->get_debug_loc_data(); + dwarf2Data->DebugLocData(); const dw_offset_t debug_loc_offset = form_value.Unsigned(); size_t loc_list_length = DWARFExpression::LocationListSize( @@ -606,14 +625,13 @@ void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data, // Dump all data in the .debug_info for the attributes const uint32_t numAttributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i = 0; i < numAttributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); + for (uint32_t i = 0; i < numAttributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr, - form); + form_value); } const DWARFDebugInfoEntry *child = GetFirstChild(); @@ -663,23 +681,21 @@ void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data, void DWARFDebugInfoEntry::DumpAttribute( SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, - Stream &s, dw_attr_t attr, dw_form_t form) { + Stream &s, dw_attr_t attr, DWARFFormValue &form_value) { bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm); s.Printf(" "); s.Indent(DW_AT_value_to_name(attr)); if (show_form) { - s.Printf("[%s", DW_FORM_value_to_name(form)); + s.Printf("[%s", DW_FORM_value_to_name(form_value.Form())); } - DWARFFormValue form_value(cu, form); - if (!form_value.ExtractValue(debug_info_data, offset_ptr)) return; if (show_form) { - if (form == DW_FORM_indirect) { + if (form_value.Form() == DW_FORM_indirect) { s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form())); } @@ -719,7 +735,7 @@ void DWARFDebugInfoEntry::DumpAttribute( uint64_t debug_loc_offset = form_value.Unsigned(); if (dwarf2Data) { DWARFExpression::PrintDWARFLocationList( - s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset); + s, cu, dwarf2Data->DebugLocData(), debug_loc_offset); } } } break; @@ -740,11 +756,13 @@ void DWARFDebugInfoEntry::DumpAttribute( } break; case DW_AT_ranges: { - lldb::offset_t ranges_offset = form_value.Unsigned(); + if (!dwarf2Data) + break; + lldb::offset_t ranges_offset = + GetRangesOffset(dwarf2Data->DebugRanges(), form_value); dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0; - if (dwarf2Data) - DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), - &ranges_offset, base_addr); + DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(), + &ranges_offset, base_addr); } break; default: @@ -786,11 +804,11 @@ size_t DWARFDebugInfoEntry::GetAttributes( cu->GetAddressByteSize(), cu->IsDWARF64()); const uint32_t num_attributes = abbrevDecl->NumAttributes(); - uint32_t i; - dw_attr_t attr; - dw_form_t form; - for (i = 0; i < num_attributes; ++i) { - abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form); + for (uint32_t i = 0; i < num_attributes; ++i) { + DWARFFormValue form_value(cu); + dw_attr_t attr; + abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value); + const dw_form_t form = form_value.Form(); // If we are tracking down DW_AT_specification or DW_AT_abstract_origin // attributes, the depth will be non-zero. We need to omit certain @@ -811,7 +829,6 @@ size_t DWARFDebugInfoEntry::GetAttributes( } if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) { - DWARFFormValue form_value(cu, form); if (form_value.ExtractValue(debug_info_data, &offset)) { dw_offset_t die_offset = form_value.Reference(); DWARFDIE spec_die = @@ -1055,14 +1072,11 @@ size_t DWARFDebugInfoEntry::GetAttributeAddressRanges( bool check_specification_or_abstract_origin) const { ranges.Clear(); - dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned( - dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET, - check_specification_or_abstract_origin); - if (debug_ranges_offset != DW_INVALID_OFFSET) { - DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - - debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges); - ranges.Slide(cu->GetBaseAddress()); + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) { + if (DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges()) + debug_ranges->FindRanges(cu, GetRangesOffset(debug_ranges, form_value), + ranges); } else if (check_hi_lo_pc) { dw_addr_t lo_pc = LLDB_INVALID_ADDRESS; dw_addr_t hi_pc = LLDB_INVALID_ADDRESS; @@ -1713,16 +1727,13 @@ bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, ((function_die != NULL) || (block_die != NULL)); } } else { - dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned( - dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET); - if (debug_ranges_offset != DW_INVALID_OFFSET) { + DWARFFormValue form_value; + if (GetAttributeValue(dwarf2Data, cu, DW_AT_ranges, form_value)) { DWARFRangeList ranges; - DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges(); - debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges); - // All DW_AT_ranges are relative to the base address of the compile - // unit. We add the compile unit base address to make sure all the - // addresses are properly fixed up. - ranges.Slide(cu->GetBaseAddress()); + DWARFDebugRangesBase *debug_ranges = dwarf2Data->DebugRanges(); + debug_ranges->FindRanges( + cu, GetRangesOffset(debug_ranges, form_value), ranges); + if (ranges.FindEntryThatContains(address)) { found_address = true; // puts("***MATCH***"); @@ -1829,7 +1840,6 @@ void DWARFDebugInfoEntry::DumpDIECollection( bool DWARFDebugInfoEntry::operator==(const DWARFDebugInfoEntry &rhs) const { return m_offset == rhs.m_offset && m_parent_idx == rhs.m_parent_idx && m_sibling_idx == rhs.m_sibling_idx && - m_empty_children == rhs.m_empty_children && m_abbr_idx == rhs.m_abbr_idx && m_has_children == rhs.m_has_children && m_tag == rhs.m_tag; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h index 97cb3046eb3e..ec19fc814fba 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h @@ -43,7 +43,6 @@ typedef UInt32ToDIEMMap::const_iterator UInt32ToDIEMMapConstIter; class DWARFDeclContext; #define DIE_SIBLING_IDX_BITSIZE 31 -#define DIE_ABBR_IDX_BITSIZE 15 class DWARFDebugInfoEntry { public: @@ -57,8 +56,7 @@ public: DWARFDebugInfoEntry() : m_offset(DW_INVALID_OFFSET), m_parent_idx(0), m_sibling_idx(0), - m_empty_children(false), m_abbr_idx(0), m_has_children(false), - m_tag(0) {} + m_has_children(false), m_abbr_idx(0), m_tag(0) {} explicit operator bool() const { return m_offset != DW_INVALID_OFFSET; } bool operator==(const DWARFDebugInfoEntry &rhs) const; @@ -178,7 +176,7 @@ public: DumpAttribute(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu, const lldb_private::DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr, lldb_private::Stream &s, - dw_attr_t attr, dw_form_t form); + dw_attr_t attr, DWARFFormValue &form_value); // This one dumps the comp unit name, objfile name and die offset for this die // so the stream S. void DumpLocation(SymbolFileDWARF *dwarf2Data, DWARFUnit *cu, @@ -227,10 +225,10 @@ public: // we don't need to store our child pointer, if we have a child it will // be the next entry in the list... DWARFDebugInfoEntry *GetFirstChild() { - return (HasChildren() && !m_empty_children) ? this + 1 : NULL; + return HasChildren() ? this + 1 : NULL; } const DWARFDebugInfoEntry *GetFirstChild() const { - return (HasChildren() && !m_empty_children) ? this + 1 : NULL; + return HasChildren() ? this + 1 : NULL; } void GetDeclContextDIEs(DWARFUnit *cu, @@ -271,10 +269,6 @@ public: void SetParentIndex(uint32_t idx) { m_parent_idx = idx; } - bool GetEmptyChildren() const { return m_empty_children; } - - void SetEmptyChildren(bool b) { m_empty_children = b; } - static void DumpDIECollection(lldb_private::Stream &strm, DWARFDebugInfoEntry::collection &die_collection); @@ -285,13 +279,13 @@ protected: uint32_t m_parent_idx; // How many to subtract from "this" to get the parent. // If zero this die has no parent uint32_t m_sibling_idx : 31, // How many to add to "this" to get the sibling. - m_empty_children : 1; // If a DIE says it had children, yet it just - // contained a NULL tag, this will be set. - uint32_t m_abbr_idx : DIE_ABBR_IDX_BITSIZE, - m_has_children : 1, // Set to 1 if this DIE has children - m_tag : 16; // A copy of the DW_TAG value so we don't - // have to go through the compile unit - // abbrev table + // If it is zero, then the DIE doesn't have children, or the + // DWARF claimed it had children but the DIE only contained + // a single NULL terminating child. + m_has_children : 1; + uint16_t m_abbr_idx; + uint16_t m_tag; // A copy of the DW_TAG value so we don't have to go through + // the compile unit abbrev table }; #endif // SymbolFileDWARF_DWARFDebugInfoEntry_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp index 317ea4c22c66..d9f50122bd6f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -41,7 +41,7 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data) { if (line_table_sp.get() == NULL) break; - if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get())) { + if (ParseStatementTable(debug_line_data, &offset, line_table_sp.get(), nullptr)) { // Make sure we don't don't loop infinitely if (offset <= debug_line_offset) break; @@ -127,7 +127,7 @@ DWARFDebugLine::DumpStatementTable(Log *log, "--------\n", debug_line_offset); - if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log)) + if (ParseStatementTable(debug_line_data, &offset, DumpStateToFile, log, nullptr)) return offset; else return debug_line_offset + 1; // Skip to next byte in .debug_line section @@ -366,17 +366,38 @@ void DWARFDebugLine::Parse(const DWARFDataExtractor &debug_line_data, void *userData) { lldb::offset_t offset = 0; if (debug_line_data.ValidOffset(offset)) { - if (!ParseStatementTable(debug_line_data, &offset, callback, userData)) + if (!ParseStatementTable(debug_line_data, &offset, callback, userData, nullptr)) ++offset; // Skip to next byte in .debug_line section } } +namespace { +struct EntryDescriptor { + dw_sleb128_t code; + dw_sleb128_t form; +}; + +static std::vector +ReadDescriptors(const DWARFDataExtractor &debug_line_data, + lldb::offset_t *offset_ptr) { + std::vector ret; + uint8_t n = debug_line_data.GetU8(offset_ptr); + for (uint8_t i = 0; i < n; ++i) { + EntryDescriptor ent; + ent.code = debug_line_data.GetULEB128(offset_ptr); + ent.form = debug_line_data.GetULEB128(offset_ptr); + ret.push_back(ent); + } + return ret; +} +} // namespace + //---------------------------------------------------------------------- // DWARFDebugLine::ParsePrologue //---------------------------------------------------------------------- bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - Prologue *prologue) { + Prologue *prologue, DWARFUnit *dwarf_cu) { const lldb::offset_t prologue_offset = *offset_ptr; // DEBUG_PRINTF("0x%8.8x: ParsePrologue()\n", *offset_ptr); @@ -386,9 +407,14 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, const char *s; prologue->total_length = debug_line_data.GetDWARFInitialLength(offset_ptr); prologue->version = debug_line_data.GetU16(offset_ptr); - if (prologue->version < 2 || prologue->version > 4) + if (prologue->version < 2 || prologue->version > 5) return false; + if (prologue->version >= 5) { + prologue->address_size = debug_line_data.GetU8(offset_ptr); + prologue->segment_selector_size = debug_line_data.GetU8(offset_ptr); + } + prologue->prologue_length = debug_line_data.GetDWARFOffset(offset_ptr); const lldb::offset_t end_prologue_offset = prologue->prologue_length + *offset_ptr; @@ -410,25 +436,83 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, prologue->standard_opcode_lengths.push_back(op_len); } - while (*offset_ptr < end_prologue_offset) { - s = debug_line_data.GetCStr(offset_ptr); - if (s && s[0]) - prologue->include_directories.push_back(s); - else - break; - } + if (prologue->version >= 5) { + std::vector dirEntryFormatV = + ReadDescriptors(debug_line_data, offset_ptr); + uint8_t dirCount = debug_line_data.GetULEB128(offset_ptr); + for (int i = 0; i < dirCount; ++i) { + for (EntryDescriptor &ent : dirEntryFormatV) { + DWARFFormValue value(dwarf_cu, ent.form); + if (ent.code != DW_LNCT_path) { + if (!value.SkipValue(debug_line_data, offset_ptr)) + return false; + continue; + } - while (*offset_ptr < end_prologue_offset) { - const char *name = debug_line_data.GetCStr(offset_ptr); - if (name && name[0]) { - FileNameEntry fileEntry; - fileEntry.name = name; - fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr); - fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr); - fileEntry.length = debug_line_data.GetULEB128(offset_ptr); - prologue->file_names.push_back(fileEntry); - } else - break; + if (!value.ExtractValue(debug_line_data, offset_ptr)) + return false; + prologue->include_directories.push_back(value.AsCString()); + } + } + + std::vector filesEntryFormatV = + ReadDescriptors(debug_line_data, offset_ptr); + llvm::DenseSet> seen; + uint8_t n = debug_line_data.GetULEB128(offset_ptr); + for (int i = 0; i < n; ++i) { + FileNameEntry entry; + for (EntryDescriptor &ent : filesEntryFormatV) { + DWARFFormValue value(dwarf_cu, ent.form); + if (!value.ExtractValue(debug_line_data, offset_ptr)) + return false; + + switch (ent.code) { + case DW_LNCT_path: + entry.name = value.AsCString(); + break; + case DW_LNCT_directory_index: + entry.dir_idx = value.Unsigned(); + break; + case DW_LNCT_timestamp: + entry.mod_time = value.Unsigned(); + break; + case DW_LNCT_size: + entry.length = value.Unsigned(); + break; + case DW_LNCT_MD5: + assert(value.Unsigned() == 16); + std::uninitialized_copy_n(value.BlockData(), 16, + entry.checksum.Bytes.begin()); + break; + default: + break; + } + } + + if (seen.insert(entry.checksum.words()).second) + prologue->file_names.push_back(entry); + } + } else { + while (*offset_ptr < end_prologue_offset) { + s = debug_line_data.GetCStr(offset_ptr); + if (s && s[0]) + prologue->include_directories.push_back(s); + else + break; + } + + while (*offset_ptr < end_prologue_offset) { + const char *name = debug_line_data.GetCStr(offset_ptr); + if (name && name[0]) { + FileNameEntry fileEntry; + fileEntry.name = name; + fileEntry.dir_idx = debug_line_data.GetULEB128(offset_ptr); + fileEntry.mod_time = debug_line_data.GetULEB128(offset_ptr); + fileEntry.length = debug_line_data.GetULEB128(offset_ptr); + prologue->file_names.push_back(fileEntry); + } else + break; + } } // XXX GNU as is broken for 64-Bit DWARF @@ -445,11 +529,11 @@ bool DWARFDebugLine::ParsePrologue(const DWARFDataExtractor &debug_line_data, bool DWARFDebugLine::ParseSupportFiles( const lldb::ModuleSP &module_sp, const DWARFDataExtractor &debug_line_data, const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, - FileSpecList &support_files) { + FileSpecList &support_files, DWARFUnit *dwarf_cu) { lldb::offset_t offset = stmt_list; Prologue prologue; - if (!ParsePrologue(debug_line_data, &offset, &prologue)) { + if (!ParsePrologue(debug_line_data, &offset, &prologue, dwarf_cu)) { Host::SystemLog(Host::eSystemLogError, "error: parsing line table prologue " "at 0x%8.8x (parsing ended around " "0x%8.8" PRIx64 "\n", @@ -463,7 +547,7 @@ bool DWARFDebugLine::ParseSupportFiles( for (uint32_t file_idx = 1; prologue.GetFile(file_idx, cu_comp_dir, file_spec); ++file_idx) { if (module_sp->RemapSourceFile(file_spec.GetPath(), remapped_file)) - file_spec.SetFile(remapped_file, false, FileSpec::Style::native); + file_spec.SetFile(remapped_file, FileSpec::Style::native); support_files.Append(file_spec); } return true; @@ -478,7 +562,7 @@ bool DWARFDebugLine::ParseSupportFiles( //---------------------------------------------------------------------- bool DWARFDebugLine::ParseStatementTable( const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - DWARFDebugLine::State::Callback callback, void *userData) { + DWARFDebugLine::State::Callback callback, void *userData, DWARFUnit *dwarf_cu) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_LINE)); Prologue::shared_ptr prologue(new Prologue()); @@ -489,7 +573,7 @@ bool DWARFDebugLine::ParseStatementTable( func_cat, "DWARFDebugLine::ParseStatementTable (.debug_line[0x%8.8x])", debug_line_offset); - if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get())) { + if (!ParsePrologue(debug_line_data, offset_ptr, prologue.get(), dwarf_cu)) { if (log) log->Error("failed to parse DWARF line table prologue"); // Restore our offset and return false to indicate failure! @@ -775,9 +859,9 @@ static void ParseStatementTableCallback(dw_offset_t offset, //---------------------------------------------------------------------- bool DWARFDebugLine::ParseStatementTable( const DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, - LineTable *line_table) { + LineTable *line_table, DWARFUnit *dwarf_cu) { return ParseStatementTable(debug_line_data, offset_ptr, - ParseStatementTableCallback, line_table); + ParseStatementTableCallback, line_table, dwarf_cu); } inline bool DWARFDebugLine::Prologue::IsValid() const { @@ -866,7 +950,7 @@ bool DWARFDebugLine::Prologue::GetFile(uint32_t file_idx, const lldb_private::FileSpec &comp_dir, FileSpec &file) const { uint32_t idx = file_idx - 1; // File indexes are 1 based... if (idx < file_names.size()) { - file.SetFile(file_names[idx].name, false, FileSpec::Style::native); + file.SetFile(file_names[idx].name, FileSpec::Style::native); if (file.IsRelative()) { if (file_names[idx].dir_idx > 0) { const uint32_t dir_idx = file_names[idx].dir_idx - 1; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h index 3ab15ac59028..04f72e03a2db 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.h @@ -19,6 +19,9 @@ #include "DWARFDataExtractor.h" #include "DWARFDefines.h" +#include "llvm/Support/MD5.h" + +class DWARFUnit; class SymbolFileDWARF; //---------------------------------------------------------------------- @@ -36,6 +39,7 @@ public: dw_sleb128_t dir_idx; dw_sleb128_t mod_time; dw_sleb128_t length; + llvm::MD5::MD5Result checksum; }; //------------------------------------------------------------------ @@ -55,6 +59,10 @@ public: // total_length field itself). uint16_t version; // Version identifier for the statement information format. + + uint8_t address_size; + uint8_t segment_selector_size; + uint32_t prologue_length; // The number of bytes following the // prologue_length field to the beginning of the // first byte of the statement program itself. @@ -201,14 +209,15 @@ public: const lldb_private::DWARFDataExtractor &debug_line_data, const lldb_private::FileSpec &cu_comp_dir, dw_offset_t stmt_list, - lldb_private::FileSpecList &support_files); + lldb_private::FileSpecList &support_files, DWARFUnit *dwarf_cu); static bool ParsePrologue(const lldb_private::DWARFDataExtractor &debug_line_data, - lldb::offset_t *offset_ptr, Prologue *prologue); + lldb::offset_t *offset_ptr, Prologue *prologue, + DWARFUnit *dwarf_cu = nullptr); static bool ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, lldb::offset_t *offset_ptr, State::Callback callback, - void *userData); + void *userData, DWARFUnit *dwarf_cu); static dw_offset_t DumpStatementTable(lldb_private::Log *log, const lldb_private::DWARFDataExtractor &debug_line_data, @@ -219,7 +228,8 @@ public: const dw_offset_t line_offset, uint32_t flags); static bool ParseStatementTable(const lldb_private::DWARFDataExtractor &debug_line_data, - lldb::offset_t *offset_ptr, LineTable *line_table); + lldb::offset_t *offset_ptr, LineTable *line_table, + DWARFUnit *dwarf_cu); static void Parse(const lldb_private::DWARFDataExtractor &debug_line_data, DWARFDebugLine::State::Callback callback, void *userData); // static void AppendLineTableData(const DWARFDebugLine::Prologue* prologue, diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 1c31d1c42598..d79acdc5cfc4 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -25,7 +25,7 @@ DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, header.m_version = debug_macro_data.GetU16(offset); uint8_t flags = debug_macro_data.GetU8(offset); - header.m_offset_is_64_bit = flags & OFFSET_SIZE_MASK ? true : false; + header.m_offset_is_64_bit = (flags & OFFSET_SIZE_MASK) != 0; if (flags & DEBUG_LINE_OFFSET_MASK) { if (header.m_offset_is_64_bit) diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp index 89e27efb3cc2..a0436dd7ffad 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "DWARFDebugRanges.h" +#include "DWARFUnit.h" #include "SymbolFileDWARF.h" #include "lldb/Utility/Stream.h" #include @@ -29,8 +30,6 @@ static dw_addr_t GetBaseAddressMarker(uint32_t addr_size) { DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {} -DWARFDebugRanges::~DWARFDebugRanges() {} - void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) { DWARFRangeList range_list; lldb::offset_t offset = 0; @@ -112,14 +111,185 @@ void DWARFDebugRanges::Dump(Stream &s, } } -bool DWARFDebugRanges::FindRanges(dw_addr_t debug_ranges_base, +bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, DWARFRangeList &range_list) const { - dw_addr_t debug_ranges_address = debug_ranges_base + debug_ranges_offset; + dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; range_map_const_iterator pos = m_range_map.find(debug_ranges_address); if (pos != m_range_map.end()) { range_list = pos->second; + + // All DW_AT_ranges are relative to the base address of the compile + // unit. We add the compile unit base address to make sure all the + // addresses are properly fixed up. + range_list.Slide(cu->GetBaseAddress()); return true; } return false; } + +uint64_t DWARFDebugRanges::GetOffset(size_t Index) const { + lldbassert(false && "DW_FORM_rnglistx is not present before DWARF5"); + return 0; +} + +bool DWARFDebugRngLists::ExtractRangeList( + const DWARFDataExtractor &data, uint8_t addrSize, + lldb::offset_t *offset_ptr, std::vector &rangeList) { + rangeList.clear(); + + bool error = false; + while (!error) { + switch (data.GetU8(offset_ptr)) { + case DW_RLE_end_of_list: + return true; + + case DW_RLE_start_length: { + dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); + dw_addr_t len = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_start_length, begin, len}); + break; + } + + case DW_RLE_start_end: { + dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize); + dw_addr_t end = data.GetMaxU64(offset_ptr, addrSize); + rangeList.push_back({DW_RLE_start_end, begin, end}); + break; + } + + case DW_RLE_base_address: { + dw_addr_t base = data.GetMaxU64(offset_ptr, addrSize); + rangeList.push_back({DW_RLE_base_address, base, 0}); + break; + } + + case DW_RLE_offset_pair: { + dw_addr_t begin = data.GetULEB128(offset_ptr); + dw_addr_t end = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_offset_pair, begin, end}); + break; + } + + case DW_RLE_base_addressx: { + dw_addr_t base = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_base_addressx, base, 0}); + break; + } + + case DW_RLE_startx_endx: { + dw_addr_t start = data.GetULEB128(offset_ptr); + dw_addr_t end = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_startx_endx, start, end}); + break; + } + + case DW_RLE_startx_length: { + dw_addr_t start = data.GetULEB128(offset_ptr); + dw_addr_t length = data.GetULEB128(offset_ptr); + rangeList.push_back({DW_RLE_startx_length, start, length}); + break; + } + + default: + lldbassert(0 && "unknown range list entry encoding"); + error = true; + } + } + + return false; +} + +static uint64_t ReadAddressFromDebugAddrSection(const DWARFUnit *cu, + uint32_t index) { + uint32_t index_size = cu->GetAddressByteSize(); + dw_offset_t addr_base = cu->GetAddrBase(); + lldb::offset_t offset = addr_base + index * index_size; + return cu->GetSymbolFileDWARF()->get_debug_addr_data().GetMaxU64(&offset, + index_size); +} + +bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu, + dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const { + range_list.Clear(); + dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset; + auto pos = m_range_map.find(debug_ranges_address); + if (pos != m_range_map.end()) { + dw_addr_t BaseAddr = cu->GetBaseAddress(); + for (const RngListEntry &E : pos->second) { + switch (E.encoding) { + case DW_RLE_start_length: + range_list.Append(DWARFRangeList::Entry(E.value0, E.value1)); + break; + case DW_RLE_base_address: + BaseAddr = E.value0; + break; + case DW_RLE_start_end: + range_list.Append(DWARFRangeList::Entry(E.value0, E.value1 - E.value0)); + break; + case DW_RLE_offset_pair: + range_list.Append( + DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0)); + break; + case DW_RLE_base_addressx: { + BaseAddr = ReadAddressFromDebugAddrSection(cu, E.value0); + break; + } + case DW_RLE_startx_endx: { + dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0); + dw_addr_t end = ReadAddressFromDebugAddrSection(cu, E.value1); + range_list.Append(DWARFRangeList::Entry(start, end - start)); + break; + } + case DW_RLE_startx_length: { + dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0); + range_list.Append(DWARFRangeList::Entry(start, E.value1)); + break; + } + default: + llvm_unreachable("unexpected encoding"); + } + } + return true; + } + return false; +} + +void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) { + const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data(); + lldb::offset_t offset = 0; + + uint64_t length = data.GetU32(&offset); + bool isDwarf64 = (length == 0xffffffff); + if (isDwarf64) + length = data.GetU64(&offset); + lldb::offset_t end = offset + length; + + // Check version. + if (data.GetU16(&offset) < 5) + return; + + uint8_t addrSize = data.GetU8(&offset); + + // We do not support non-zero segment selector size. + if (data.GetU8(&offset) != 0) { + lldbassert(0 && "not implemented"); + return; + } + + uint32_t offsetsAmount = data.GetU32(&offset); + for (uint32_t i = 0; i < offsetsAmount; ++i) + Offsets.push_back(data.GetMaxU64(&offset, isDwarf64 ? 8 : 4)); + + lldb::offset_t listOffset = offset; + std::vector rangeList; + while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) { + m_range_map[listOffset] = rangeList; + listOffset = offset; + } +} + +uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const { + return Offsets[Index]; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h index f514359e00a4..5790f448ba85 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h @@ -15,17 +15,28 @@ #include -class DWARFDebugRanges { +class DWARFDebugRangesBase { +public: + virtual ~DWARFDebugRangesBase(){}; + + virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0; + virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const = 0; + virtual uint64_t GetOffset(size_t Index) const = 0; +}; + +class DWARFDebugRanges final : public DWARFDebugRangesBase { public: DWARFDebugRanges(); - ~DWARFDebugRanges(); - void Extract(SymbolFileDWARF *dwarf2Data); + + void Extract(SymbolFileDWARF *dwarf2Data) override; + bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const override; + uint64_t GetOffset(size_t Index) const override; + static void Dump(lldb_private::Stream &s, const lldb_private::DWARFDataExtractor &debug_ranges_data, lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr); - bool FindRanges(dw_addr_t debug_ranges_base, - dw_offset_t debug_ranges_offset, - DWARFRangeList &range_list) const; protected: bool Extract(SymbolFileDWARF *dwarf2Data, lldb::offset_t *offset_ptr, @@ -37,4 +48,27 @@ protected: range_map m_range_map; }; +// DWARF v5 .debug_rnglists section. +class DWARFDebugRngLists final : public DWARFDebugRangesBase { + struct RngListEntry { + uint8_t encoding; + uint64_t value0; + uint64_t value1; + }; + +public: + void Extract(SymbolFileDWARF *dwarf2Data) override; + bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset, + DWARFRangeList &range_list) const override; + uint64_t GetOffset(size_t Index) const override; + +protected: + bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data, + uint8_t addrSize, lldb::offset_t *offset_ptr, + std::vector &list); + + std::vector Offsets; + std::map> m_range_map; +}; + #endif // SymbolFileDWARF_DWARFDebugRanges_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index 1f3c59768fdf..aff5ea64e9ce 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -10,13 +10,9 @@ #ifndef SymbolFileDWARF_DWARFDeclContext_h_ #define SymbolFileDWARF_DWARFDeclContext_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "lldb/Utility/ConstString.h" -// Project includes #include "DWARFDefines.h" //---------------------------------------------------------------------- diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp index 1d927ba3bca3..99becdbb2bc1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.cpp @@ -504,9 +504,9 @@ const char *DW_MACINFO_value_to_name(uint32_t val) { return llvmstr.data(); } -const char *DW_CFA_value_to_name(uint32_t val) { +const char *DW_CFA_value_to_name(uint32_t val, llvm::Triple::ArchType Arch) { static char invalid[100]; - llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val); + llvm::StringRef llvmstr = llvm::dwarf::CallFrameString(val, Arch); if (llvmstr.empty()) { snprintf(invalid, sizeof(invalid), "Unknown DW_CFA constant: 0x%x", val); return invalid; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h index 926f83b3564a..0f5a885efb86 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFDefines.h @@ -64,7 +64,7 @@ const char *DW_LNE_value_to_name(uint32_t val); const char *DW_MACINFO_value_to_name(uint32_t val); -const char *DW_CFA_value_to_name(uint32_t val); +const char *DW_CFA_value_to_name(uint32_t val, llvm::Triple::ArchType Arch); const char *DW_GNU_EH_PE_value_to_name(uint32_t val); diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index 4fde5748d3f3..5d2a8ffdb85b 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -154,6 +154,9 @@ DWARFFormValue::GetFixedFormSizesForAddressSize(uint8_t addr_size, DWARFFormValue::DWARFFormValue() : m_cu(NULL), m_form(0), m_value() {} +DWARFFormValue::DWARFFormValue(const DWARFUnit *cu) + : m_cu(cu), m_form(0), m_value() {} + DWARFFormValue::DWARFFormValue(const DWARFUnit *cu, dw_form_t form) : m_cu(cu), m_form(form), m_value() {} @@ -165,6 +168,9 @@ void DWARFFormValue::Clear() { bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, lldb::offset_t *offset_ptr) { + if (m_form == DW_FORM_implicit_const) + return true; + bool indirect = false; bool is_block = false; m_value.data = NULL; @@ -176,8 +182,12 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, switch (m_form) { case DW_FORM_addr: assert(m_cu); - m_value.value.uval = data.GetMaxU64( - offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); + m_value.value.uval = + data.GetMaxU64(offset_ptr, DWARFUnit::GetAddressByteSize(m_cu)); + break; + case DW_FORM_block1: + m_value.value.uval = data.GetU8(offset_ptr); + is_block = true; break; case DW_FORM_block2: m_value.value.uval = data.GetU16(offset_ptr); @@ -187,94 +197,82 @@ bool DWARFFormValue::ExtractValue(const DWARFDataExtractor &data, m_value.value.uval = data.GetU32(offset_ptr); is_block = true; break; - case DW_FORM_data2: - m_value.value.uval = data.GetU16(offset_ptr); - break; - case DW_FORM_data4: - m_value.value.uval = data.GetU32(offset_ptr); - break; - case DW_FORM_data8: - m_value.value.uval = data.GetU64(offset_ptr); - break; - case DW_FORM_string: - m_value.value.cstr = data.GetCStr(offset_ptr); + case DW_FORM_data16: + m_value.value.uval = 16; + is_block = true; break; case DW_FORM_exprloc: case DW_FORM_block: m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true; break; - case DW_FORM_block1: - m_value.value.uval = data.GetU8(offset_ptr); - is_block = true; - break; - case DW_FORM_data1: - m_value.value.uval = data.GetU8(offset_ptr); - break; - case DW_FORM_flag: - m_value.value.uval = data.GetU8(offset_ptr); + case DW_FORM_string: + m_value.value.cstr = data.GetCStr(offset_ptr); break; case DW_FORM_sdata: m_value.value.sval = data.GetSLEB128(offset_ptr); break; case DW_FORM_strp: + case DW_FORM_line_strp: + case DW_FORM_sec_offset: assert(m_cu); m_value.value.uval = data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); break; - // case DW_FORM_APPLE_db_str: + case DW_FORM_addrx1: + case DW_FORM_strx1: + case DW_FORM_ref1: + case DW_FORM_data1: + case DW_FORM_flag: + m_value.value.uval = data.GetU8(offset_ptr); + break; + case DW_FORM_addrx2: + case DW_FORM_strx2: + case DW_FORM_ref2: + case DW_FORM_data2: + m_value.value.uval = data.GetU16(offset_ptr); + break; + case DW_FORM_addrx3: + case DW_FORM_strx3: + m_value.value.uval = data.GetMaxU64(offset_ptr, 3); + break; + case DW_FORM_addrx4: + case DW_FORM_strx4: + case DW_FORM_ref4: + case DW_FORM_data4: + m_value.value.uval = data.GetU32(offset_ptr); + break; + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + m_value.value.uval = data.GetU64(offset_ptr); + break; + case DW_FORM_addrx: + case DW_FORM_rnglistx: + case DW_FORM_strx: case DW_FORM_udata: + case DW_FORM_ref_udata: + case DW_FORM_GNU_str_index: + case DW_FORM_GNU_addr_index: m_value.value.uval = data.GetULEB128(offset_ptr); break; case DW_FORM_ref_addr: assert(m_cu); - ref_addr_size = 4; if (m_cu->GetVersion() <= 2) ref_addr_size = m_cu->GetAddressByteSize(); else ref_addr_size = m_cu->IsDWARF64() ? 8 : 4; m_value.value.uval = data.GetMaxU64(offset_ptr, ref_addr_size); break; - case DW_FORM_ref1: - m_value.value.uval = data.GetU8(offset_ptr); - break; - case DW_FORM_ref2: - m_value.value.uval = data.GetU16(offset_ptr); - break; - case DW_FORM_ref4: - m_value.value.uval = data.GetU32(offset_ptr); - break; - case DW_FORM_ref8: - m_value.value.uval = data.GetU64(offset_ptr); - break; - case DW_FORM_ref_udata: - m_value.value.uval = data.GetULEB128(offset_ptr); - break; case DW_FORM_indirect: m_form = data.GetULEB128(offset_ptr); indirect = true; break; - - case DW_FORM_sec_offset: - assert(m_cu); - m_value.value.uval = - data.GetMaxU64(offset_ptr, DWARFUnit::IsDWARF64(m_cu) ? 8 : 4); - break; case DW_FORM_flag_present: m_value.value.uval = 1; break; - case DW_FORM_ref_sig8: - m_value.value.uval = data.GetU64(offset_ptr); - break; - case DW_FORM_GNU_str_index: - m_value.value.uval = data.GetULEB128(offset_ptr); - break; - case DW_FORM_GNU_addr_index: - m_value.value.uval = data.GetULEB128(offset_ptr); - break; default: return false; - break; } } while (indirect); @@ -346,49 +344,65 @@ bool DWARFFormValue::SkipValue(dw_form_t form, // 0 bytes values (implied from DW_FORM) case DW_FORM_flag_present: + case DW_FORM_implicit_const: return true; - // 1 byte values - case DW_FORM_data1: - case DW_FORM_flag: - case DW_FORM_ref1: - *offset_ptr += 1; - return true; + // 1 byte values + case DW_FORM_addrx1: + case DW_FORM_data1: + case DW_FORM_flag: + case DW_FORM_ref1: + case DW_FORM_strx1: + *offset_ptr += 1; + return true; - // 2 byte values - case DW_FORM_data2: - case DW_FORM_ref2: - *offset_ptr += 2; - return true; + // 2 byte values + case DW_FORM_addrx2: + case DW_FORM_data2: + case DW_FORM_ref2: + case DW_FORM_strx2: + *offset_ptr += 2; + return true; - // 32 bit for DWARF 32, 64 for DWARF 64 - case DW_FORM_sec_offset: - case DW_FORM_strp: - assert(cu); - *offset_ptr += (cu->IsDWARF64() ? 8 : 4); - return true; + // 3 byte values + case DW_FORM_addrx3: + case DW_FORM_strx3: + *offset_ptr += 3; + return true; - // 4 byte values - case DW_FORM_data4: - case DW_FORM_ref4: - *offset_ptr += 4; - return true; + // 32 bit for DWARF 32, 64 for DWARF 64 + case DW_FORM_sec_offset: + case DW_FORM_strp: + assert(cu); + *offset_ptr += (cu->IsDWARF64() ? 8 : 4); + return true; - // 8 byte values - case DW_FORM_data8: - case DW_FORM_ref8: - case DW_FORM_ref_sig8: - *offset_ptr += 8; - return true; + // 4 byte values + case DW_FORM_addrx4: + case DW_FORM_data4: + case DW_FORM_ref4: + case DW_FORM_strx4: + *offset_ptr += 4; + return true; - // signed or unsigned LEB 128 values - case DW_FORM_sdata: - case DW_FORM_udata: - case DW_FORM_ref_udata: - case DW_FORM_GNU_addr_index: - case DW_FORM_GNU_str_index: - debug_info_data.Skip_LEB128(offset_ptr); - return true; + // 8 byte values + case DW_FORM_data8: + case DW_FORM_ref8: + case DW_FORM_ref_sig8: + *offset_ptr += 8; + return true; + + // signed or unsigned LEB 128 values + case DW_FORM_addrx: + case DW_FORM_rnglistx: + case DW_FORM_sdata: + case DW_FORM_udata: + case DW_FORM_ref_udata: + case DW_FORM_GNU_addr_index: + case DW_FORM_GNU_str_index: + case DW_FORM_strx: + debug_info_data.Skip_LEB128(offset_ptr); + return true; case DW_FORM_indirect: { dw_form_t indirect_form = debug_info_data.GetULEB128(offset_ptr); @@ -546,6 +560,26 @@ const char *DWARFFormValue::AsCString() const { index_size); return symbol_file->get_debug_str_data().PeekCStr(str_offset); } + + if (m_form == DW_FORM_strx || m_form == DW_FORM_strx1 || + m_form == DW_FORM_strx2 || m_form == DW_FORM_strx3 || + m_form == DW_FORM_strx4) { + + // The same code as above. + if (!symbol_file) + return nullptr; + + uint32_t indexSize = m_cu->IsDWARF64() ? 8 : 4; + lldb::offset_t offset = + m_cu->GetStrOffsetsBase() + m_value.value.uval * indexSize; + dw_offset_t strOffset = + symbol_file->get_debug_str_offsets_data().GetMaxU64(&offset, indexSize); + return symbol_file->get_debug_str_data().PeekCStr(strOffset); + } + + if (m_form == DW_FORM_line_strp) + return symbol_file->get_debug_line_str_data().PeekCStr(m_value.value.uval); + return nullptr; } @@ -556,7 +590,9 @@ dw_addr_t DWARFFormValue::Address() const { return Unsigned(); assert(m_cu); - assert(m_form == DW_FORM_GNU_addr_index); + assert(m_form == DW_FORM_GNU_addr_index || m_form == DW_FORM_addrx || + m_form == DW_FORM_addrx1 || m_form == DW_FORM_addrx2 || + m_form == DW_FORM_addrx3 || m_form == DW_FORM_addrx4); if (!symbol_file) return 0; @@ -568,7 +604,7 @@ dw_addr_t DWARFFormValue::Address() const { } uint64_t DWARFFormValue::Reference() const { - uint64_t die_offset = m_value.value.uval; + uint64_t value = m_value.value.uval; switch (m_form) { case DW_FORM_ref1: case DW_FORM_ref2: @@ -577,32 +613,36 @@ uint64_t DWARFFormValue::Reference() const { case DW_FORM_ref_udata: assert(m_cu); // CU must be valid for DW_FORM_ref forms that are compile // unit relative or we will get this wrong - die_offset += m_cu->GetOffset(); - break; + return value + m_cu->GetOffset(); + + case DW_FORM_ref_addr: + case DW_FORM_ref_sig8: + case DW_FORM_GNU_ref_alt: + return value; default: - break; + return DW_INVALID_OFFSET; } - - return die_offset; } uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const { - uint64_t die_offset = m_value.value.uval; + uint64_t value = m_value.value.uval; switch (m_form) { case DW_FORM_ref1: case DW_FORM_ref2: case DW_FORM_ref4: case DW_FORM_ref8: case DW_FORM_ref_udata: - die_offset += base_offset; - break; + return value + base_offset; + + case DW_FORM_ref_addr: + case DW_FORM_ref_sig8: + case DW_FORM_GNU_ref_alt: + return value; default: - break; + return DW_INVALID_OFFSET; } - - return die_offset; } const uint8_t *DWARFFormValue::BlockData() const { return m_value.data; } @@ -729,6 +769,8 @@ int DWARFFormValue::Compare(const DWARFFormValue &a_value, bool DWARFFormValue::FormIsSupported(dw_form_t form) { switch (form) { case DW_FORM_addr: + case DW_FORM_addrx: + case DW_FORM_rnglistx: case DW_FORM_block2: case DW_FORM_block4: case DW_FORM_data2: @@ -741,6 +783,11 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) { case DW_FORM_flag: case DW_FORM_sdata: case DW_FORM_strp: + case DW_FORM_strx: + case DW_FORM_strx1: + case DW_FORM_strx2: + case DW_FORM_strx3: + case DW_FORM_strx4: case DW_FORM_udata: case DW_FORM_ref_addr: case DW_FORM_ref1: @@ -755,6 +802,7 @@ bool DWARFFormValue::FormIsSupported(dw_form_t form) { case DW_FORM_ref_sig8: case DW_FORM_GNU_str_index: case DW_FORM_GNU_addr_index: + case DW_FORM_implicit_const: return true; default: break; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h index ef1a693b37c9..0890f0c1bfc5 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h @@ -11,9 +11,10 @@ #define SymbolFileDWARF_DWARFFormValue_h_ #include "DWARFDataExtractor.h" -#include // for NULL +#include class DWARFUnit; +class SymbolFileDWARF; class DWARFFormValue { public: @@ -55,12 +56,17 @@ public: }; DWARFFormValue(); + DWARFFormValue(const DWARFUnit *cu); DWARFFormValue(const DWARFUnit *cu, dw_form_t form); const DWARFUnit *GetCompileUnit() const { return m_cu; } void SetCompileUnit(const DWARFUnit *cu) { m_cu = cu; } dw_form_t Form() const { return m_form; } + dw_form_t& FormRef() { return m_form; } void SetForm(dw_form_t form) { m_form = form; } const ValueType &Value() const { return m_value; } + ValueType &ValueRef() { return m_value; } + void SetValue(const ValueType &val) { m_value = val; } + void Dump(lldb_private::Stream &s) const; bool ExtractValue(const lldb_private::DWARFDataExtractor &data, lldb::offset_t *offset_ptr); diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index d26556d73e28..7afc71bc24f0 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -191,13 +191,6 @@ void DWARFUnit::ExtractDIEsRWLocked() { IsDWARF64()); while (offset < next_cu_offset && die.FastExtract(data, this, fixed_form_sizes, &offset)) { - // if (log) - // log->Printf("0x%8.8x: %*.*s%s%s", - // die.GetOffset(), - // depth * 2, depth * 2, "", - // DW_TAG_value_to_name (die.Tag()), - // die.HasChildren() ? " *" : ""); - const bool null_die = die.IsNULL(); if (depth == 0) { assert(m_die_array.empty() && "Compile unit DIE already added"); @@ -223,7 +216,7 @@ void DWARFUnit::ExtractDIEsRWLocked() { // the list (saves up to 25% in C++ code), we need a way to let the // DIE know that it actually doesn't have children. if (!m_die_array.empty()) - m_die_array.back().SetEmptyChildren(true); + m_die_array.back().SetHasChildren(false); } } else { die.SetParentIndex(m_die_array.size() - die_index_stack[depth - 1]); @@ -244,9 +237,6 @@ void DWARFUnit::ExtractDIEsRWLocked() { if (depth > 0) --depth; - if (depth == 0) - break; // We are done with this compile unit! - prev_die_had_children = false; } else { die_index_stack.back() = m_die_array.size() - 1; @@ -258,12 +248,15 @@ void DWARFUnit::ExtractDIEsRWLocked() { } prev_die_had_children = die_has_children; } + + if (depth == 0) + break; // We are done with this compile unit! } if (!m_die_array.empty()) { if (m_first_die) { // Only needed for the assertion. - m_first_die.SetEmptyChildren(m_die_array.front().GetEmptyChildren()); + m_first_die.SetHasChildren(m_die_array.front().HasChildren()); lldbassert(m_first_die == m_die_array.front()); } m_first_die = m_die_array.front(); @@ -305,8 +298,46 @@ void DWARFUnit::ExtractDIEsEndCheck(lldb::offset_t offset) const { } } +// This is used when a split dwarf is enabled. +// A skeleton compilation unit may contain the DW_AT_str_offsets_base attribute +// that points to the first string offset of the CU contribution to the +// .debug_str_offsets. At the same time, the corresponding split debug unit also +// may use DW_FORM_strx* forms pointing to its own .debug_str_offsets.dwo and +// for that case, we should find the offset (skip the section header). +static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) { + lldb::offset_t baseOffset = 0; + + const DWARFDataExtractor &strOffsets = + dwo_cu->GetSymbolFileDWARF()->get_debug_str_offsets_data(); + uint64_t length = strOffsets.GetU32(&baseOffset); + if (length == 0xffffffff) + length = strOffsets.GetU64(&baseOffset); + + // Check version. + if (strOffsets.GetU16(&baseOffset) < 5) + return; + + // Skip padding. + baseOffset += 2; + + dwo_cu->SetStrOffsetsBase(baseOffset); +} + // m_die_array_mutex must be already held as read/write. void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { + dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned( + m_dwarf, this, DW_AT_addr_base, LLDB_INVALID_ADDRESS); + if (addr_base != LLDB_INVALID_ADDRESS) + SetAddrBase(addr_base); + + dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( + m_dwarf, this, DW_AT_rnglists_base, LLDB_INVALID_ADDRESS); + if (ranges_base != LLDB_INVALID_ADDRESS) + SetRangesBase(ranges_base); + + SetStrOffsetsBase(cu_die.GetAttributeValueAsUnsigned( + m_dwarf, this, DW_AT_str_offsets_base, 0)); + uint64_t base_addr = cu_die.GetAttributeValueAsAddress( m_dwarf, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS); if (base_addr == LLDB_INVALID_ADDRESS) @@ -337,11 +368,25 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) { m_dwo_symbol_file = std::move(dwo_symbol_file); - dw_addr_t addr_base = - cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, DW_AT_GNU_addr_base, 0); - dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned( - m_dwarf, this, DW_AT_GNU_ranges_base, 0); - dwo_cu->SetAddrBase(addr_base, ranges_base, m_offset); + // Here for DWO CU we want to use the address base set in the skeleton unit + // (DW_AT_addr_base) if it is available and use the DW_AT_GNU_addr_base + // otherwise. We do that because pre-DWARF v5 could use the DW_AT_GNU_* + // attributes which were applicable to the DWO units. The corresponding + // DW_AT_* attributes standardized in DWARF v5 are also applicable to the main + // unit in contrast. + if (addr_base == LLDB_INVALID_ADDRESS) + addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, + DW_AT_GNU_addr_base, 0); + dwo_cu->SetAddrBase(addr_base); + + if (ranges_base == LLDB_INVALID_ADDRESS) + ranges_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf, this, + DW_AT_GNU_ranges_base, 0); + dwo_cu->SetRangesBase(ranges_base); + + dwo_cu->SetBaseObjOffset(m_offset); + + SetDwoStrOffsetsBase(dwo_cu); } DWARFDIE DWARFUnit::LookupAddress(const dw_addr_t address) { @@ -399,14 +444,20 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const { return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET; } -void DWARFUnit::SetAddrBase(dw_addr_t addr_base, - dw_addr_t ranges_base, - dw_offset_t base_obj_offset) { - m_addr_base = addr_base; +void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; } + +void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) { m_ranges_base = ranges_base; +} + +void DWARFUnit::SetBaseObjOffset(dw_offset_t base_obj_offset) { m_base_obj_offset = base_obj_offset; } +void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) { + m_str_offsets_base = str_offsets_base; +} + // It may be called only with m_die_array_mutex held R/W. void DWARFUnit::ClearDIEsRWLocked() { m_die_array.clear(); @@ -590,9 +641,7 @@ void DWARFUnit::SetUserData(void *d) { } bool DWARFUnit::Supports_DW_AT_APPLE_objc_complete_type() { - if (GetProducer() == eProducerLLVMGCC) - return false; - return true; + return GetProducer() != eProducerLLVMGCC; } bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() { @@ -604,11 +653,8 @@ bool DWARFUnit::DW_AT_decl_file_attributes_are_invalid() { bool DWARFUnit::Supports_unnamed_objc_bitfields() { if (GetProducer() == eProducerClang) { const uint32_t major_version = GetProducerVersionMajor(); - if (major_version > 425 || - (major_version == 425 && GetProducerVersionUpdate() >= 13)) - return true; - else - return false; + return major_version > 425 || + (major_version == 425 && GetProducerVersionUpdate() >= 13); } return true; // Assume all other compilers didn't have incorrect ObjC bitfield // info diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 3cc24d4202b8..178c894686ee 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -111,8 +111,11 @@ public: dw_addr_t GetBaseAddress() const { return m_base_addr; } dw_addr_t GetAddrBase() const { return m_addr_base; } dw_addr_t GetRangesBase() const { return m_ranges_base; } - void SetAddrBase(dw_addr_t addr_base, dw_addr_t ranges_base, - dw_offset_t base_obj_offset); + dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; } + void SetAddrBase(dw_addr_t addr_base); + void SetRangesBase(dw_addr_t ranges_base); + void SetBaseObjOffset(dw_offset_t base_obj_offset); + void SetStrOffsetsBase(dw_offset_t str_offsets_base); void BuildAddressRangeTable(SymbolFileDWARF *dwarf, DWARFDebugAranges *debug_aranges); @@ -202,6 +205,8 @@ protected: dw_offset_t m_length = 0; uint16_t m_version = 0; uint8_t m_addr_size = 0; + uint8_t m_unit_type = 0; + uint64_t m_dwo_id = 0; DWARFProducer m_producer = eProducerInvalid; uint32_t m_producer_version_major = 0; uint32_t m_producer_version_minor = 0; @@ -214,7 +219,7 @@ protected: // If this is a dwo compile unit this is the offset of the base compile unit // in the main object file dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET; - + dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base. // Offset of the initial length field. dw_offset_t m_offset; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 614ff470d161..c043272f8a3e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -225,7 +225,8 @@ void DebugNamesDWARFIndex::GetFunctions( const CompilerDeclContext &parent_decl_ctx, uint32_t name_type_mask, std::vector &dies) { - m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, dies); + std::vector v; + m_fallback.GetFunctions(name, info, parent_decl_ctx, name_type_mask, v); for (const DebugNames::Entry &entry : m_debug_names_up->equal_range(name.GetStringRef())) { @@ -235,8 +236,13 @@ void DebugNamesDWARFIndex::GetFunctions( if (DIERef ref = ToDIERef(entry)) ProcessFunctionDIE(name.GetStringRef(), ref, info, parent_decl_ctx, - name_type_mask, dies); + name_type_mask, v); } + + std::set seen; + for (DWARFDIE die : v) + if (seen.insert(die.GetDIE()).second) + dies.push_back(die); } void DebugNamesDWARFIndex::GetFunctions(const RegularExpression ®ex, diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index 36211a08557e..f83ba6663dfc 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -279,7 +279,9 @@ bool DWARFMappedHash::Header::Read(const lldb_private::DWARFDataExtractor &data, switch (header_data.atoms[i].type) { case eAtomTypeDIEOffset: // DIE offset, check form for encoding hash_data.offset = - (dw_offset_t)form_value.Reference(header_data.die_base_offset); + DWARFFormValue::IsDataForm(form_value.Form()) + ? form_value.Unsigned() + : form_value.Reference(header_data.die_base_offset); break; case eAtomTypeTag: // DW_TAG value for the DIE diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h index 0293fbd7c495..038e9b8c2b08 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h @@ -10,10 +10,6 @@ #ifndef SymbolFileDWARF_LogChannelDWARF_h_ #define SymbolFileDWARF_LogChannelDWARF_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Utility/Log.h" #define DWARF_LOG_DEBUG_INFO (1u << 1) diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index ac320ac52b08..2a0a89f0b25a 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -9,7 +9,6 @@ #include "SymbolFileDWARF.h" -// Other libraries and framework includes #include "llvm/Support/Casting.h" #include "llvm/Support/Threading.h" @@ -17,12 +16,12 @@ #include "lldb/Core/ModuleList.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Section.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Utility/ArchSpec.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" @@ -111,17 +110,14 @@ using namespace lldb_private; namespace { -PropertyDefinition g_properties[] = { +static constexpr PropertyDefinition g_properties[] = { {"comp-dir-symlink-paths", OptionValue::eTypeFileSpecList, true, 0, nullptr, - nullptr, + {}, "If the DW_AT_comp_dir matches any of these paths the symbolic " "links will be resolved at DWARF parse time."}, - {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, - nullptr, + {"ignore-file-indexes", OptionValue::eTypeBoolean, true, 0, nullptr, {}, "Ignore indexes present in the object files and always index DWARF " - "manually."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}, -}; + "manually."}}; enum { ePropertySymLinkPaths, @@ -200,7 +196,7 @@ static FileSpec resolveCompDir(const char *path_from_dwarf) { bool is_symlink = false; // Always normalize our compile unit directory to get rid of redundant // slashes and other path anomalies before we use it for path prepending - FileSpec local_spec(local_path, false); + FileSpec local_spec(local_path); const auto &file_specs = GetGlobalPluginProperties()->GetSymLinkPaths(); for (size_t i = 0; i < file_specs.GetSize() && !is_symlink; ++i) is_symlink = FileSpec::Equal(file_specs.GetFileSpecAtIndex(i), @@ -215,7 +211,7 @@ static FileSpec resolveCompDir(const char *path_from_dwarf) { return local_spec; FileSpec resolved_symlink; - const auto error = FileSystem::Readlink(local_spec, resolved_symlink); + const auto error = FileSystem::Instance().Readlink(local_spec, resolved_symlink); if (error.Success()) return resolved_symlink; @@ -263,6 +259,9 @@ SymbolFile *SymbolFileDWARF::CreateInstance(ObjectFile *obj_file) { } TypeList *SymbolFileDWARF::GetTypeList() { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) return debug_map_symfile->GetTypeList(); @@ -341,9 +340,10 @@ void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, } size_t SymbolFileDWARF::GetTypes(SymbolContextScope *sc_scope, - uint32_t type_mask, TypeList &type_list) + TypeClass type_mask, TypeList &type_list) { + ASSERT_MODULE_LOCK(this); TypeSet type_set; CompileUnit *comp_unit = NULL; @@ -413,9 +413,9 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile *objfile) m_debug_map_module_wp(), m_debug_map_symfile(NULL), m_data_debug_abbrev(), m_data_debug_aranges(), m_data_debug_frame(), m_data_debug_info(), m_data_debug_line(), m_data_debug_macro(), m_data_debug_loc(), - m_data_debug_ranges(), m_data_debug_str(), m_data_apple_names(), - m_data_apple_types(), m_data_apple_namespaces(), m_abbr(), m_info(), - m_line(), m_fetched_external_modules(false), + m_data_debug_ranges(), m_data_debug_rnglists(), m_data_debug_str(), + m_data_apple_names(), m_data_apple_types(), m_data_apple_namespaces(), + m_abbr(), m_info(), m_line(), m_fetched_external_modules(false), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate), m_ranges(), m_unique_ast_type_map() {} @@ -494,7 +494,7 @@ void SymbolFileDWARF::InitializeObject() { } bool SymbolFileDWARF::SupportedVersion(uint16_t version) { - return version == 2 || version == 3 || version == 4; + return version >= 2 && version <= 5; } uint32_t SymbolFileDWARF::CalculateAbilities() { @@ -645,19 +645,40 @@ const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_data() { return GetCachedSectionData(eSectionTypeDWARFDebugLine, m_data_debug_line); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_line_str_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugLineStr, m_data_debug_line_str); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_macro_data() { return GetCachedSectionData(eSectionTypeDWARFDebugMacro, m_data_debug_macro); } +const DWARFDataExtractor &SymbolFileDWARF::DebugLocData() { + const DWARFDataExtractor &debugLocData = get_debug_loc_data(); + if (debugLocData.GetByteSize() > 0) + return debugLocData; + return get_debug_loclists_data(); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_loc_data() { return GetCachedSectionData(eSectionTypeDWARFDebugLoc, m_data_debug_loc); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_loclists_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugLocLists, + m_data_debug_loclists); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_ranges_data() { return GetCachedSectionData(eSectionTypeDWARFDebugRanges, m_data_debug_ranges); } +const DWARFDataExtractor &SymbolFileDWARF::get_debug_rnglists_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugRngLists, + m_data_debug_rnglists); +} + const DWARFDataExtractor &SymbolFileDWARF::get_debug_str_data() { return GetCachedSectionData(eSectionTypeDWARFDebugStr, m_data_debug_str); } @@ -747,21 +768,24 @@ SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) { return NULL; } -DWARFDebugRanges *SymbolFileDWARF::DebugRanges() { +DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() { if (m_ranges.get() == NULL) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION, static_cast(this)); - if (get_debug_ranges_data().GetByteSize() > 0) { + + if (get_debug_ranges_data().GetByteSize() > 0) m_ranges.reset(new DWARFDebugRanges()); - if (m_ranges.get()) - m_ranges->Extract(this); - } + else if (get_debug_rnglists_data().GetByteSize() > 0) + m_ranges.reset(new DWARFDebugRngLists()); + + if (m_ranges.get()) + m_ranges->Extract(this); } return m_ranges.get(); } -const DWARFDebugRanges *SymbolFileDWARF::DebugRanges() const { +const DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() const { return m_ranges.get(); } @@ -786,7 +810,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu, if (module_sp) { const DWARFDIE cu_die = dwarf_cu->DIE(); if (cu_die) { - FileSpec cu_file_spec{cu_die.GetName(), false}; + FileSpec cu_file_spec(cu_die.GetName()); if (cu_file_spec) { // If we have a full path to the compile unit, we don't need to // resolve the file. This can be expensive e.g. when the source @@ -801,8 +825,7 @@ lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu, std::string remapped_file; if (module_sp->RemapSourceFile(cu_file_spec.GetPath(), remapped_file)) - cu_file_spec.SetFile(remapped_file, false, - FileSpec::Style::native); + cu_file_spec.SetFile(remapped_file, FileSpec::Style::native); } LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF( @@ -851,6 +874,7 @@ uint32_t SymbolFileDWARF::GetNumCompileUnits() { } CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { + ASSERT_MODULE_LOCK(this); CompUnitSP cu_sp; DWARFDebugInfo *info = DebugInfo(); if (info) { @@ -861,8 +885,9 @@ CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) { return cu_sp; } -Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc, - const DWARFDIE &die) { +Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, + const DWARFDIE &die) { + ASSERT_MODULE_LOCK(this); if (die.IsValid()) { TypeSystem *type_system = GetTypeSystemForLanguage(die.GetCU()->GetLanguageType()); @@ -870,7 +895,7 @@ Function *SymbolFileDWARF::ParseCompileUnitFunction(const SymbolContext &sc, if (type_system) { DWARFASTParser *dwarf_ast = type_system->GetDWARFParser(); if (dwarf_ast) - return dwarf_ast->ParseFunctionFromDWARF(sc, die); + return dwarf_ast->ParseFunctionFromDWARF(comp_unit, die); } } return nullptr; @@ -884,20 +909,19 @@ bool SymbolFileDWARF::FixupAddress(Address &addr) { // This is a normal DWARF file, no address fixups need to happen return true; } -lldb::LanguageType -SymbolFileDWARF::ParseCompileUnitLanguage(const SymbolContext &sc) { - assert(sc.comp_unit); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); +lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) return dwarf_cu->GetLanguageType(); else return eLanguageTypeUnknown; } -size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { - assert(sc.comp_unit); +size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); size_t functions_added = 0; - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) { DWARFDIECollection function_dies; const size_t num_functions = @@ -905,8 +929,8 @@ size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { size_t func_idx; for (func_idx = 0; func_idx < num_functions; ++func_idx) { DWARFDIE die = function_dies.GetDIEAtIndex(func_idx); - if (sc.comp_unit->FindFunctionByUID(die.GetID()).get() == NULL) { - if (ParseCompileUnitFunction(sc, die)) + if (comp_unit.FindFunctionByUID(die.GetID()).get() == NULL) { + if (ParseFunction(comp_unit, die)) ++functions_added; } } @@ -915,10 +939,10 @@ size_t SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc) { return functions_added; } -bool SymbolFileDWARF::ParseCompileUnitSupportFiles( - const SymbolContext &sc, FileSpecList &support_files) { - assert(sc.comp_unit); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); +bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) { + ASSERT_MODULE_LOCK(this); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) { const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly(); @@ -930,19 +954,19 @@ bool SymbolFileDWARF::ParseCompileUnitSupportFiles( if (stmt_list != DW_INVALID_OFFSET) { // All file indexes in DWARF are one based and a file of index zero is // supposed to be the compile unit itself. - support_files.Append(*sc.comp_unit); + support_files.Append(comp_unit); return DWARFDebugLine::ParseSupportFiles( - sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, - stmt_list, support_files); + comp_unit.GetModule(), get_debug_line_data(), cu_comp_dir, + stmt_list, support_files, dwarf_cu); } } } return false; } -bool SymbolFileDWARF::ParseCompileUnitIsOptimized( - const lldb_private::SymbolContext &sc) { - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); +bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) return dwarf_cu->GetIsOptimized(); return false; @@ -951,6 +975,7 @@ bool SymbolFileDWARF::ParseCompileUnitIsOptimized( bool SymbolFileDWARF::ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector &imported_modules) { + ASSERT_MODULE_LOCK(this); assert(sc.comp_unit); DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); if (dwarf_cu) { @@ -1027,12 +1052,12 @@ static void ParseDWARFLineTableCallback(dw_offset_t offset, } } -bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { - assert(sc.comp_unit); - if (sc.comp_unit->GetLineTable() != NULL) +bool SymbolFileDWARF::ParseLineTable(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); + if (comp_unit.GetLineTable() != NULL) return true; - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) { const DWARFBaseDIE dwarf_cu_die = dwarf_cu->GetUnitDIEOnly(); if (dwarf_cu_die) { @@ -1040,7 +1065,7 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { dwarf_cu_die.GetAttributeValueAsUnsigned(DW_AT_stmt_list, DW_INVALID_OFFSET); if (cu_line_offset != DW_INVALID_OFFSET) { - std::unique_ptr line_table_ap(new LineTable(sc.comp_unit)); + std::unique_ptr line_table_ap(new LineTable(&comp_unit)); if (line_table_ap.get()) { ParseDWARFLineTableCallbackInfo info; info.line_table = line_table_ap.get(); @@ -1053,9 +1078,7 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { * #0 * for MIPS. Use ArchSpec to clear the bit #0. */ - ArchSpec arch; - GetObjectFile()->GetArchitecture(arch); - switch (arch.GetMachine()) { + switch (GetObjectFile()->GetArchitecture().GetMachine()) { case llvm::Triple::mips: case llvm::Triple::mipsel: case llvm::Triple::mips64: @@ -1070,17 +1093,17 @@ bool SymbolFileDWARF::ParseCompileUnitLineTable(const SymbolContext &sc) { lldb::offset_t offset = cu_line_offset; DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, - &info); + &info, dwarf_cu); SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); if (debug_map_symfile) { // We have an object file that has a line table with addresses that // are not linked. We need to link the line table and convert the // addresses that are relative to the .o file into addresses for // the main executable. - sc.comp_unit->SetLineTable( + comp_unit.SetLineTable( debug_map_symfile->LinkOSOLineTable(this, line_table_ap.get())); } else { - sc.comp_unit->SetLineTable(line_table_ap.release()); + comp_unit.SetLineTable(line_table_ap.release()); return true; } } @@ -1112,10 +1135,10 @@ SymbolFileDWARF::ParseDebugMacros(lldb::offset_t *offset) { return debug_macros_sp; } -bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) { - assert(sc.comp_unit); +bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu == nullptr) return false; @@ -1131,16 +1154,14 @@ bool SymbolFileDWARF::ParseCompileUnitDebugMacros(const SymbolContext &sc) { if (sect_offset == DW_INVALID_OFFSET) return false; - sc.comp_unit->SetDebugMacros(ParseDebugMacros(§_offset)); + comp_unit.SetDebugMacros(ParseDebugMacros(§_offset)); return true; } -size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc, - Block *parent_block, - const DWARFDIE &orig_die, - addr_t subprogram_low_pc, - uint32_t depth) { +size_t SymbolFileDWARF::ParseBlocksRecursive( + lldb_private::CompileUnit &comp_unit, Block *parent_block, + const DWARFDIE &orig_die, addr_t subprogram_low_pc, uint32_t depth) { size_t blocks_added = 0; DWARFDIE die = orig_die; while (die) { @@ -1219,13 +1240,13 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc, std::unique_ptr decl_ap; if (decl_file != 0 || decl_line != 0 || decl_column != 0) decl_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), + comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); std::unique_ptr call_ap; if (call_file != 0 || call_line != 0 || call_column != 0) call_ap.reset(new Declaration( - sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), + comp_unit.GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column)); block->SetInlinedFunctionInfo(name, mangled_name, decl_ap.get(), @@ -1235,8 +1256,9 @@ size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc, ++blocks_added; if (die.HasChildren()) { - blocks_added += ParseFunctionBlocks(sc, block, die.GetFirstChild(), - subprogram_low_pc, depth + 1); + blocks_added += + ParseBlocksRecursive(comp_unit, block, die.GetFirstChild(), + subprogram_low_pc, depth + 1); } } } break; @@ -1292,6 +1314,9 @@ void SymbolFileDWARF::ParseDeclsForContext(CompilerDeclContext decl_ctx) { } SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple @@ -1308,6 +1333,9 @@ SymbolFileDWARF *SymbolFileDWARF::GetDWARFForUID(lldb::user_id_t uid) { DWARFDIE SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); // Anytime we get a "lldb::user_id_t" from an lldb_private::SymbolFile API we // must make sure we use the correct DWARF file when resolving things. On // MacOSX, when using SymbolFileDWARFDebugMap, we will use multiple @@ -1322,6 +1350,9 @@ SymbolFileDWARF::GetDIEFromUID(lldb::user_id_t uid) { } CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1333,6 +1364,9 @@ CompilerDecl SymbolFileDWARF::GetDeclForUID(lldb::user_id_t type_uid) { CompilerDeclContext SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1344,6 +1378,9 @@ SymbolFileDWARF::GetDeclContextForUID(lldb::user_id_t type_uid) { CompilerDeclContext SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1354,6 +1391,9 @@ SymbolFileDWARF::GetDeclContextContainingUID(lldb::user_id_t type_uid) { } Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { + // This method can be called without going through the symbol vendor so we + // need to lock the module. + std::lock_guard guard(GetModuleMutex()); // Anytime we have a lldb::user_id_t, we must get the DIE by calling // SymbolFileDWARF::GetDIEFromUID(). See comments inside the // SymbolFileDWARF::GetDIEFromUID() for details. @@ -1364,6 +1404,17 @@ Type *SymbolFileDWARF::ResolveTypeUID(lldb::user_id_t type_uid) { return nullptr; } +llvm::Optional +SymbolFileDWARF::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + std::lock_guard guard(GetModuleMutex()); + DWARFDIE type_die = GetDIEFromUID(type_uid); + if (type_die) + return DWARFASTParser::ParseChildArrayInfo(type_die, exe_ctx); + else + return llvm::None; +} + Type *SymbolFileDWARF::ResolveTypeUID(const DIERef &die_ref) { return ResolveType(GetDIE(die_ref), true); } @@ -1429,8 +1480,7 @@ bool SymbolFileDWARF::HasForwardDeclForClangType( } bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) { - std::lock_guard guard( - GetObjectFile()->GetModule()->GetMutex()); + std::lock_guard guard(GetModuleMutex()); ClangASTContext *clang_type_system = llvm::dyn_cast_or_null(compiler_type.GetTypeSystem()); @@ -1525,7 +1575,7 @@ bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) { sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get(); if (sc.function == NULL) - sc.function = ParseCompileUnitFunction(sc, die); + sc.function = ParseFunction(*sc.comp_unit, die); if (sc.function) { sc.module_sp = sc.function->CalculateSymbolContextModule(); @@ -1578,18 +1628,20 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( return dwo_symfile; } - FileSpec dwo_file(dwo_name, true); + FileSpec dwo_file(dwo_name); + FileSystem::Instance().Resolve(dwo_file); if (dwo_file.IsRelative()) { const char *comp_dir = cu_die.GetAttributeValueAsString( this, &dwarf_cu, DW_AT_comp_dir, nullptr); if (!comp_dir) return nullptr; - dwo_file.SetFile(comp_dir, true, FileSpec::Style::native); + dwo_file.SetFile(comp_dir, FileSpec::Style::native); + FileSystem::Instance().Resolve(dwo_file); dwo_file.AppendPathComponent(dwo_name); } - if (!dwo_file.Exists()) + if (!FileSystem::Instance().Exists(dwo_file)) return nullptr; const lldb::offset_t file_offset = 0; @@ -1597,7 +1649,8 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( lldb::offset_t dwo_file_data_offset = 0; ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin( GetObjectFile()->GetModule(), &dwo_file, file_offset, - dwo_file.GetByteSize(), dwo_file_data_sp, dwo_file_data_offset); + FileSystem::Instance().GetByteSize(dwo_file), dwo_file_data_sp, + dwo_file_data_offset); if (dwo_obj_file == nullptr) return nullptr; @@ -1616,7 +1669,7 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { DWARFUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); const DWARFBaseDIE die = dwarf_cu->GetUnitDIEOnly(); - if (die && die.HasChildren() == false) { + if (die && !die.HasChildren()) { const char *name = die.GetAttributeValueAsString(DW_AT_name, nullptr); if (name) { @@ -1628,14 +1681,15 @@ void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() { die.GetAttributeValueAsString(DW_AT_GNU_dwo_name, nullptr); if (dwo_path) { ModuleSpec dwo_module_spec; - dwo_module_spec.GetFileSpec().SetFile(dwo_path, false, + dwo_module_spec.GetFileSpec().SetFile(dwo_path, FileSpec::Style::native); if (dwo_module_spec.GetFileSpec().IsRelative()) { const char *comp_dir = die.GetAttributeValueAsString(DW_AT_comp_dir, nullptr); if (comp_dir) { - dwo_module_spec.GetFileSpec().SetFile(comp_dir, true, + dwo_module_spec.GetFileSpec().SetFile(comp_dir, FileSpec::Style::native); + FileSystem::Instance().Resolve(dwo_module_spec.GetFileSpec()); dwo_module_spec.GetFileSpec().AppendPathComponent(dwo_path); } } @@ -1726,7 +1780,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { } uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, - uint32_t resolve_scope, + SymbolContextItem resolve_scope, SymbolContext &sc) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, @@ -1784,7 +1838,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, sc.function = sc.comp_unit->FindFunctionByUID(function_die.GetID()).get(); if (sc.function == NULL) - sc.function = ParseCompileUnitFunction(sc, function_die); + sc.function = ParseFunction(*sc.comp_unit, function_die); if (sc.function && (resolve_scope & eSymbolContextBlock)) block_die = function_die.LookupDeepestBlock(file_vm_addr); @@ -1860,7 +1914,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const Address &so_addr, uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { const uint32_t prev_size = sc_list.GetSize(); if (resolve_scope & eSymbolContextCompUnit) { @@ -1925,7 +1979,7 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, .get(); if (sc.function == NULL) sc.function = - ParseCompileUnitFunction(sc, function_die); + ParseFunction(*sc.comp_unit, function_die); if (sc.function && (resolve_scope & eSymbolContextBlock)) @@ -1975,11 +2029,17 @@ uint32_t SymbolFileDWARF::ResolveSymbolContext(const FileSpec &file_spec, } void SymbolFileDWARF::PreloadSymbols() { - std::lock_guard guard( - GetObjectFile()->GetModule()->GetMutex()); + std::lock_guard guard(GetModuleMutex()); m_index->Preload(); } +std::recursive_mutex &SymbolFileDWARF::GetModuleMutex() const { + lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); + if (module_sp) + return module_sp->GetMutex(); + return GetObjectFile()->GetModule()->GetMutex(); +} + bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( const lldb_private::CompilerDeclContext *decl_ctx) { if (decl_ctx == nullptr || !decl_ctx->IsValid()) { @@ -2195,7 +2255,7 @@ bool SymbolFileDWARF::ResolveFunction(const DWARFDIE &orig_die, sc.block = function_block.FindBlockByID(inlined_die.GetID()); if (sc.block == NULL) sc.block = function_block.FindBlockByID(inlined_die.GetOffset()); - if (sc.block == NULL || sc.block->GetStartAddress(addr) == false) + if (sc.block == NULL || !sc.block->GetStartAddress(addr)) addr.Clear(); } else { sc.block = NULL; @@ -2231,11 +2291,10 @@ bool SymbolFileDWARF::DIEInDeclContext(const CompilerDeclContext *decl_ctx, return false; } -uint32_t -SymbolFileDWARF::FindFunctions(const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, - bool append, SymbolContextList &sc_list) { +uint32_t SymbolFileDWARF::FindFunctions( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + FunctionNameType name_type_mask, bool include_inlines, bool append, + SymbolContextList &sc_list) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, "SymbolFileDWARF::FindFunctions (name = '%s')", name.AsCString()); @@ -2378,9 +2437,8 @@ void SymbolFileDWARF::GetMangledNamesForFunction( } uint32_t SymbolFileDWARF::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { // If we aren't appending the results to this list, then clear the list @@ -2469,8 +2527,8 @@ uint32_t SymbolFileDWARF::FindTypes( SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor(); if (sym_vendor) { const uint32_t num_external_matches = - sym_vendor->FindTypes(sc, name, parent_decl_ctx, append, - max_matches, searched_symbol_files, types); + sym_vendor->FindTypes(name, parent_decl_ctx, append, max_matches, + searched_symbol_files, types); if (num_external_matches) return num_external_matches; } @@ -2506,7 +2564,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector &context, if (die) { std::vector die_context; - die.GetDWOContext(die_context); + die.GetDeclContext(die_context); if (die_context != context) continue; @@ -2528,7 +2586,7 @@ size_t SymbolFileDWARF::FindTypes(const std::vector &context, } CompilerDeclContext -SymbolFileDWARF::FindNamespace(const SymbolContext &sc, const ConstString &name, +SymbolFileDWARF::FindNamespace(const ConstString &name, const CompilerDeclContext *parent_decl_ctx) { Log *log(LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS)); @@ -3065,39 +3123,36 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc, return types_added; } -size_t SymbolFileDWARF::ParseFunctionBlocks(const SymbolContext &sc) { - assert(sc.comp_unit && sc.function); +size_t SymbolFileDWARF::ParseBlocksRecursive(Function &func) { + ASSERT_MODULE_LOCK(this); + CompileUnit *comp_unit = func.GetCompileUnit(); + lldbassert(comp_unit); + + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit); + if (!dwarf_cu) + return 0; + size_t functions_added = 0; - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); - if (dwarf_cu) { - const dw_offset_t function_die_offset = sc.function->GetID(); - DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset); - if (function_die) { - ParseFunctionBlocks(sc, &sc.function->GetBlock(false), function_die, - LLDB_INVALID_ADDRESS, 0); - } + const dw_offset_t function_die_offset = func.GetID(); + DWARFDIE function_die = dwarf_cu->GetDIE(function_die_offset); + if (function_die) { + ParseBlocksRecursive(*comp_unit, &func.GetBlock(false), function_die, + LLDB_INVALID_ADDRESS, 0); } return functions_added; } -size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) { - // At least a compile unit must be valid - assert(sc.comp_unit); +size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) { + ASSERT_MODULE_LOCK(this); size_t types_added = 0; - DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit); if (dwarf_cu) { - if (sc.function) { - dw_offset_t function_die_offset = sc.function->GetID(); - DWARFDIE func_die = dwarf_cu->GetDIE(function_die_offset); - if (func_die && func_die.HasChildren()) { - types_added = ParseTypes(sc, func_die.GetFirstChild(), true, true); - } - } else { - DWARFDIE dwarf_cu_die = dwarf_cu->DIE(); - if (dwarf_cu_die && dwarf_cu_die.HasChildren()) { - types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true); - } + DWARFDIE dwarf_cu_die = dwarf_cu->DIE(); + if (dwarf_cu_die && dwarf_cu_die.HasChildren()) { + SymbolContext sc; + sc.comp_unit = &comp_unit; + types_added = ParseTypes(sc, dwarf_cu_die.GetFirstChild(), true, true); } } @@ -3105,6 +3160,7 @@ size_t SymbolFileDWARF::ParseTypes(const SymbolContext &sc) { } size_t SymbolFileDWARF::ParseVariablesForContext(const SymbolContext &sc) { + ASSERT_MODULE_LOCK(this); if (sc.comp_unit != NULL) { DWARFDebugInfo *info = DebugInfo(); if (info == NULL) @@ -3298,7 +3354,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, uint32_t block_length = form_value.Unsigned(); location.CopyOpcodeData(module, data, block_offset, block_length); } else { - const DWARFDataExtractor &debug_loc_data = get_debug_loc_data(); + const DWARFDataExtractor &debug_loc_data = DebugLocData(); const dw_offset_t debug_loc_offset = form_value.Unsigned(); size_t loc_list_length = DWARFExpression::LocationListSize( @@ -3319,22 +3375,10 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, case DW_AT_start_scope: { if (form_value.Form() == DW_FORM_sec_offset) { DWARFRangeList dwarf_scope_ranges; - const DWARFDebugRanges *debug_ranges = DebugRanges(); - debug_ranges->FindRanges(die.GetCU()->GetRangesBase(), + const DWARFDebugRangesBase *debug_ranges = DebugRanges(); + debug_ranges->FindRanges(die.GetCU(), form_value.Unsigned(), dwarf_scope_ranges); - - // All DW_AT_start_scope are relative to the base address of the - // compile unit. We add the compile unit base address to make - // sure all the addresses are properly fixed up. - for (size_t i = 0, count = dwarf_scope_ranges.GetSize(); - i < count; ++i) { - const DWARFRangeList::Entry &range = - dwarf_scope_ranges.GetEntryRef(i); - scope_ranges.Append(range.GetRangeBase() + - die.GetCU()->GetBaseAddress(), - range.GetByteSize()); - } } else { // TODO: Handle the case when DW_AT_start_scope have form // constant. The @@ -3436,6 +3480,11 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, is_static_lifetime = true; } SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile(); + if (debug_map_symfile) + // Set the module of the expression to the linked module + // instead of the oject file so the relocated address can be + // found there. + location.SetModule(debug_map_symfile->GetObjectFile()->GetModule()); if (is_static_lifetime) { if (is_external) @@ -3736,6 +3785,60 @@ size_t SymbolFileDWARF::ParseVariables(const SymbolContext &sc, return vars_added; } +/// Collect call graph edges present in a function DIE. +static std::vector +CollectCallEdges(DWARFDIE function_die) { + // Check if the function has a supported call site-related attribute. + // TODO: In the future it may be worthwhile to support call_all_source_calls. + uint64_t has_call_edges = + function_die.GetAttributeValueAsUnsigned(DW_AT_call_all_calls, 0); + if (!has_call_edges) + return {}; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + LLDB_LOG(log, "CollectCallEdges: Found call site info in {0}", + function_die.GetPubname()); + + // Scan the DIE for TAG_call_site entries. + // TODO: A recursive scan of all blocks in the subprogram is needed in order + // to be DWARF5-compliant. This may need to be done lazily to be performant. + // For now, assume that all entries are nested directly under the subprogram + // (this is the kind of DWARF LLVM produces) and parse them eagerly. + std::vector call_edges; + for (DWARFDIE child = function_die.GetFirstChild(); child.IsValid(); + child = child.GetSibling()) { + if (child.Tag() != DW_TAG_call_site) + continue; + + // Extract DW_AT_call_origin (the call target's DIE). + DWARFDIE call_origin = child.GetReferencedDIE(DW_AT_call_origin); + if (!call_origin.IsValid()) { + LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}", + function_die.GetPubname()); + continue; + } + + // Extract DW_AT_call_return_pc (the PC the call returns to) if it's + // available. It should only ever be unavailable for tail call edges, in + // which case use LLDB_INVALID_ADDRESS. + addr_t return_pc = child.GetAttributeValueAsAddress(DW_AT_call_return_pc, + LLDB_INVALID_ADDRESS); + + LLDB_LOG(log, "CollectCallEdges: Found call origin: {0} (retn-PC: {1:x})", + call_origin.GetPubname(), return_pc); + call_edges.emplace_back(call_origin.GetMangledName(), return_pc); + } + return call_edges; +} + +std::vector +SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { + DWARFDIE func_die = GetDIEFromUID(func_id.GetID()); + if (func_die.IsValid()) + return CollectCallEdges(func_die); + return {}; +} + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -3745,6 +3848,14 @@ uint32_t SymbolFileDWARF::GetPluginVersion() { return 1; } void SymbolFileDWARF::Dump(lldb_private::Stream &s) { m_index->Dump(s); } +void SymbolFileDWARF::DumpClangAST(Stream &s) { + TypeSystem *ts = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); + ClangASTContext *clang = llvm::dyn_cast_or_null(ts); + if (!clang) + return; + clang->Dump(s); +} + SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired()) { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); @@ -3760,6 +3871,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { DWARFExpression::LocationListFormat SymbolFileDWARF::GetLocationListFormat() const { + if (m_data_debug_loclists.m_data.GetByteSize() > 0) + return DWARFExpression::LocLists; return DWARFExpression::RegularLocationList; } @@ -3768,9 +3881,9 @@ SymbolFileDWARFDwp *SymbolFileDWARF::GetDwpSymbolFile() { ModuleSpec module_spec; module_spec.GetFileSpec() = m_obj_file->GetFileSpec(); module_spec.GetSymbolFileSpec() = - FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp", false); + FileSpec(m_obj_file->GetFileSpec().GetPath() + ".dwp"); FileSpec dwp_filespec = Symbols::LocateExecutableSymbolFile(module_spec); - if (dwp_filespec.Exists()) { + if (FileSystem::Instance().Exists(dwp_filespec)) { m_dwp_symfile = SymbolFileDWARFDwp::Create(GetObjectFile()->GetModule(), dwp_filespec); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index a5f2ac8f3e7d..d351289f8b51 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -10,8 +10,6 @@ #ifndef SymbolFileDWARF_SymbolFileDWARF_h_ #define SymbolFileDWARF_SymbolFileDWARF_h_ -// C Includes -// C++ Includes #include #include #include @@ -19,7 +17,6 @@ #include #include -// Other libraries and framework includes #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Threading.h" @@ -35,7 +32,6 @@ #include "lldb/Utility/ConstString.h" #include "lldb/lldb-private.h" -// Project includes #include "DWARFDataExtractor.h" #include "DWARFDefines.h" #include "DWARFIndex.h" @@ -53,7 +49,7 @@ class DWARFDebugAranges; class DWARFDebugInfo; class DWARFDebugInfoEntry; class DWARFDebugLine; -class DWARFDebugRanges; +class DWARFDebugRangesBase; class DWARFDeclContext; class DWARFDIECollection; class DWARFFormValue; @@ -73,9 +69,6 @@ public: friend class DWARFUnit; friend class DWARFDIE; friend class DWARFASTParserClang; - friend class DWARFASTParserGo; - friend class DWARFASTParserJava; - friend class DWARFASTParserOCaml; //------------------------------------------------------------------ // Static Functions @@ -114,36 +107,34 @@ public: lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; + ParseLanguage(lldb_private::CompileUnit &comp_unit) override; - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; + bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; - bool - ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; + bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; - bool ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) override; + bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, + lldb_private::FileSpecList &support_files) override; - bool - ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override; + bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override; + + size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; bool ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector &imported_modules) override; - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - - size_t ParseTypes(const lldb_private::SymbolContext &sc) override; + size_t ParseBlocksRecursive(lldb_private::Function &func) override; size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; @@ -168,12 +159,13 @@ public: ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; uint32_t ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, uint32_t resolve_scope, + bool check_inlines, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) override; uint32_t @@ -189,8 +181,8 @@ public: uint32_t FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) override; + lldb::FunctionNameType name_type_mask, bool include_inlines, + bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, @@ -201,8 +193,7 @@ public: std::vector &mangled_names) override; uint32_t - FindTypes(const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, + FindTypes(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, @@ -214,19 +205,20 @@ public: lldb_private::TypeList *GetTypeList() override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; lldb_private::TypeSystem * GetTypeSystemForLanguage(lldb::LanguageType language) override; lldb_private::CompilerDeclContext FindNamespace( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx) override; void PreloadSymbols() override; + std::recursive_mutex &GetModuleMutex() const override; + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ @@ -234,17 +226,20 @@ public: uint32_t GetPluginVersion() override; - const lldb_private::DWARFDataExtractor &get_debug_abbrev_data(); - const lldb_private::DWARFDataExtractor &get_debug_addr_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_abbrev_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_addr_data(); const lldb_private::DWARFDataExtractor &get_debug_aranges_data(); const lldb_private::DWARFDataExtractor &get_debug_frame_data(); - const lldb_private::DWARFDataExtractor &get_debug_info_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_info_data(); const lldb_private::DWARFDataExtractor &get_debug_line_data(); + const lldb_private::DWARFDataExtractor &get_debug_line_str_data(); const lldb_private::DWARFDataExtractor &get_debug_macro_data(); const lldb_private::DWARFDataExtractor &get_debug_loc_data(); + const lldb_private::DWARFDataExtractor &get_debug_loclists_data(); const lldb_private::DWARFDataExtractor &get_debug_ranges_data(); - const lldb_private::DWARFDataExtractor &get_debug_str_data(); - const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data(); + const lldb_private::DWARFDataExtractor &get_debug_rnglists_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_str_data(); + virtual const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data(); const lldb_private::DWARFDataExtractor &get_debug_types_data(); const lldb_private::DWARFDataExtractor &get_apple_names_data(); const lldb_private::DWARFDataExtractor &get_apple_types_data(); @@ -260,9 +255,11 @@ public: const DWARFDebugInfo *DebugInfo() const; - DWARFDebugRanges *DebugRanges(); + DWARFDebugRangesBase *DebugRanges(); - const DWARFDebugRanges *DebugRanges() const; + const DWARFDebugRangesBase *DebugRanges() const; + + const lldb_private::DWARFDataExtractor &DebugLocData(); static bool SupportedVersion(uint16_t version); @@ -316,8 +313,13 @@ public: DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx, const DWARFDIE &die); + std::vector + ParseCallEdgesInFunction(UserID func_id) override; + void Dump(lldb_private::Stream &s) override; + void DumpClangAST(lldb_private::Stream &s) override; + protected: typedef llvm::DenseMap DIEToTypePtr; @@ -352,14 +354,13 @@ protected: bool GetFunction(const DWARFDIE &die, lldb_private::SymbolContext &sc); - lldb_private::Function * - ParseCompileUnitFunction(const lldb_private::SymbolContext &sc, - const DWARFDIE &die); + lldb_private::Function *ParseFunction(lldb_private::CompileUnit &comp_unit, + const DWARFDIE &die); - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc, - lldb_private::Block *parent_block, - const DWARFDIE &die, - lldb::addr_t subprogram_low_pc, uint32_t depth); + size_t ParseBlocksRecursive(lldb_private::CompileUnit &comp_unit, + lldb_private::Block *parent_block, + const DWARFDIE &die, + lldb::addr_t subprogram_low_pc, uint32_t depth); size_t ParseTypes(const lldb_private::SymbolContext &sc, const DWARFDIE &die, bool parse_siblings, bool parse_children); @@ -466,9 +467,12 @@ protected: DWARFDataSegment m_data_debug_frame; DWARFDataSegment m_data_debug_info; DWARFDataSegment m_data_debug_line; + DWARFDataSegment m_data_debug_line_str; DWARFDataSegment m_data_debug_macro; DWARFDataSegment m_data_debug_loc; + DWARFDataSegment m_data_debug_loclists; DWARFDataSegment m_data_debug_ranges; + DWARFDataSegment m_data_debug_rnglists; DWARFDataSegment m_data_debug_str; DWARFDataSegment m_data_debug_str_offsets; DWARFDataSegment m_data_debug_types; @@ -498,7 +502,7 @@ protected: typedef std::shared_ptr> DIERefSetSP; typedef std::unordered_map NameToOffsetMap; NameToOffsetMap m_function_scope_qualified_name_map; - std::unique_ptr m_ranges; + std::unique_ptr m_ranges; UniqueDWARFASTTypeMap m_unique_ast_type_map; DIEToTypePtr m_die_to_type; DIEToVariableSP m_die_to_variable_sp; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 39c70d146524..2c1e6416a935 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "SymbolFileDWARFDebugMap.h" #include "DWARFDebugAranges.h" @@ -90,11 +86,10 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap( const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1; for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO - idx < oso_end_idx; - ++idx) { + idx < oso_end_idx; ++idx) { Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx); if (exe_symbol) { - if (exe_symbol->IsDebug() == false) + if (!exe_symbol->IsDebug()) continue; switch (exe_symbol->GetType()) { @@ -184,7 +179,7 @@ public: GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL) override { // Scope for locker - if (m_symfile_ap.get() || can_create == false) + if (m_symfile_ap.get() || !can_create) return m_symfile_ap.get(); ModuleSP exe_module_sp(m_exe_module_wp.lock()); @@ -351,7 +346,7 @@ void SymbolFileDWARFDebugMap::InitOSO() { so_symbol->GetType() == eSymbolTypeSourceFile && oso_symbol->GetType() == eSymbolTypeObjectFile) { m_compile_unit_infos[i].so_file.SetFile( - so_symbol->GetName().AsCString(), false, FileSpec::Style::native); + so_symbol->GetName().AsCString(), FileSpec::Style::native); m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); m_compile_unit_infos[i].oso_mod_time = llvm::sys::toTimePoint(oso_symbol->GetIntegerValue(0)); @@ -421,10 +416,13 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( m_oso_map[{comp_unit_info->oso_path, comp_unit_info->oso_mod_time}] = comp_unit_info->oso_sp; const char *oso_path = comp_unit_info->oso_path.GetCString(); - FileSpec oso_file(oso_path, false); + FileSpec oso_file(oso_path); ConstString oso_object; - if (oso_file.Exists()) { - auto oso_mod_time = FileSystem::GetModificationTime(oso_file); + if (FileSystem::Instance().Exists(oso_file)) { + // The modification time returned by the FS can have a higher precision + // than the one from the CU. + auto oso_mod_time = std::chrono::time_point_cast( + FileSystem::Instance().GetModificationTime(oso_file)); if (oso_mod_time != comp_unit_info->oso_mod_time) { obj_file->GetModule()->ReportError( "debug map object file '%s' has changed (actual time is " @@ -490,7 +488,12 @@ ObjectFile *SymbolFileDWARFDebugMap::GetObjectFileByOSOIndex(uint32_t oso_idx) { SymbolFileDWARF * SymbolFileDWARFDebugMap::GetSymbolFile(const SymbolContext &sc) { - CompileUnitInfo *comp_unit_info = GetCompUnitInfo(sc); + return GetSymbolFile(*sc.comp_unit); +} + +SymbolFileDWARF * +SymbolFileDWARFDebugMap::GetSymbolFile(const CompileUnit &comp_unit) { + CompileUnitInfo *comp_unit_info = GetCompUnitInfo(comp_unit); if (comp_unit_info) return GetSymbolFileByCompUnitInfo(comp_unit_info); return NULL; @@ -518,7 +521,8 @@ uint32_t SymbolFileDWARFDebugMap::GetCompUnitInfoIndex( SymbolFileDWARF * SymbolFileDWARFDebugMap::GetSymbolFileByOSOIndex(uint32_t oso_idx) { - if (oso_idx < m_compile_unit_infos.size()) + unsigned size = m_compile_unit_infos.size(); + if (oso_idx < size) return GetSymbolFileByCompUnitInfo(&m_compile_unit_infos[oso_idx]); return NULL; } @@ -597,9 +601,14 @@ CompUnitSP SymbolFileDWARFDebugMap::ParseCompileUnitAtIndex(uint32_t cu_idx) { SymbolFileDWARFDebugMap::CompileUnitInfo * SymbolFileDWARFDebugMap::GetCompUnitInfo(const SymbolContext &sc) { + return GetCompUnitInfo(*sc.comp_unit); +} + +SymbolFileDWARFDebugMap::CompileUnitInfo * +SymbolFileDWARFDebugMap::GetCompUnitInfo(const CompileUnit &comp_unit) { const uint32_t cu_count = GetNumCompileUnits(); for (uint32_t i = 0; i < cu_count; ++i) { - if (sc.comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) + if (comp_unit == m_compile_unit_infos[i].compile_unit_sp.get()) return &m_compile_unit_infos[i]; } return NULL; @@ -617,50 +626,46 @@ size_t SymbolFileDWARFDebugMap::GetCompUnitInfosForModule( } lldb::LanguageType -SymbolFileDWARFDebugMap::ParseCompileUnitLanguage(const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +SymbolFileDWARFDebugMap::ParseLanguage(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitLanguage(sc); + return oso_dwarf->ParseLanguage(comp_unit); return eLanguageTypeUnknown; } -size_t -SymbolFileDWARFDebugMap::ParseCompileUnitFunctions(const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +size_t SymbolFileDWARFDebugMap::ParseFunctions(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitFunctions(sc); + return oso_dwarf->ParseFunctions(comp_unit); return 0; } -bool SymbolFileDWARFDebugMap::ParseCompileUnitLineTable( - const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +bool SymbolFileDWARFDebugMap::ParseLineTable(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitLineTable(sc); + return oso_dwarf->ParseLineTable(comp_unit); return false; } -bool SymbolFileDWARFDebugMap::ParseCompileUnitDebugMacros( - const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +bool SymbolFileDWARFDebugMap::ParseDebugMacros(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitDebugMacros(sc); + return oso_dwarf->ParseDebugMacros(comp_unit); return false; } -bool SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles( - const SymbolContext &sc, FileSpecList &support_files) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +bool SymbolFileDWARFDebugMap::ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitSupportFiles(sc, support_files); + return oso_dwarf->ParseSupportFiles(comp_unit, support_files); return false; } -bool SymbolFileDWARFDebugMap::ParseCompileUnitIsOptimized( - const lldb_private::SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +bool SymbolFileDWARFDebugMap::ParseIsOptimized(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseCompileUnitIsOptimized(sc); + return oso_dwarf->ParseIsOptimized(comp_unit); return false; } @@ -672,17 +677,21 @@ bool SymbolFileDWARFDebugMap::ParseImportedModules( return false; } -size_t SymbolFileDWARFDebugMap::ParseFunctionBlocks(const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +size_t SymbolFileDWARFDebugMap::ParseBlocksRecursive(Function &func) { + CompileUnit *comp_unit = func.GetCompileUnit(); + if (!comp_unit) + return 0; + + SymbolFileDWARF *oso_dwarf = GetSymbolFile(*comp_unit); if (oso_dwarf) - return oso_dwarf->ParseFunctionBlocks(sc); + return oso_dwarf->ParseBlocksRecursive(func); return 0; } -size_t SymbolFileDWARFDebugMap::ParseTypes(const SymbolContext &sc) { - SymbolFileDWARF *oso_dwarf = GetSymbolFile(sc); +size_t SymbolFileDWARFDebugMap::ParseTypes(CompileUnit &comp_unit) { + SymbolFileDWARF *oso_dwarf = GetSymbolFile(comp_unit); if (oso_dwarf) - return oso_dwarf->ParseTypes(sc); + return oso_dwarf->ParseTypes(comp_unit); return 0; } @@ -702,6 +711,16 @@ Type *SymbolFileDWARFDebugMap::ResolveTypeUID(lldb::user_id_t type_uid) { return NULL; } +llvm::Optional +SymbolFileDWARFDebugMap::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + const uint64_t oso_idx = GetOSOIndexFromUserID(type_uid); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->GetDynamicArrayInfoForUID(type_uid, exe_ctx); + return llvm::None; +} + bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { bool success = false; if (compiler_type) { @@ -717,8 +736,10 @@ bool SymbolFileDWARFDebugMap::CompleteType(CompilerType &compiler_type) { return success; } -uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( - const Address &exe_so_addr, uint32_t resolve_scope, SymbolContext &sc) { +uint32_t +SymbolFileDWARFDebugMap::ResolveSymbolContext(const Address &exe_so_addr, + SymbolContextItem resolve_scope, + SymbolContext &sc) { uint32_t resolved_flags = 0; Symtab *symtab = m_obj_file->GetSymtab(); if (symtab) { @@ -760,7 +781,7 @@ uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( uint32_t SymbolFileDWARFDebugMap::ResolveSymbolContext( const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, SymbolContextList &sc_list) { + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { const uint32_t initial = sc_list.GetSize(); const uint32_t cu_count = GetNumCompileUnits(); @@ -792,8 +813,7 @@ uint32_t SymbolFileDWARFDebugMap::PrivateFindGlobalVariables( const ConstString &name, const CompilerDeclContext *parent_decl_ctx, const std::vector &indexes, // Indexes into the symbol table that match "name" - uint32_t max_matches, - VariableList &variables) { + uint32_t max_matches, VariableList &variables) { const uint32_t original_size = variables.GetSize(); const size_t match_count = indexes.size(); for (size_t i = 0; i < match_count; ++i) { @@ -977,7 +997,7 @@ static void RemoveFunctionsWithModuleNotEqualTo(const ModuleSP &module_sp, uint32_t SymbolFileDWARFDebugMap::FindFunctions( const ConstString &name, const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, + FunctionNameType name_type_mask, bool include_inlines, bool append, SymbolContextList &sc_list) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, @@ -1032,7 +1052,7 @@ uint32_t SymbolFileDWARFDebugMap::FindFunctions(const RegularExpression ®ex, } size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, TypeList &type_list) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, @@ -1060,6 +1080,15 @@ size_t SymbolFileDWARFDebugMap::GetTypes(SymbolContextScope *sc_scope, return type_list.GetSize() - initial_size; } +std::vector +SymbolFileDWARFDebugMap::ParseCallEdgesInFunction(UserID func_id) { + uint32_t oso_idx = GetOSOIndexFromUserID(func_id.GetID()); + SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex(oso_idx); + if (oso_dwarf) + return oso_dwarf->ParseCallEdgesInFunction(func_id); + return {}; +} + TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext( const DWARFDeclContext &die_decl_ctx) { TypeSP type_sp; @@ -1136,7 +1165,7 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( // Only search all .o files for the definition if we don't need the // implementation because otherwise, with a valid debug map we should have // the ObjC class symbol and the code above should have found it. - if (must_be_implementation == false) { + if (!must_be_implementation) { TypeSP type_sp; ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { @@ -1151,32 +1180,20 @@ TypeSP SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE( } uint32_t SymbolFileDWARFDebugMap::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { if (!append) types.Clear(); const uint32_t initial_types_size = types.GetSize(); - SymbolFileDWARF *oso_dwarf; - if (sc.comp_unit) { - oso_dwarf = GetSymbolFile(sc); - if (oso_dwarf) - return oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, - max_matches, searched_symbol_files, types); - } else { - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, max_matches, - searched_symbol_files, types); - if (types.GetSize() >= max_matches) - return true; - else - return false; - }); - } + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + oso_dwarf->FindTypes(name, parent_decl_ctx, append, max_matches, + searched_symbol_files, types); + return types.GetSize() >= max_matches; + }); return types.GetSize() - initial_types_size; } @@ -1195,27 +1212,26 @@ uint32_t SymbolFileDWARFDebugMap::FindTypes( //} CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const CompilerDeclContext *parent_decl_ctx) { CompilerDeclContext matching_namespace; - SymbolFileDWARF *oso_dwarf; - if (sc.comp_unit) { - oso_dwarf = GetSymbolFile(sc); - if (oso_dwarf) - matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx); - } else { - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - matching_namespace = oso_dwarf->FindNamespace(sc, name, parent_decl_ctx); + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + matching_namespace = oso_dwarf->FindNamespace(name, parent_decl_ctx); - return (bool)matching_namespace; - }); - } + return (bool)matching_namespace; + }); return matching_namespace; } +void SymbolFileDWARFDebugMap::DumpClangAST(Stream &s) { + ForEachSymbolFile([&s](SymbolFileDWARF *oso_dwarf) -> bool { + oso_dwarf->DumpClangAST(s); + return true; + }); +} + //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 550f74a203ea..176eadeeca71 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -56,27 +56,33 @@ public: lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; - bool - ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; - bool ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) override; - bool - ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) override; + ParseLanguage(lldb_private::CompileUnit &comp_unit) override; + + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; + + bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; + + bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; + + bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, + lldb_private::FileSpecList &support_files) override; + + bool ParseIsOptimized(lldb_private::CompileUnit &comp_unit) override; + + size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; + bool ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector &imported_modules) override; - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - size_t ParseTypes(const lldb_private::SymbolContext &sc) override; + size_t ParseBlocksRecursive(lldb_private::Function &func) override; size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; + lldb_private::CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override; lldb_private::CompilerDeclContext @@ -86,11 +92,12 @@ public: bool CompleteType(lldb_private::CompilerType &compiler_type) override; uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; uint32_t ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, uint32_t resolve_scope, + bool check_inlines, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) override; uint32_t FindGlobalVariables(const lldb_private::ConstString &name, @@ -103,25 +110,27 @@ public: uint32_t FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) override; + lldb::FunctionNameType name_type_mask, bool include_inlines, + bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t - FindTypes(const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, + FindTypes(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; lldb_private::CompilerDeclContext FindNamespace( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx) override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; + std::vector + ParseCallEdgesInFunction(lldb_private::UserID func_id) override; + + void DumpClangAST(lldb_private::Stream &s) override; //------------------------------------------------------------------ // PluginInterface protocol @@ -189,6 +198,7 @@ protected: bool GetFileSpecForSO(uint32_t oso_idx, lldb_private::FileSpec &file_spec); CompileUnitInfo *GetCompUnitInfo(const lldb_private::SymbolContext &sc); + CompileUnitInfo *GetCompUnitInfo(const lldb_private::CompileUnit &comp_unit); size_t GetCompUnitInfosForModule(const lldb_private::Module *oso_module, std::vector &cu_infos); @@ -206,6 +216,7 @@ protected: uint32_t GetCompUnitInfoIndex(const CompileUnitInfo *comp_unit_info); SymbolFileDWARF *GetSymbolFile(const lldb_private::SymbolContext &sc); + SymbolFileDWARF *GetSymbolFile(const lldb_private::CompileUnit &comp_unit); SymbolFileDWARF *GetSymbolFileByCompUnitInfo(CompileUnitInfo *comp_unit_info); diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp index 15fe362fa117..7881448535b8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp @@ -61,14 +61,6 @@ SymbolFileDWARFDwo::ParseCompileUnit(DWARFUnit *dwarf_cu, } DWARFUnit *SymbolFileDWARFDwo::GetCompileUnit() { - // A clang module is found via a skeleton CU, but is not a proper DWO. - // Clang modules have a .debug_info section instead of the *_dwo variant. - if (auto *section_list = m_obj_file->GetSectionList(false)) - if (auto section_sp = - section_list->FindSectionByType(eSectionTypeDWARFDebugInfo, true)) - if (!section_sp->GetName().GetStringRef().endswith("dwo")) - return nullptr; - // Only dwo files with 1 compile unit is supported if (GetNumCompileUnits() == 1) return DebugInfo()->GetCompileUnitAtIndex(0); @@ -126,6 +118,37 @@ DWARFUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() { return m_base_dwarf_cu; } +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_abbrev_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugAbbrevDwo, + m_data_debug_abbrev); +} + +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_addr_data() { + // For single file split dwarf case (when we have .dwo sections in a .o), + // we do not want to use the .debug_addr section from .o file, + // but want to get one from the final executable. + // For regular split debug case, .dwo file does not contain the + // .debug_addr, so we would always fall back to such lookup anyways. + llvm::call_once(m_data_debug_addr.m_flag, [this] { + SymbolFileDWARF::LoadSectionData(eSectionTypeDWARFDebugAddr, + std::ref(m_data_debug_addr.m_data)); + }); + return m_data_debug_addr.m_data; +} + +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_info_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugInfoDwo, m_data_debug_info); +} + +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugStrDwo, m_data_debug_str); +} + +const DWARFDataExtractor &SymbolFileDWARFDwo::get_debug_str_offsets_data() { + return GetCachedSectionData(eSectionTypeDWARFDebugStrOffsetsDwo, + m_data_debug_str_offsets); +} + SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() { return m_base_dwarf_cu->GetSymbolFileDWARF(); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h index 483a19512a36..b9ed37547aca 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h @@ -10,10 +10,6 @@ #ifndef SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ #define SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "SymbolFileDWARF.h" class SymbolFileDWARFDwo : public SymbolFileDWARF { @@ -50,6 +46,12 @@ public: DWARFUnit *GetBaseCompileUnit() override; + const lldb_private::DWARFDataExtractor &get_debug_abbrev_data() override; + const lldb_private::DWARFDataExtractor &get_debug_addr_data() override; + const lldb_private::DWARFDataExtractor &get_debug_info_data() override; + const lldb_private::DWARFDataExtractor &get_debug_str_data() override; + const lldb_private::DWARFDataExtractor &get_debug_str_offsets_data() override; + protected: void LoadSectionData(lldb::SectionType sect_type, lldb_private::DWARFDataExtractor &data) override; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h index b1b505b5899f..905ba0a5c7b8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h @@ -10,10 +10,6 @@ #ifndef SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ #define SymbolFileDWARFDwoDwp_SymbolFileDWARFDwoDwp_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "SymbolFileDWARFDwo.h" #include "SymbolFileDWARFDwp.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp index ae10e7179e33..73226dfc130f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp @@ -9,10 +9,6 @@ #include "SymbolFileDWARFDwp.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" @@ -30,7 +26,7 @@ lldbSectTypeToLlvmSectionKind(lldb::SectionType type) { case lldb::eSectionTypeDWARFDebugLine: return llvm::DW_SECT_LINE; case lldb::eSectionTypeDWARFDebugLoc: - return llvm::DW_SECT_LOC; + return llvm::DW_SECT_LOC; case lldb::eSectionTypeDWARFDebugStrOffsets: return llvm::DW_SECT_STR_OFFSETS; // case lldb::eSectionTypeDWARFDebugMacinfo: @@ -50,7 +46,8 @@ SymbolFileDWARFDwp::Create(lldb::ModuleSP module_sp, lldb::DataBufferSP file_data_sp; lldb::offset_t file_data_offset = 0; lldb::ObjectFileSP obj_file = lldb_private::ObjectFile::FindPlugin( - module_sp, &file_spec, file_offset, file_spec.GetByteSize(), file_data_sp, + module_sp, &file_spec, file_offset, + lldb_private::FileSystem::Instance().GetByteSize(file_spec), file_data_sp, file_data_offset); if (obj_file == nullptr) return nullptr; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h index 470d1c5b1c48..87f4d9402335 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h @@ -10,14 +10,10 @@ #ifndef SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ #define SymbolFileDWARFDwp_SymbolFileDWARFDwp_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" -// Project includes #include "lldb/Core/Module.h" #include "DWARFDataExtractor.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp index 8273d975e57d..dd912aecf0d8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -9,10 +9,6 @@ #include "UniqueDWARFASTType.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/Declaration.h" bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die, diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h index 5d51044cbe1a..1e6b164e9457 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.h @@ -10,14 +10,10 @@ #ifndef lldb_UniqueDWARFASTType_h_ #define lldb_UniqueDWARFASTType_h_ -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/ADT/DenseMap.h" -// Project includes #include "DWARFDIE.h" #include "lldb/Symbol/Declaration.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp new file mode 100644 index 000000000000..67ea05767fde --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -0,0 +1,217 @@ +//===-- CompileUnitIndex.cpp ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "CompileUnitIndex.h" + +#include "PdbIndex.h" +#include "PdbUtil.h" + +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/InfoStream.h" +#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" +#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/Support/Path.h" + +#include "lldb/Utility/LLDBAssert.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::npdb; +using namespace llvm::codeview; +using namespace llvm::pdb; + +static bool IsMainFile(llvm::StringRef main, llvm::StringRef other) { + if (main == other) + return true; + + // If the files refer to the local file system, we can just ask the file + // system if they're equivalent. But if the source isn't present on disk + // then we still want to try. + if (llvm::sys::fs::equivalent(main, other)) + return true; + + llvm::SmallString<64> normalized(other); + llvm::sys::path::native(normalized); + return main.equals_lower(normalized); +} + +static void ParseCompile3(const CVSymbol &sym, CompilandIndexItem &cci) { + cci.m_compile_opts.emplace(); + llvm::cantFail( + SymbolDeserializer::deserializeAs(sym, *cci.m_compile_opts)); +} + +static void ParseObjname(const CVSymbol &sym, CompilandIndexItem &cci) { + cci.m_obj_name.emplace(); + llvm::cantFail( + SymbolDeserializer::deserializeAs(sym, *cci.m_obj_name)); +} + +static void ParseBuildInfo(PdbIndex &index, const CVSymbol &sym, + CompilandIndexItem &cci) { + BuildInfoSym bis(SymbolRecordKind::BuildInfoSym); + llvm::cantFail(SymbolDeserializer::deserializeAs(sym, bis)); + + // S_BUILDINFO just points to an LF_BUILDINFO in the IPI stream. Let's do + // a little extra work to pull out the LF_BUILDINFO. + LazyRandomTypeCollection &types = index.ipi().typeCollection(); + llvm::Optional cvt = types.tryGetType(bis.BuildId); + + if (!cvt || cvt->kind() != LF_BUILDINFO) + return; + + BuildInfoRecord bir; + llvm::cantFail(TypeDeserializer::deserializeAs(*cvt, bir)); + cci.m_build_info.assign(bir.ArgIndices.begin(), bir.ArgIndices.end()); +} + +static void ParseExtendedInfo(PdbIndex &index, CompilandIndexItem &item) { + const CVSymbolArray &syms = item.m_debug_stream.getSymbolArray(); + + // This is a private function, it shouldn't be called if the information + // has already been parsed. + lldbassert(!item.m_obj_name); + lldbassert(!item.m_compile_opts); + lldbassert(item.m_build_info.empty()); + + // We're looking for 3 things. S_COMPILE3, S_OBJNAME, and S_BUILDINFO. + int found = 0; + for (const CVSymbol &sym : syms) { + switch (sym.kind()) { + case S_COMPILE3: + ParseCompile3(sym, item); + break; + case S_OBJNAME: + ParseObjname(sym, item); + break; + case S_BUILDINFO: + ParseBuildInfo(index, sym, item); + break; + default: + continue; + } + if (++found >= 3) + break; + } +} + +CompilandIndexItem::CompilandIndexItem( + PdbCompilandId id, llvm::pdb::ModuleDebugStreamRef debug_stream, + llvm::pdb::DbiModuleDescriptor descriptor) + : m_id(id), m_debug_stream(std::move(debug_stream)), + m_module_descriptor(std::move(descriptor)) {} + +CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { + auto result = m_comp_units.try_emplace(modi, nullptr); + if (!result.second) + return *result.first->second; + + // Find the module list and load its debug information stream and cache it + // since we need to use it for almost all interesting operations. + const DbiModuleList &modules = m_index.dbi().modules(); + llvm::pdb::DbiModuleDescriptor descriptor = modules.getModuleDescriptor(modi); + uint16_t stream = descriptor.getModuleStreamIndex(); + std::unique_ptr stream_data = + m_index.pdb().createIndexedStream(stream); + llvm::pdb::ModuleDebugStreamRef debug_stream(descriptor, + std::move(stream_data)); + cantFail(debug_stream.reload()); + + std::unique_ptr &cci = result.first->second; + + cci = llvm::make_unique( + PdbCompilandId{modi}, std::move(debug_stream), std::move(descriptor)); + ParseExtendedInfo(m_index, *cci); + + cci->m_strings.initialize(debug_stream.getSubsectionsArray()); + PDBStringTable &strings = cantFail(m_index.pdb().getStringTable()); + cci->m_strings.setStrings(strings.getStringTable()); + + // We want the main source file to always comes first. Note that we can't + // just push_back the main file onto the front because `GetMainSourceFile` + // computes it in such a way that it doesn't own the resulting memory. So we + // have to iterate the module file list comparing each one to the main file + // name until we find it, and we can cache that one since the memory is backed + // by a contiguous chunk inside the mapped PDB. + llvm::SmallString<64> main_file = GetMainSourceFile(*cci); + std::string s = main_file.str(); + llvm::sys::path::native(main_file); + + uint32_t file_count = modules.getSourceFileCount(modi); + cci->m_file_list.reserve(file_count); + bool found_main_file = false; + for (llvm::StringRef file : modules.source_files(modi)) { + if (!found_main_file && IsMainFile(main_file, file)) { + cci->m_file_list.insert(cci->m_file_list.begin(), file); + found_main_file = true; + continue; + } + cci->m_file_list.push_back(file); + } + + return *cci; +} + +const CompilandIndexItem *CompileUnitIndex::GetCompiland(uint16_t modi) const { + auto iter = m_comp_units.find(modi); + if (iter == m_comp_units.end()) + return nullptr; + return iter->second.get(); +} + +CompilandIndexItem *CompileUnitIndex::GetCompiland(uint16_t modi) { + auto iter = m_comp_units.find(modi); + if (iter == m_comp_units.end()) + return nullptr; + return iter->second.get(); +} + +llvm::SmallString<64> +CompileUnitIndex::GetMainSourceFile(const CompilandIndexItem &item) const { + // LF_BUILDINFO contains a list of arg indices which point to LF_STRING_ID + // records in the IPI stream. The order of the arg indices is as follows: + // [0] - working directory where compiler was invoked. + // [1] - absolute path to compiler binary + // [2] - source file name + // [3] - path to compiler generated PDB (the /Zi PDB, although this entry gets + // added even when using /Z7) + // [4] - full command line invocation. + // + // We need to form the path [0]\[2] to generate the full path to the main + // file.source + if (item.m_build_info.size() < 3) + return {""}; + + LazyRandomTypeCollection &types = m_index.ipi().typeCollection(); + + StringIdRecord working_dir; + StringIdRecord file_name; + CVType dir_cvt = types.getType(item.m_build_info[0]); + CVType file_cvt = types.getType(item.m_build_info[2]); + llvm::cantFail( + TypeDeserializer::deserializeAs(dir_cvt, working_dir)); + llvm::cantFail( + TypeDeserializer::deserializeAs(file_cvt, file_name)); + + llvm::sys::path::Style style = working_dir.String.startswith("/") + ? llvm::sys::path::Style::posix + : llvm::sys::path::Style::windows; + if (llvm::sys::path::is_absolute(file_name.String, style)) + return file_name.String; + + llvm::SmallString<64> absolute_path = working_dir.String; + llvm::sys::path::append(absolute_path, file_name.String); + return absolute_path; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h new file mode 100644 index 000000000000..c965870da44b --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.h @@ -0,0 +1,95 @@ +//===-- CompileUnitIndex.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H +#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_COMPILEUNITINDEX_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/IntervalMap.h" +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +#include "PdbSymUid.h" + +#include +#include + +namespace lldb_private { + +namespace npdb { +class PdbIndex; + +/// Represents a single compile unit. This class is useful for collecting the +/// important accessors and information about a compile unit from disparate +/// parts of the PDB into a single place, simplifying acess to compile unit +/// information for the callers. +struct CompilandIndexItem { + CompilandIndexItem(PdbCompilandId m_id, + llvm::pdb::ModuleDebugStreamRef debug_stream, + llvm::pdb::DbiModuleDescriptor descriptor); + + // index of this compile unit. + PdbCompilandId m_id; + + // debug stream. + llvm::pdb::ModuleDebugStreamRef m_debug_stream; + + // dbi module descriptor. + llvm::pdb::DbiModuleDescriptor m_module_descriptor; + + llvm::codeview::StringsAndChecksumsRef m_strings; + + // List of files which contribute to this compiland. + std::vector m_file_list; + + // Maps virtual address to global symbol id, which can then be used to + // locate the exact compile unit and offset of the symbol. Note that this + // is intentionally an ordered map so that we can find all symbols up to a + // given starting address. + std::map m_symbols_by_va; + + // S_COMPILE3 sym describing compilation settings for the module. + llvm::Optional m_compile_opts; + + // S_OBJNAME sym describing object name. + llvm::Optional m_obj_name; + + // LF_BUILDINFO sym describing source file name, working directory, + // command line, etc. This usually contains exactly 5 items which + // are references to other strings. + llvm::SmallVector m_build_info; +}; + +/// Indexes information about all compile units. This is really just a map of +/// global compile unit index to |CompilandIndexItem| structures. +class CompileUnitIndex { + PdbIndex &m_index; + llvm::DenseMap> m_comp_units; + +public: + explicit CompileUnitIndex(PdbIndex &index) : m_index(index) {} + + CompilandIndexItem &GetOrCreateCompiland(uint16_t modi); + + const CompilandIndexItem *GetCompiland(uint16_t modi) const; + + CompilandIndexItem *GetCompiland(uint16_t modi); + + llvm::SmallString<64> GetMainSourceFile(const CompilandIndexItem &item) const; +}; +} // namespace npdb +} // namespace lldb_private + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp new file mode 100644 index 000000000000..7b62530e4680 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp @@ -0,0 +1,673 @@ +//===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DWARFLocationExpression.h" + +#include "Plugins/Process/Utility/lldb-x86-register-enums.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/Section.h" +#include "lldb/Core/StreamBuffer.h" +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/DataBufferHeap.h" + +#include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/Support/Endian.h" + +#include "PdbUtil.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::npdb; +using namespace llvm::codeview; +using namespace llvm::pdb; + +static const uint32_t g_code_view_to_lldb_registers_x86[] = { + LLDB_INVALID_REGNUM, // NONE + lldb_al_i386, // AL + lldb_cl_i386, // CL + lldb_dl_i386, // DL + lldb_bl_i386, // BL + lldb_ah_i386, // AH + lldb_ch_i386, // CH + lldb_dh_i386, // DH + lldb_bh_i386, // BH + lldb_ax_i386, // AX + lldb_cx_i386, // CX + lldb_dx_i386, // DX + lldb_bx_i386, // BX + lldb_sp_i386, // SP + lldb_bp_i386, // BP + lldb_si_i386, // SI + lldb_di_i386, // DI + lldb_eax_i386, // EAX + lldb_ecx_i386, // ECX + lldb_edx_i386, // EDX + lldb_ebx_i386, // EBX + lldb_esp_i386, // ESP + lldb_ebp_i386, // EBP + lldb_esi_i386, // ESI + lldb_edi_i386, // EDI + lldb_es_i386, // ES + lldb_cs_i386, // CS + lldb_ss_i386, // SS + lldb_ds_i386, // DS + lldb_fs_i386, // FS + lldb_gs_i386, // GS + LLDB_INVALID_REGNUM, // IP + LLDB_INVALID_REGNUM, // FLAGS + lldb_eip_i386, // EIP + lldb_eflags_i386, // EFLAGS + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, // TEMP + LLDB_INVALID_REGNUM, // TEMPH + LLDB_INVALID_REGNUM, // QUOTE + LLDB_INVALID_REGNUM, // PCDR3 + LLDB_INVALID_REGNUM, // PCDR4 + LLDB_INVALID_REGNUM, // PCDR5 + LLDB_INVALID_REGNUM, // PCDR6 + LLDB_INVALID_REGNUM, // PCDR7 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, // CR0 + LLDB_INVALID_REGNUM, // CR1 + LLDB_INVALID_REGNUM, // CR2 + LLDB_INVALID_REGNUM, // CR3 + LLDB_INVALID_REGNUM, // CR4 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + lldb_dr0_i386, // DR0 + lldb_dr1_i386, // DR1 + lldb_dr2_i386, // DR2 + lldb_dr3_i386, // DR3 + lldb_dr4_i386, // DR4 + lldb_dr5_i386, // DR5 + lldb_dr6_i386, // DR6 + lldb_dr7_i386, // DR7 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, // GDTR + LLDB_INVALID_REGNUM, // GDTL + LLDB_INVALID_REGNUM, // IDTR + LLDB_INVALID_REGNUM, // IDTL + LLDB_INVALID_REGNUM, // LDTR + LLDB_INVALID_REGNUM, // TR + LLDB_INVALID_REGNUM, // PSEUDO1 + LLDB_INVALID_REGNUM, // PSEUDO2 + LLDB_INVALID_REGNUM, // PSEUDO3 + LLDB_INVALID_REGNUM, // PSEUDO4 + LLDB_INVALID_REGNUM, // PSEUDO5 + LLDB_INVALID_REGNUM, // PSEUDO6 + LLDB_INVALID_REGNUM, // PSEUDO7 + LLDB_INVALID_REGNUM, // PSEUDO8 + LLDB_INVALID_REGNUM, // PSEUDO9 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + lldb_st0_i386, // ST0 + lldb_st1_i386, // ST1 + lldb_st2_i386, // ST2 + lldb_st3_i386, // ST3 + lldb_st4_i386, // ST4 + lldb_st5_i386, // ST5 + lldb_st6_i386, // ST6 + lldb_st7_i386, // ST7 + LLDB_INVALID_REGNUM, // CTRL + LLDB_INVALID_REGNUM, // STAT + LLDB_INVALID_REGNUM, // TAG + LLDB_INVALID_REGNUM, // FPIP + LLDB_INVALID_REGNUM, // FPCS + LLDB_INVALID_REGNUM, // FPDO + LLDB_INVALID_REGNUM, // FPDS + LLDB_INVALID_REGNUM, // ISEM + LLDB_INVALID_REGNUM, // FPEIP + LLDB_INVALID_REGNUM, // FPEDO + lldb_mm0_i386, // MM0 + lldb_mm1_i386, // MM1 + lldb_mm2_i386, // MM2 + lldb_mm3_i386, // MM3 + lldb_mm4_i386, // MM4 + lldb_mm5_i386, // MM5 + lldb_mm6_i386, // MM6 + lldb_mm7_i386, // MM7 + lldb_xmm0_i386, // XMM0 + lldb_xmm1_i386, // XMM1 + lldb_xmm2_i386, // XMM2 + lldb_xmm3_i386, // XMM3 + lldb_xmm4_i386, // XMM4 + lldb_xmm5_i386, // XMM5 + lldb_xmm6_i386, // XMM6 + lldb_xmm7_i386 // XMM7 +}; + +static const uint32_t g_code_view_to_lldb_registers_x86_64[] = { + LLDB_INVALID_REGNUM, // NONE + lldb_al_x86_64, // AL + lldb_cl_x86_64, // CL + lldb_dl_x86_64, // DL + lldb_bl_x86_64, // BL + lldb_ah_x86_64, // AH + lldb_ch_x86_64, // CH + lldb_dh_x86_64, // DH + lldb_bh_x86_64, // BH + lldb_ax_x86_64, // AX + lldb_cx_x86_64, // CX + lldb_dx_x86_64, // DX + lldb_bx_x86_64, // BX + lldb_sp_x86_64, // SP + lldb_bp_x86_64, // BP + lldb_si_x86_64, // SI + lldb_di_x86_64, // DI + lldb_eax_x86_64, // EAX + lldb_ecx_x86_64, // ECX + lldb_edx_x86_64, // EDX + lldb_ebx_x86_64, // EBX + lldb_esp_x86_64, // ESP + lldb_ebp_x86_64, // EBP + lldb_esi_x86_64, // ESI + lldb_edi_x86_64, // EDI + lldb_es_x86_64, // ES + lldb_cs_x86_64, // CS + lldb_ss_x86_64, // SS + lldb_ds_x86_64, // DS + lldb_fs_x86_64, // FS + lldb_gs_x86_64, // GS + LLDB_INVALID_REGNUM, // IP + LLDB_INVALID_REGNUM, // FLAGS + LLDB_INVALID_REGNUM, // EIP + LLDB_INVALID_REGNUM, // EFLAGS + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, // TEMP + LLDB_INVALID_REGNUM, // TEMPH + LLDB_INVALID_REGNUM, // QUOTE + LLDB_INVALID_REGNUM, // PCDR3 + LLDB_INVALID_REGNUM, // PCDR4 + LLDB_INVALID_REGNUM, // PCDR5 + LLDB_INVALID_REGNUM, // PCDR6 + LLDB_INVALID_REGNUM, // PCDR7 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, // CR0 + LLDB_INVALID_REGNUM, // CR1 + LLDB_INVALID_REGNUM, // CR2 + LLDB_INVALID_REGNUM, // CR3 + LLDB_INVALID_REGNUM, // CR4 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + lldb_dr0_x86_64, // DR0 + lldb_dr1_x86_64, // DR1 + lldb_dr2_x86_64, // DR2 + lldb_dr3_x86_64, // DR3 + lldb_dr4_x86_64, // DR4 + lldb_dr5_x86_64, // DR5 + lldb_dr6_x86_64, // DR6 + lldb_dr7_x86_64, // DR7 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, // GDTR + LLDB_INVALID_REGNUM, // GDTL + LLDB_INVALID_REGNUM, // IDTR + LLDB_INVALID_REGNUM, // IDTL + LLDB_INVALID_REGNUM, // LDTR + LLDB_INVALID_REGNUM, // TR + LLDB_INVALID_REGNUM, // PSEUDO1 + LLDB_INVALID_REGNUM, // PSEUDO2 + LLDB_INVALID_REGNUM, // PSEUDO3 + LLDB_INVALID_REGNUM, // PSEUDO4 + LLDB_INVALID_REGNUM, // PSEUDO5 + LLDB_INVALID_REGNUM, // PSEUDO6 + LLDB_INVALID_REGNUM, // PSEUDO7 + LLDB_INVALID_REGNUM, // PSEUDO8 + LLDB_INVALID_REGNUM, // PSEUDO9 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + lldb_st0_x86_64, // ST0 + lldb_st1_x86_64, // ST1 + lldb_st2_x86_64, // ST2 + lldb_st3_x86_64, // ST3 + lldb_st4_x86_64, // ST4 + lldb_st5_x86_64, // ST5 + lldb_st6_x86_64, // ST6 + lldb_st7_x86_64, // ST7 + LLDB_INVALID_REGNUM, // CTRL + LLDB_INVALID_REGNUM, // STAT + LLDB_INVALID_REGNUM, // TAG + LLDB_INVALID_REGNUM, // FPIP + LLDB_INVALID_REGNUM, // FPCS + LLDB_INVALID_REGNUM, // FPDO + LLDB_INVALID_REGNUM, // FPDS + LLDB_INVALID_REGNUM, // ISEM + LLDB_INVALID_REGNUM, // FPEIP + LLDB_INVALID_REGNUM, // FPEDO + lldb_mm0_x86_64, // MM0 + lldb_mm1_x86_64, // MM1 + lldb_mm2_x86_64, // MM2 + lldb_mm3_x86_64, // MM3 + lldb_mm4_x86_64, // MM4 + lldb_mm5_x86_64, // MM5 + lldb_mm6_x86_64, // MM6 + lldb_mm7_x86_64, // MM7 + lldb_xmm0_x86_64, // XMM0 + lldb_xmm1_x86_64, // XMM1 + lldb_xmm2_x86_64, // XMM2 + lldb_xmm3_x86_64, // XMM3 + lldb_xmm4_x86_64, // XMM4 + lldb_xmm5_x86_64, // XMM5 + lldb_xmm6_x86_64, // XMM6 + lldb_xmm7_x86_64, // XMM7 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + lldb_mxcsr_x86_64, // MXCSR + LLDB_INVALID_REGNUM, // EDXEAX + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, // EMM0L + LLDB_INVALID_REGNUM, // EMM1L + LLDB_INVALID_REGNUM, // EMM2L + LLDB_INVALID_REGNUM, // EMM3L + LLDB_INVALID_REGNUM, // EMM4L + LLDB_INVALID_REGNUM, // EMM5L + LLDB_INVALID_REGNUM, // EMM6L + LLDB_INVALID_REGNUM, // EMM7L + LLDB_INVALID_REGNUM, // EMM0H + LLDB_INVALID_REGNUM, // EMM1H + LLDB_INVALID_REGNUM, // EMM2H + LLDB_INVALID_REGNUM, // EMM3H + LLDB_INVALID_REGNUM, // EMM4H + LLDB_INVALID_REGNUM, // EMM5H + LLDB_INVALID_REGNUM, // EMM6H + LLDB_INVALID_REGNUM, // EMM7H + LLDB_INVALID_REGNUM, // MM00 + LLDB_INVALID_REGNUM, // MM01 + LLDB_INVALID_REGNUM, // MM10 + LLDB_INVALID_REGNUM, // MM11 + LLDB_INVALID_REGNUM, // MM20 + LLDB_INVALID_REGNUM, // MM21 + LLDB_INVALID_REGNUM, // MM30 + LLDB_INVALID_REGNUM, // MM31 + LLDB_INVALID_REGNUM, // MM40 + LLDB_INVALID_REGNUM, // MM41 + LLDB_INVALID_REGNUM, // MM50 + LLDB_INVALID_REGNUM, // MM51 + LLDB_INVALID_REGNUM, // MM60 + LLDB_INVALID_REGNUM, // MM61 + LLDB_INVALID_REGNUM, // MM70 + LLDB_INVALID_REGNUM, // MM71 + lldb_xmm8_x86_64, // XMM8 + lldb_xmm9_x86_64, // XMM9 + lldb_xmm10_x86_64, // XMM10 + lldb_xmm11_x86_64, // XMM11 + lldb_xmm12_x86_64, // XMM12 + lldb_xmm13_x86_64, // XMM13 + lldb_xmm14_x86_64, // XMM14 + lldb_xmm15_x86_64, // XMM15 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, + lldb_sil_x86_64, // SIL + lldb_dil_x86_64, // DIL + lldb_bpl_x86_64, // BPL + lldb_spl_x86_64, // SPL + lldb_rax_x86_64, // RAX + lldb_rbx_x86_64, // RBX + lldb_rcx_x86_64, // RCX + lldb_rdx_x86_64, // RDX + lldb_rsi_x86_64, // RSI + lldb_rdi_x86_64, // RDI + lldb_rbp_x86_64, // RBP + lldb_rsp_x86_64, // RSP + lldb_r8_x86_64, // R8 + lldb_r9_x86_64, // R9 + lldb_r10_x86_64, // R10 + lldb_r11_x86_64, // R11 + lldb_r12_x86_64, // R12 + lldb_r13_x86_64, // R13 + lldb_r14_x86_64, // R14 + lldb_r15_x86_64, // R15 + lldb_r8l_x86_64, // R8B + lldb_r9l_x86_64, // R9B + lldb_r10l_x86_64, // R10B + lldb_r11l_x86_64, // R11B + lldb_r12l_x86_64, // R12B + lldb_r13l_x86_64, // R13B + lldb_r14l_x86_64, // R14B + lldb_r15l_x86_64, // R15B + lldb_r8w_x86_64, // R8W + lldb_r9w_x86_64, // R9W + lldb_r10w_x86_64, // R10W + lldb_r11w_x86_64, // R11W + lldb_r12w_x86_64, // R12W + lldb_r13w_x86_64, // R13W + lldb_r14w_x86_64, // R14W + lldb_r15w_x86_64, // R15W + lldb_r8d_x86_64, // R8D + lldb_r9d_x86_64, // R9D + lldb_r10d_x86_64, // R10D + lldb_r11d_x86_64, // R11D + lldb_r12d_x86_64, // R12D + lldb_r13d_x86_64, // R13D + lldb_r14d_x86_64, // R14D + lldb_r15d_x86_64, // R15D + lldb_ymm0_x86_64, // AMD64_YMM0 + lldb_ymm1_x86_64, // AMD64_YMM1 + lldb_ymm2_x86_64, // AMD64_YMM2 + lldb_ymm3_x86_64, // AMD64_YMM3 + lldb_ymm4_x86_64, // AMD64_YMM4 + lldb_ymm5_x86_64, // AMD64_YMM5 + lldb_ymm6_x86_64, // AMD64_YMM6 + lldb_ymm7_x86_64, // AMD64_YMM7 + lldb_ymm8_x86_64, // AMD64_YMM8 + lldb_ymm9_x86_64, // AMD64_YMM9 + lldb_ymm10_x86_64, // AMD64_YMM10 + lldb_ymm11_x86_64, // AMD64_YMM11 + lldb_ymm12_x86_64, // AMD64_YMM12 + lldb_ymm13_x86_64, // AMD64_YMM13 + lldb_ymm14_x86_64, // AMD64_YMM14 + lldb_ymm15_x86_64, // AMD64_YMM15 + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + lldb_bnd0_x86_64, // BND0 + lldb_bnd1_x86_64, // BND1 + lldb_bnd2_x86_64 // BND2 +}; + +uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, + llvm::codeview::RegisterId register_id) { + switch (arch_type) { + case llvm::Triple::x86: + if (static_cast(register_id) < + sizeof(g_code_view_to_lldb_registers_x86) / + sizeof(g_code_view_to_lldb_registers_x86[0])) + return g_code_view_to_lldb_registers_x86[static_cast( + register_id)]; + + switch (register_id) { + case llvm::codeview::RegisterId::MXCSR: + return lldb_mxcsr_i386; + case llvm::codeview::RegisterId::BND0: + return lldb_bnd0_i386; + case llvm::codeview::RegisterId::BND1: + return lldb_bnd1_i386; + case llvm::codeview::RegisterId::BND2: + return lldb_bnd2_i386; + default: + return LLDB_INVALID_REGNUM; + } + case llvm::Triple::x86_64: + if (static_cast(register_id) < + sizeof(g_code_view_to_lldb_registers_x86_64) / + sizeof(g_code_view_to_lldb_registers_x86_64[0])) + return g_code_view_to_lldb_registers_x86_64[static_cast( + register_id)]; + + return LLDB_INVALID_REGNUM; + default: + return LLDB_INVALID_REGNUM; + } +} + +uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) { + if (register_id == llvm::codeview::RegisterId::VFRAME) + return LLDB_REGNUM_GENERIC_FP; + + return LLDB_INVALID_REGNUM; +} + +static uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type, + llvm::codeview::RegisterId register_id, + RegisterKind ®ister_kind) { + register_kind = eRegisterKindLLDB; + uint32_t reg_num = GetLLDBRegisterNumber(arch_type, register_id); + if (reg_num != LLDB_INVALID_REGNUM) + return reg_num; + + register_kind = eRegisterKindGeneric; + return GetGenericRegisterNumber(register_id); +} + +static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind) { + switch (kind) { + case SimpleTypeKind::Int128: + case SimpleTypeKind::Int64: + case SimpleTypeKind::Int64Quad: + case SimpleTypeKind::Int32: + case SimpleTypeKind::Int32Long: + case SimpleTypeKind::Int16: + case SimpleTypeKind::Int16Short: + case SimpleTypeKind::Float128: + case SimpleTypeKind::Float80: + case SimpleTypeKind::Float64: + case SimpleTypeKind::Float32: + case SimpleTypeKind::Float16: + case SimpleTypeKind::NarrowCharacter: + case SimpleTypeKind::SignedCharacter: + case SimpleTypeKind::SByte: + return true; + default: + return false; + } +} + +static std::pair GetIntegralTypeInfo(TypeIndex ti, + TpiStream &tpi) { + if (ti.isSimple()) { + SimpleTypeKind stk = ti.getSimpleKind(); + return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)}; + } + + CVType cvt = tpi.getType(ti); + switch (cvt.kind()) { + case LF_MODIFIER: { + ModifierRecord mfr; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, mfr)); + return GetIntegralTypeInfo(mfr.ModifiedType, tpi); + } + case LF_POINTER: { + PointerRecord pr; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, pr)); + return GetIntegralTypeInfo(pr.ReferentType, tpi); + } + case LF_ENUM: { + EnumRecord er; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, er)); + return GetIntegralTypeInfo(er.UnderlyingType, tpi); + } + default: + assert(false && "Type is not integral!"); + return {0, false}; + } +} + +template +static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module, + StreamWriter &&writer) { + const ArchSpec &architecture = module->GetArchitecture(); + ByteOrder byte_order = architecture.GetByteOrder(); + uint32_t address_size = architecture.GetAddressByteSize(); + uint32_t byte_size = architecture.GetDataByteSize(); + if (byte_order == eByteOrderInvalid || address_size == 0) + return DWARFExpression(nullptr); + + RegisterKind register_kind = eRegisterKindDWARF; + StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order); + + if (!writer(stream, register_kind)) + return DWARFExpression(nullptr); + + DataBufferSP buffer = + std::make_shared(stream.GetData(), stream.GetSize()); + DataExtractor extractor(buffer, byte_order, address_size, byte_size); + DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize()); + result.SetRegisterKind(register_kind); + + return result; +} + +static DWARFExpression MakeRegisterBasedLocationExpressionInternal( + llvm::codeview::RegisterId reg, llvm::Optional relative_offset, + lldb::ModuleSP module) { + return MakeLocationExpressionInternal( + module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool { + uint32_t reg_num = GetRegisterNumber( + module->GetArchitecture().GetMachine(), reg, register_kind); + if (reg_num == LLDB_INVALID_REGNUM) + return false; + + if (reg_num > 31) { + llvm::dwarf::LocationAtom base = relative_offset + ? llvm::dwarf::DW_OP_bregx + : llvm::dwarf::DW_OP_regx; + stream.PutHex8(base); + stream.PutULEB128(reg_num); + } else { + llvm::dwarf::LocationAtom base = relative_offset + ? llvm::dwarf::DW_OP_breg0 + : llvm::dwarf::DW_OP_reg0; + stream.PutHex8(base + reg_num); + } + + if (relative_offset) + stream.PutSLEB128(*relative_offset); + + return true; + }); +} + +DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpression( + llvm::codeview::RegisterId reg, lldb::ModuleSP module) { + return MakeRegisterBasedLocationExpressionInternal(reg, llvm::None, module); +} + +DWARFExpression lldb_private::npdb::MakeRegRelLocationExpression( + llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module) { + return MakeRegisterBasedLocationExpressionInternal(reg, offset, module); +} + +DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression( + uint16_t section, uint32_t offset, ModuleSP module) { + assert(section > 0); + assert(module); + + return MakeLocationExpressionInternal( + module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool { + stream.PutHex8(llvm::dwarf::DW_OP_addr); + + SectionList *section_list = module->GetSectionList(); + assert(section_list); + + // Section indices in PDB are 1-based, but in DWARF they are 0-based, so + // we need to subtract 1. + uint32_t section_idx = section - 1; + if (section_idx >= section_list->GetSize()) + return false; + + auto section_ptr = section_list->GetSectionAtIndex(section_idx); + if (!section_ptr) + return false; + + stream.PutMaxHex64(section_ptr->GetFileAddress() + offset, + stream.GetAddressByteSize(), stream.GetByteOrder()); + + return true; + }); +} + +DWARFExpression lldb_private::npdb::MakeConstantLocationExpression( + TypeIndex underlying_ti, TpiStream &tpi, const llvm::APSInt &constant, + ModuleSP module) { + const ArchSpec &architecture = module->GetArchitecture(); + uint32_t address_size = architecture.GetAddressByteSize(); + + size_t size = 0; + bool is_signed = false; + std::tie(size, is_signed) = GetIntegralTypeInfo(underlying_ti, tpi); + + union { + llvm::support::little64_t I; + llvm::support::ulittle64_t U; + } Value; + + std::shared_ptr buffer = std::make_shared(); + buffer->SetByteSize(size); + + llvm::ArrayRef bytes; + if (is_signed) { + Value.I = constant.getSExtValue(); + } else { + Value.U = constant.getZExtValue(); + } + + bytes = llvm::makeArrayRef(reinterpret_cast(&Value), 8) + .take_front(size); + buffer->CopyData(bytes.data(), size); + DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size); + DWARFExpression result(nullptr, extractor, nullptr, 0, size); + return result; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h new file mode 100644 index 000000000000..670e95ee8e3c --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h @@ -0,0 +1,42 @@ +//===-- DWARFLocationExpression.h -------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H +#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H + +#include "lldb/lldb-forward.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" + +namespace llvm { +class APSInt; +namespace codeview { +class TypeIndex; +} +namespace pdb { +class TpiStream; +} +} // namespace llvm +namespace lldb_private { +namespace npdb { +DWARFExpression +MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg, + lldb::ModuleSP module); + +DWARFExpression MakeRegRelLocationExpression(llvm::codeview::RegisterId reg, + int32_t offset, + lldb::ModuleSP module); +DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset, + lldb::ModuleSP module); +DWARFExpression MakeConstantLocationExpression( + llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi, + const llvm::APSInt &constant, lldb::ModuleSP module); +} // namespace npdb +} // namespace lldb_private + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp new file mode 100644 index 000000000000..8917fd092385 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -0,0 +1,1348 @@ +#include "PdbAstBuilder.h" + +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" +#include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/PublicsStream.h" +#include "llvm/DebugInfo/PDB/Native/SymbolStream.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/Demangle/MicrosoftDemangle.h" + +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "lldb/Core/Module.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangExternalASTSourceCommon.h" +#include "lldb/Symbol/ClangUtil.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Utility/LLDBAssert.h" + +#include "PdbUtil.h" +#include "UdtRecordCompleter.h" + +using namespace lldb_private; +using namespace lldb_private::npdb; +using namespace llvm::codeview; +using namespace llvm::pdb; + +static llvm::Optional FindSymbolScope(PdbIndex &index, + PdbCompilandSymId id) { + CVSymbol sym = index.ReadSymbolRecord(id); + if (symbolOpensScope(sym.kind())) { + // If this exact symbol opens a scope, we can just directly access its + // parent. + id.offset = getScopeParentOffset(sym); + // Global symbols have parent offset of 0. Return llvm::None to indicate + // this. + if (id.offset == 0) + return llvm::None; + return id; + } + + // Otherwise we need to start at the beginning and iterate forward until we + // reach (or pass) this particular symbol + CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(id.modi); + const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray(); + + auto begin = syms.begin(); + auto end = syms.at(id.offset); + std::vector scope_stack; + + while (begin != end) { + if (id.offset == begin.offset()) { + // We have a match! Return the top of the stack + if (scope_stack.empty()) + return llvm::None; + return scope_stack.back(); + } + if (begin.offset() > id.offset) { + // We passed it. We couldn't even find this symbol record. + lldbassert(false && "Invalid compiland symbol id!"); + return llvm::None; + } + + // We haven't found the symbol yet. Check if we need to open or close the + // scope stack. + if (symbolOpensScope(begin->kind())) { + // We can use the end offset of the scope to determine whether or not + // we can just outright skip this entire scope. + uint32_t scope_end = getScopeEndOffset(*begin); + if (scope_end < id.modi) { + begin = syms.at(scope_end); + } else { + // The symbol we're looking for is somewhere in this scope. + scope_stack.emplace_back(id.modi, begin.offset()); + } + } else if (symbolEndsScope(begin->kind())) { + scope_stack.pop_back(); + } + ++begin; + } + + return llvm::None; +} + +static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) { + switch (cr.Kind) { + case TypeRecordKind::Class: + return clang::TTK_Class; + case TypeRecordKind::Struct: + return clang::TTK_Struct; + case TypeRecordKind::Union: + return clang::TTK_Union; + case TypeRecordKind::Interface: + return clang::TTK_Interface; + case TypeRecordKind::Enum: + return clang::TTK_Enum; + default: + lldbassert(false && "Invalid tag record kind!"); + return clang::TTK_Struct; + } +} + +static bool IsCVarArgsFunction(llvm::ArrayRef args) { + if (args.empty()) + return false; + return args.back() == TypeIndex::None(); +} + +static bool +AnyScopesHaveTemplateParams(llvm::ArrayRef scopes) { + for (llvm::ms_demangle::Node *n : scopes) { + auto *idn = static_cast(n); + if (idn->TemplateParams) + return true; + } + return false; +} + +static ClangASTContext &GetClangASTContext(ObjectFile &obj) { + TypeSystem *ts = + obj.GetModule()->GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); + lldbassert(ts); + return static_cast(*ts); +} + +static llvm::Optional +TranslateCallingConvention(llvm::codeview::CallingConvention conv) { + using CC = llvm::codeview::CallingConvention; + switch (conv) { + + case CC::NearC: + case CC::FarC: + return clang::CallingConv::CC_C; + case CC::NearPascal: + case CC::FarPascal: + return clang::CallingConv::CC_X86Pascal; + case CC::NearFast: + case CC::FarFast: + return clang::CallingConv::CC_X86FastCall; + case CC::NearStdCall: + case CC::FarStdCall: + return clang::CallingConv::CC_X86StdCall; + case CC::ThisCall: + return clang::CallingConv::CC_X86ThisCall; + case CC::NearVector: + return clang::CallingConv::CC_X86VectorCall; + default: + return llvm::None; + } +} + +static llvm::Optional +GetNestedTagDefinition(const NestedTypeRecord &Record, + const CVTagRecord &parent, TpiStream &tpi) { + // An LF_NESTTYPE is essentially a nested typedef / using declaration, but it + // is also used to indicate the primary definition of a nested class. That is + // to say, if you have: + // struct A { + // struct B {}; + // using C = B; + // }; + // Then in the debug info, this will appear as: + // LF_STRUCTURE `A::B` [type index = N] + // LF_STRUCTURE `A` + // LF_NESTTYPE [name = `B`, index = N] + // LF_NESTTYPE [name = `C`, index = N] + // In order to accurately reconstruct the decl context hierarchy, we need to + // know which ones are actual definitions and which ones are just aliases. + + // If it's a simple type, then this is something like `using foo = int`. + if (Record.Type.isSimple()) + return llvm::None; + + CVType cvt = tpi.getType(Record.Type); + + if (!IsTagRecord(cvt)) + return llvm::None; + + // If it's an inner definition, then treat whatever name we have here as a + // single component of a mangled name. So we can inject it into the parent's + // mangled name to see if it matches. + CVTagRecord child = CVTagRecord::create(cvt); + std::string qname = parent.asTag().getUniqueName(); + if (qname.size() < 4 || child.asTag().getUniqueName().size() < 4) + return llvm::None; + + // qname[3] is the tag type identifier (struct, class, union, etc). Since the + // inner tag type is not necessarily the same as the outer tag type, re-write + // it to match the inner tag type. + qname[3] = child.asTag().getUniqueName()[3]; + std::string piece; + if (qname[3] == 'W') + piece = "4"; + piece += Record.Name; + piece.push_back('@'); + qname.insert(4, std::move(piece)); + if (qname != child.asTag().UniqueName) + return llvm::None; + + return std::move(child); +} + +PdbAstBuilder::PdbAstBuilder(ObjectFile &obj, PdbIndex &index) + : m_index(index), m_clang(GetClangASTContext(obj)) { + BuildParentMap(); +} + +clang::DeclContext &PdbAstBuilder::GetTranslationUnitDecl() { + return *m_clang.GetTranslationUnitDecl(); +} + +std::pair +PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { + // FIXME: Move this to GetDeclContextContainingUID. + if (!record.hasUniqueName()) + return CreateDeclInfoForUndecoratedName(record.Name); + + llvm::ms_demangle::Demangler demangler; + StringView sv(record.UniqueName.begin(), record.UniqueName.size()); + llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); + if (demangler.Error) + return {m_clang.GetTranslationUnitDecl(), record.UniqueName}; + + llvm::ms_demangle::IdentifierNode *idn = + ttn->QualifiedName->getUnqualifiedIdentifier(); + std::string uname = idn->toString(llvm::ms_demangle::OF_NoTagSpecifier); + + llvm::ms_demangle::NodeArrayNode *name_components = + ttn->QualifiedName->Components; + llvm::ArrayRef scopes(name_components->Nodes, + name_components->Count - 1); + + clang::DeclContext *context = m_clang.GetTranslationUnitDecl(); + + // If this type doesn't have a parent type in the debug info, then the best we + // can do is to say that it's either a series of namespaces (if the scope is + // non-empty), or the translation unit (if the scope is empty). + auto parent_iter = m_parent_types.find(ti); + if (parent_iter == m_parent_types.end()) { + if (scopes.empty()) + return {context, uname}; + + // If there is no parent in the debug info, but some of the scopes have + // template params, then this is a case of bad debug info. See, for + // example, llvm.org/pr39607. We don't want to create an ambiguity between + // a NamespaceDecl and a CXXRecordDecl, so instead we create a class at + // global scope with the fully qualified name. + if (AnyScopesHaveTemplateParams(scopes)) + return {context, record.Name}; + + for (llvm::ms_demangle::Node *scope : scopes) { + auto *nii = static_cast(scope); + std::string str = nii->toString(); + context = m_clang.GetUniqueNamespaceDeclaration(str.c_str(), context); + } + return {context, uname}; + } + + // Otherwise, all we need to do is get the parent type of this type and + // recurse into our lazy type creation / AST reconstruction logic to get an + // LLDB TypeSP for the parent. This will cause the AST to automatically get + // the right DeclContext created for any parent. + clang::QualType parent_qt = GetOrCreateType(parent_iter->second); + + context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl()); + return {context, uname}; +} + +void PdbAstBuilder::BuildParentMap() { + LazyRandomTypeCollection &types = m_index.tpi().typeCollection(); + + llvm::DenseMap forward_to_full; + llvm::DenseMap full_to_forward; + + struct RecordIndices { + TypeIndex forward; + TypeIndex full; + }; + + llvm::StringMap record_indices; + + for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { + CVType type = types.getType(*ti); + if (!IsTagRecord(type)) + continue; + + CVTagRecord tag = CVTagRecord::create(type); + + RecordIndices &indices = record_indices[tag.asTag().getUniqueName()]; + if (tag.asTag().isForwardRef()) + indices.forward = *ti; + else + indices.full = *ti; + + if (indices.full != TypeIndex::None() && + indices.forward != TypeIndex::None()) { + forward_to_full[indices.forward] = indices.full; + full_to_forward[indices.full] = indices.forward; + } + + // We're looking for LF_NESTTYPE records in the field list, so ignore + // forward references (no field list), and anything without a nested class + // (since there won't be any LF_NESTTYPE records). + if (tag.asTag().isForwardRef() || !tag.asTag().containsNestedClass()) + continue; + + struct ProcessTpiStream : public TypeVisitorCallbacks { + ProcessTpiStream(PdbIndex &index, TypeIndex parent, + const CVTagRecord &parent_cvt, + llvm::DenseMap &parents) + : index(index), parents(parents), parent(parent), + parent_cvt(parent_cvt) {} + + PdbIndex &index; + llvm::DenseMap &parents; + + unsigned unnamed_type_index = 1; + TypeIndex parent; + const CVTagRecord &parent_cvt; + + llvm::Error visitKnownMember(CVMemberRecord &CVR, + NestedTypeRecord &Record) override { + std::string unnamed_type_name; + if (Record.Name.empty()) { + unnamed_type_name = + llvm::formatv("", unnamed_type_index).str(); + Record.Name = unnamed_type_name; + ++unnamed_type_index; + } + llvm::Optional tag = + GetNestedTagDefinition(Record, parent_cvt, index.tpi()); + if (!tag) + return llvm::ErrorSuccess(); + + parents[Record.Type] = parent; + return llvm::ErrorSuccess(); + } + }; + + CVType field_list = m_index.tpi().getType(tag.asTag().FieldList); + ProcessTpiStream process(m_index, *ti, tag, m_parent_types); + llvm::Error error = visitMemberRecordStream(field_list.data(), process); + if (error) + llvm::consumeError(std::move(error)); + } + + // Now that we know the forward -> full mapping of all type indices, we can + // re-write all the indices. At the end of this process, we want a mapping + // consisting of fwd -> full and full -> full for all child -> parent indices. + // We can re-write the values in place, but for the keys, we must save them + // off so that we don't modify the map in place while also iterating it. + std::vector full_keys; + std::vector fwd_keys; + for (auto &entry : m_parent_types) { + TypeIndex key = entry.first; + TypeIndex value = entry.second; + + auto iter = forward_to_full.find(value); + if (iter != forward_to_full.end()) + entry.second = iter->second; + + iter = forward_to_full.find(key); + if (iter != forward_to_full.end()) + fwd_keys.push_back(key); + else + full_keys.push_back(key); + } + for (TypeIndex fwd : fwd_keys) { + TypeIndex full = forward_to_full[fwd]; + m_parent_types[full] = m_parent_types[fwd]; + } + for (TypeIndex full : full_keys) { + TypeIndex fwd = full_to_forward[full]; + m_parent_types[fwd] = m_parent_types[full]; + } + + // Now that +} + +static bool isLocalVariableType(SymbolKind K) { + switch (K) { + case S_REGISTER: + case S_REGREL32: + case S_LOCAL: + return true; + default: + break; + } + return false; +} + +static std::string +RenderScopeList(llvm::ArrayRef nodes) { + lldbassert(!nodes.empty()); + + std::string result = nodes.front()->toString(); + nodes = nodes.drop_front(); + while (!nodes.empty()) { + result += "::"; + result += nodes.front()->toString(llvm::ms_demangle::OF_NoTagSpecifier); + nodes = nodes.drop_front(); + } + return result; +} + +static llvm::Optional FindPublicSym(const SegmentOffset &addr, + SymbolStream &syms, + PublicsStream &publics) { + llvm::FixedStreamArray addr_map = publics.getAddressMap(); + auto iter = std::lower_bound( + addr_map.begin(), addr_map.end(), addr, + [&](const ulittle32_t &x, const SegmentOffset &y) { + CVSymbol s1 = syms.readRecord(x); + lldbassert(s1.kind() == S_PUB32); + PublicSym32 p1; + llvm::cantFail(SymbolDeserializer::deserializeAs(s1, p1)); + if (p1.Segment < y.segment) + return true; + return p1.Offset < y.offset; + }); + if (iter == addr_map.end()) + return llvm::None; + CVSymbol sym = syms.readRecord(*iter); + lldbassert(sym.kind() == S_PUB32); + PublicSym32 p; + llvm::cantFail(SymbolDeserializer::deserializeAs(sym, p)); + if (p.Segment == addr.segment && p.Offset == addr.offset) + return p; + return llvm::None; +} + +clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) { + CVSymbol cvs = m_index.ReadSymbolRecord(id); + + if (isLocalVariableType(cvs.kind())) { + clang::DeclContext *scope = GetParentDeclContext(id); + clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope); + PdbCompilandSymId scope_id(id.modi, m_decl_to_status[scope_decl].uid); + return GetOrCreateVariableDecl(scope_id, id); + } + + switch (cvs.kind()) { + case S_GPROC32: + case S_LPROC32: + return GetOrCreateFunctionDecl(id); + case S_GDATA32: + case S_LDATA32: + case S_GTHREAD32: + case S_CONSTANT: + // global variable + return nullptr; + case S_BLOCK32: + return GetOrCreateBlockDecl(id); + default: + return nullptr; + } +} + +clang::Decl *PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) { + if (clang::Decl *result = TryGetDecl(uid)) + return result; + + clang::Decl *result = nullptr; + switch (uid.kind()) { + case PdbSymUidKind::CompilandSym: + result = GetOrCreateSymbolForId(uid.asCompilandSym()); + break; + case PdbSymUidKind::Type: { + clang::QualType qt = GetOrCreateType(uid.asTypeSym()); + if (auto *tag = qt->getAsTagDecl()) { + result = tag; + break; + } + return nullptr; + } + default: + return nullptr; + } + m_uid_to_decl[toOpaqueUid(uid)] = result; + return result; +} + +clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) { + if (uid.kind() == PdbSymUidKind::CompilandSym) { + if (uid.asCompilandSym().offset == 0) + return &GetTranslationUnitDecl(); + } + + clang::Decl *decl = GetOrCreateDeclForUid(uid); + if (!decl) + return nullptr; + + return clang::Decl::castToDeclContext(decl); +} + +std::pair +PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { + MSVCUndecoratedNameParser parser(name); + llvm::ArrayRef specs = parser.GetSpecifiers(); + + clang::DeclContext *context = &GetTranslationUnitDecl(); + + llvm::StringRef uname = specs.back().GetBaseName(); + specs = specs.drop_back(); + if (specs.empty()) + return {context, name}; + + llvm::StringRef scope_name = specs.back().GetFullName(); + + // It might be a class name, try that first. + std::vector types = m_index.tpi().findRecordsByName(scope_name); + while (!types.empty()) { + clang::QualType qt = GetOrCreateType(types.back()); + clang::TagDecl *tag = qt->getAsTagDecl(); + if (tag) + return {clang::TagDecl::castToDeclContext(tag), uname}; + types.pop_back(); + } + + // If that fails, treat it as a series of namespaces. + for (const MSVCUndecoratedNameSpecifier &spec : specs) { + std::string ns_name = spec.GetBaseName().str(); + context = m_clang.GetUniqueNamespaceDeclaration(ns_name.c_str(), context); + } + return {context, uname}; +} + +clang::DeclContext * +PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) { + if (!SymbolHasAddress(sym)) + return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first; + SegmentOffset addr = GetSegmentAndOffset(sym); + llvm::Optional pub = + FindPublicSym(addr, m_index.symrecords(), m_index.publics()); + if (!pub) + return CreateDeclInfoForUndecoratedName(getSymbolName(sym)).first; + + llvm::ms_demangle::Demangler demangler; + StringView name{pub->Name.begin(), pub->Name.size()}; + llvm::ms_demangle::SymbolNode *node = demangler.parse(name); + if (!node) + return &GetTranslationUnitDecl(); + llvm::ArrayRef name_components{ + node->Name->Components->Nodes, node->Name->Components->Count - 1}; + + if (!name_components.empty()) { + // Render the current list of scope nodes as a fully qualified name, and + // look it up in the debug info as a type name. If we find something, + // this is a type (which may itself be prefixed by a namespace). If we + // don't, this is a list of namespaces. + std::string qname = RenderScopeList(name_components); + std::vector matches = m_index.tpi().findRecordsByName(qname); + while (!matches.empty()) { + clang::QualType qt = GetOrCreateType(matches.back()); + clang::TagDecl *tag = qt->getAsTagDecl(); + if (tag) + return clang::TagDecl::castToDeclContext(tag); + matches.pop_back(); + } + } + + // It's not a type. It must be a series of namespaces. + clang::DeclContext *context = &GetTranslationUnitDecl(); + while (!name_components.empty()) { + std::string ns = name_components.front()->toString(); + context = m_clang.GetUniqueNamespaceDeclaration(ns.c_str(), context); + name_components = name_components.drop_front(); + } + return context; +} + +clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) { + // We must do this *without* calling GetOrCreate on the current uid, as + // that would be an infinite recursion. + switch (uid.kind()) { + case PdbSymUidKind::CompilandSym: { + llvm::Optional scope = + FindSymbolScope(m_index, uid.asCompilandSym()); + if (scope) + return GetOrCreateDeclContextForUid(*scope); + + CVSymbol sym = m_index.ReadSymbolRecord(uid.asCompilandSym()); + return GetParentDeclContextForSymbol(sym); + } + case PdbSymUidKind::Type: { + // It could be a namespace, class, or global. We don't support nested + // functions yet. Anyway, we just need to consult the parent type map. + PdbTypeSymId type_id = uid.asTypeSym(); + auto iter = m_parent_types.find(type_id.index); + if (iter == m_parent_types.end()) + return &GetTranslationUnitDecl(); + return GetOrCreateDeclContextForUid(PdbTypeSymId(iter->second)); + } + case PdbSymUidKind::FieldListMember: + // In this case the parent DeclContext is the one for the class that this + // member is inside of. + break; + case PdbSymUidKind::GlobalSym: { + // If this refers to a compiland symbol, just recurse in with that symbol. + // The only other possibilities are S_CONSTANT and S_UDT, in which case we + // need to parse the undecorated name to figure out the scope, then look + // that up in the TPI stream. If it's found, it's a type, othewrise it's + // a series of namespaces. + // FIXME: do this. + CVSymbol global = m_index.ReadSymbolRecord(uid.asGlobalSym()); + switch (global.kind()) { + case SymbolKind::S_GDATA32: + case SymbolKind::S_LDATA32: + return GetParentDeclContextForSymbol(global); + case SymbolKind::S_PROCREF: + case SymbolKind::S_LPROCREF: { + ProcRefSym ref{global.kind()}; + llvm::cantFail( + SymbolDeserializer::deserializeAs(global, ref)); + PdbCompilandSymId cu_sym_id{ref.modi(), ref.SymOffset}; + return GetParentDeclContext(cu_sym_id); + } + case SymbolKind::S_CONSTANT: + case SymbolKind::S_UDT: + return CreateDeclInfoForUndecoratedName(getSymbolName(global)).first; + default: + break; + } + break; + } + default: + break; + } + return &GetTranslationUnitDecl(); +} + +bool PdbAstBuilder::CompleteType(clang::QualType qt) { + clang::TagDecl *tag = qt->getAsTagDecl(); + if (!tag) + return false; + + return CompleteTagDecl(*tag); +} + +bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { + // If this is not in our map, it's an error. + auto status_iter = m_decl_to_status.find(&tag); + lldbassert(status_iter != m_decl_to_status.end()); + + // If it's already complete, just return. + DeclStatus &status = status_iter->second; + if (status.resolved) + return true; + + PdbTypeSymId type_id = PdbSymUid(status.uid).asTypeSym(); + + lldbassert(IsTagRecord(type_id, m_index.tpi())); + + clang::QualType tag_qt = m_clang.getASTContext()->getTypeDeclType(&tag); + ClangASTContext::SetHasExternalStorage(tag_qt.getAsOpaquePtr(), false); + + TypeIndex tag_ti = type_id.index; + CVType cvt = m_index.tpi().getType(tag_ti); + if (cvt.kind() == LF_MODIFIER) + tag_ti = LookThroughModifierRecord(cvt); + + PdbTypeSymId best_ti = GetBestPossibleDecl(tag_ti, m_index.tpi()); + cvt = m_index.tpi().getType(best_ti.index); + lldbassert(IsTagRecord(cvt)); + + if (IsForwardRefUdt(cvt)) { + // If we can't find a full decl for this forward ref anywhere in the debug + // info, then we have no way to complete it. + return false; + } + + TypeIndex field_list_ti = GetFieldListIndex(cvt); + CVType field_list_cvt = m_index.tpi().getType(field_list_ti); + if (field_list_cvt.kind() != LF_FIELDLIST) + return false; + + // Visit all members of this class, then perform any finalization necessary + // to complete the class. + CompilerType ct = ToCompilerType(tag_qt); + UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index.tpi()); + auto error = + llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); + completer.complete(); + + status.resolved = true; + if (!error) + return true; + + llvm::consumeError(std::move(error)); + return false; +} + +clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) { + if (ti == TypeIndex::NullptrT()) + return GetBasicType(lldb::eBasicTypeNullPtr); + + if (ti.getSimpleMode() != SimpleTypeMode::Direct) { + clang::QualType direct_type = GetOrCreateType(ti.makeDirect()); + return m_clang.getASTContext()->getPointerType(direct_type); + } + + if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated) + return {}; + + lldb::BasicType bt = GetCompilerTypeForSimpleKind(ti.getSimpleKind()); + if (bt == lldb::eBasicTypeInvalid) + return {}; + + return GetBasicType(bt); +} + +clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) { + clang::QualType pointee_type = GetOrCreateType(pointer.ReferentType); + + // This can happen for pointers to LF_VTSHAPE records, which we shouldn't + // create in the AST. + if (pointee_type.isNull()) + return {}; + + if (pointer.isPointerToMember()) { + MemberPointerInfo mpi = pointer.getMemberInfo(); + clang::QualType class_type = GetOrCreateType(mpi.ContainingType); + + return m_clang.getASTContext()->getMemberPointerType( + pointee_type, class_type.getTypePtr()); + } + + clang::QualType pointer_type; + if (pointer.getMode() == PointerMode::LValueReference) + pointer_type = + m_clang.getASTContext()->getLValueReferenceType(pointee_type); + else if (pointer.getMode() == PointerMode::RValueReference) + pointer_type = + m_clang.getASTContext()->getRValueReferenceType(pointee_type); + else + pointer_type = m_clang.getASTContext()->getPointerType(pointee_type); + + if ((pointer.getOptions() & PointerOptions::Const) != PointerOptions::None) + pointer_type.addConst(); + + if ((pointer.getOptions() & PointerOptions::Volatile) != PointerOptions::None) + pointer_type.addVolatile(); + + if ((pointer.getOptions() & PointerOptions::Restrict) != PointerOptions::None) + pointer_type.addRestrict(); + + return pointer_type; +} + +clang::QualType +PdbAstBuilder::CreateModifierType(const ModifierRecord &modifier) { + clang::QualType unmodified_type = GetOrCreateType(modifier.ModifiedType); + if (unmodified_type.isNull()) + return {}; + + if ((modifier.Modifiers & ModifierOptions::Const) != ModifierOptions::None) + unmodified_type.addConst(); + if ((modifier.Modifiers & ModifierOptions::Volatile) != ModifierOptions::None) + unmodified_type.addVolatile(); + + return unmodified_type; +} + +clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id, + const TagRecord &record) { + clang::DeclContext *context = nullptr; + std::string uname; + std::tie(context, uname) = CreateDeclInfoForType(record, id.index); + clang::TagTypeKind ttk = TranslateUdtKind(record); + lldb::AccessType access = + (ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic; + + ClangASTMetadata metadata; + metadata.SetUserID(toOpaqueUid(id)); + metadata.SetIsDynamicCXXType(false); + + CompilerType ct = + m_clang.CreateRecordType(context, access, uname.c_str(), ttk, + lldb::eLanguageTypeC_plus_plus, &metadata); + + lldbassert(ct.IsValid()); + + ClangASTContext::StartTagDeclarationDefinition(ct); + + // Even if it's possible, don't complete it at this point. Just mark it + // forward resolved, and if/when LLDB needs the full definition, it can + // ask us. + clang::QualType result = + clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); + + ClangASTContext::SetHasExternalStorage(result.getAsOpaquePtr(), true); + return result; +} + +clang::Decl *PdbAstBuilder::TryGetDecl(PdbSymUid uid) const { + auto iter = m_uid_to_decl.find(toOpaqueUid(uid)); + if (iter != m_uid_to_decl.end()) + return iter->second; + return nullptr; +} + +clang::NamespaceDecl * +PdbAstBuilder::GetOrCreateNamespaceDecl(llvm::StringRef name, + clang::DeclContext &context) { + return m_clang.GetUniqueNamespaceDeclaration(name.str().c_str(), &context); +} + +clang::BlockDecl * +PdbAstBuilder::GetOrCreateBlockDecl(PdbCompilandSymId block_id) { + if (clang::Decl *decl = TryGetDecl(block_id)) + return llvm::dyn_cast(decl); + + clang::DeclContext *scope = GetParentDeclContext(block_id); + + clang::BlockDecl *block_decl = m_clang.CreateBlockDeclaration(scope); + m_uid_to_decl.insert({toOpaqueUid(block_id), block_decl}); + + DeclStatus status; + status.resolved = true; + status.uid = toOpaqueUid(block_id); + m_decl_to_status.insert({block_decl, status}); + + return block_decl; +} + +clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym, + clang::DeclContext &scope) { + VariableInfo var_info = GetVariableNameInfo(sym); + clang::QualType qt = GetOrCreateType(var_info.type); + + clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration( + &scope, var_info.name.str().c_str(), qt); + + m_uid_to_decl[toOpaqueUid(uid)] = var_decl; + DeclStatus status; + status.resolved = true; + status.uid = toOpaqueUid(uid); + m_decl_to_status.insert({var_decl, status}); + return var_decl; +} + +clang::VarDecl * +PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id, + PdbCompilandSymId var_id) { + if (clang::Decl *decl = TryGetDecl(var_id)) + return llvm::dyn_cast(decl); + + clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id); + + CVSymbol sym = m_index.ReadSymbolRecord(var_id); + return CreateVariableDecl(PdbSymUid(var_id), sym, *scope); +} + +clang::VarDecl *PdbAstBuilder::GetOrCreateVariableDecl(PdbGlobalSymId var_id) { + if (clang::Decl *decl = TryGetDecl(var_id)) + return llvm::dyn_cast(decl); + + CVSymbol sym = m_index.ReadSymbolRecord(var_id); + return CreateVariableDecl(PdbSymUid(var_id), sym, GetTranslationUnitDecl()); +} + +clang::TypedefNameDecl * +PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) { + if (clang::Decl *decl = TryGetDecl(id)) + return llvm::dyn_cast(decl); + + CVSymbol sym = m_index.ReadSymbolRecord(id); + lldbassert(sym.kind() == S_UDT); + UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs(sym)); + + clang::DeclContext *scope = GetParentDeclContext(id); + + PdbTypeSymId real_type_id{udt.Type, false}; + clang::QualType qt = GetOrCreateType(real_type_id); + + std::string uname = DropNameScope(udt.Name); + + CompilerType ct = m_clang.CreateTypedefType(ToCompilerType(qt), uname.c_str(), + ToCompilerDeclContext(*scope)); + clang::TypedefNameDecl *tnd = m_clang.GetAsTypedefDecl(ct); + DeclStatus status; + status.resolved = true; + status.uid = toOpaqueUid(id); + m_decl_to_status.insert({tnd, status}); + return tnd; +} + +clang::QualType PdbAstBuilder::GetBasicType(lldb::BasicType type) { + CompilerType ct = m_clang.GetBasicType(type); + return clang::QualType::getFromOpaquePtr(ct.GetOpaqueQualType()); +} + +clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) { + if (type.index.isSimple()) + return CreateSimpleType(type.index); + + CVType cvt = m_index.tpi().getType(type.index); + + if (cvt.kind() == LF_MODIFIER) { + ModifierRecord modifier; + llvm::cantFail( + TypeDeserializer::deserializeAs(cvt, modifier)); + return CreateModifierType(modifier); + } + + if (cvt.kind() == LF_POINTER) { + PointerRecord pointer; + llvm::cantFail( + TypeDeserializer::deserializeAs(cvt, pointer)); + return CreatePointerType(pointer); + } + + if (IsTagRecord(cvt)) { + CVTagRecord tag = CVTagRecord::create(cvt); + if (tag.kind() == CVTagRecord::Union) + return CreateRecordType(type.index, tag.asUnion()); + if (tag.kind() == CVTagRecord::Enum) + return CreateEnumType(type.index, tag.asEnum()); + return CreateRecordType(type.index, tag.asClass()); + } + + if (cvt.kind() == LF_ARRAY) { + ArrayRecord ar; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ar)); + return CreateArrayType(ar); + } + + if (cvt.kind() == LF_PROCEDURE) { + ProcedureRecord pr; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, pr)); + return CreateProcedureType(pr); + } + + return {}; +} + +clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { + lldb::user_id_t uid = toOpaqueUid(type); + auto iter = m_uid_to_type.find(uid); + if (iter != m_uid_to_type.end()) + return iter->second; + + PdbTypeSymId best_type = GetBestPossibleDecl(type, m_index.tpi()); + + clang::QualType qt; + if (best_type.index != type.index) { + // This is a forward decl. Call GetOrCreate on the full decl, then map the + // forward decl id to the full decl QualType. + clang::QualType qt = GetOrCreateType(best_type); + m_uid_to_type[toOpaqueUid(type)] = qt; + return qt; + } + + // This is either a full decl, or a forward decl with no matching full decl + // in the debug info. + qt = CreateType(type); + m_uid_to_type[toOpaqueUid(type)] = qt; + if (IsTagRecord(type, m_index.tpi())) { + clang::TagDecl *tag = qt->getAsTagDecl(); + lldbassert(m_decl_to_status.count(tag) == 0); + + DeclStatus &status = m_decl_to_status[tag]; + status.uid = uid; + status.resolved = false; + } + return qt; +} + +clang::FunctionDecl * +PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { + if (clang::Decl *decl = TryGetDecl(func_id)) + return llvm::dyn_cast(decl); + + clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id)); + std::string context_name; + if (clang::NamespaceDecl *ns = llvm::dyn_cast(parent)) { + context_name = ns->getQualifiedNameAsString(); + } else if (clang::TagDecl *tag = llvm::dyn_cast(parent)) { + context_name = tag->getQualifiedNameAsString(); + } + + CVSymbol cvs = m_index.ReadSymbolRecord(func_id); + ProcSym proc(static_cast(cvs.kind())); + llvm::cantFail(SymbolDeserializer::deserializeAs(cvs, proc)); + + PdbTypeSymId type_id(proc.FunctionType); + clang::QualType qt = GetOrCreateType(type_id); + if (qt.isNull()) + return nullptr; + + clang::StorageClass storage = clang::SC_None; + if (proc.Kind == SymbolRecordKind::ProcSym) + storage = clang::SC_Static; + + const clang::FunctionProtoType *func_type = + llvm::dyn_cast(qt); + + CompilerType func_ct = ToCompilerType(qt); + + llvm::StringRef proc_name = proc.Name; + proc_name.consume_front(context_name); + proc_name.consume_front("::"); + + clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration( + parent, proc_name.str().c_str(), func_ct, storage, false); + + lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0); + m_uid_to_decl[toOpaqueUid(func_id)] = function_decl; + DeclStatus status; + status.resolved = true; + status.uid = toOpaqueUid(func_id); + m_decl_to_status.insert({function_decl, status}); + + CreateFunctionParameters(func_id, *function_decl, func_type->getNumParams()); + + return function_decl; +} + +void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, + clang::FunctionDecl &function_decl, + uint32_t param_count) { + CompilandIndexItem *cii = m_index.compilands().GetCompiland(func_id.modi); + CVSymbolArray scope = + cii->m_debug_stream.getSymbolArrayForScope(func_id.offset); + + auto begin = scope.begin(); + auto end = scope.end(); + std::vector params; + while (begin != end && param_count > 0) { + uint32_t record_offset = begin.offset(); + CVSymbol sym = *begin++; + + TypeIndex param_type; + llvm::StringRef param_name; + switch (sym.kind()) { + case S_REGREL32: { + RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); + cantFail(SymbolDeserializer::deserializeAs(sym, reg)); + param_type = reg.Type; + param_name = reg.Name; + break; + } + case S_REGISTER: { + RegisterSym reg(SymbolRecordKind::RegisterSym); + cantFail(SymbolDeserializer::deserializeAs(sym, reg)); + param_type = reg.Index; + param_name = reg.Name; + break; + } + case S_LOCAL: { + LocalSym local(SymbolRecordKind::LocalSym); + cantFail(SymbolDeserializer::deserializeAs(sym, local)); + if ((local.Flags & LocalSymFlags::IsParameter) == LocalSymFlags::None) + continue; + param_type = local.Type; + param_name = local.Name; + break; + } + case S_BLOCK32: + // All parameters should come before the first block. If that isn't the + // case, then perhaps this is bad debug info that doesn't contain + // information about all parameters. + return; + default: + continue; + } + + PdbCompilandSymId param_uid(func_id.modi, record_offset); + clang::QualType qt = GetOrCreateType(param_type); + + CompilerType param_type_ct(&m_clang, qt.getAsOpaquePtr()); + clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( + &function_decl, param_name.str().c_str(), param_type_ct, + clang::SC_None); + lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0); + + m_uid_to_decl[toOpaqueUid(param_uid)] = param; + params.push_back(param); + --param_count; + } + + if (!params.empty()) + m_clang.SetFunctionParameters(&function_decl, params.data(), params.size()); +} + +clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, + const EnumRecord &er) { + clang::DeclContext *decl_context = nullptr; + std::string uname; + std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index); + clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType); + + Declaration declaration; + CompilerType enum_ct = m_clang.CreateEnumerationType( + uname.c_str(), decl_context, declaration, ToCompilerType(underlying_type), + er.isScoped()); + + ClangASTContext::StartTagDeclarationDefinition(enum_ct); + ClangASTContext::SetHasExternalStorage(enum_ct.GetOpaqueQualType(), true); + + return clang::QualType::getFromOpaquePtr(enum_ct.GetOpaqueQualType()); +} + +clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) { + clang::QualType element_type = GetOrCreateType(ar.ElementType); + + uint64_t element_count = + ar.Size / GetSizeOfType({ar.ElementType}, m_index.tpi()); + + CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type), + element_count, false); + return clang::QualType::getFromOpaquePtr(array_ct.GetOpaqueQualType()); +} + +clang::QualType +PdbAstBuilder::CreateProcedureType(const ProcedureRecord &proc) { + TpiStream &stream = m_index.tpi(); + CVType args_cvt = stream.getType(proc.ArgumentList); + ArgListRecord args; + llvm::cantFail( + TypeDeserializer::deserializeAs(args_cvt, args)); + + llvm::ArrayRef arg_indices = llvm::makeArrayRef(args.ArgIndices); + bool is_variadic = IsCVarArgsFunction(arg_indices); + if (is_variadic) + arg_indices = arg_indices.drop_back(); + + std::vector arg_types; + arg_types.reserve(arg_indices.size()); + + for (TypeIndex arg_index : arg_indices) { + clang::QualType arg_type = GetOrCreateType(arg_index); + arg_types.push_back(ToCompilerType(arg_type)); + } + + clang::QualType return_type = GetOrCreateType(proc.ReturnType); + + llvm::Optional cc = + TranslateCallingConvention(proc.CallConv); + if (!cc) + return {}; + + CompilerType return_ct = ToCompilerType(return_type); + CompilerType func_sig_ast_type = m_clang.CreateFunctionType( + return_ct, arg_types.data(), arg_types.size(), is_variadic, 0, *cc); + + return clang::QualType::getFromOpaquePtr( + func_sig_ast_type.GetOpaqueQualType()); +} + +static bool isTagDecl(clang::DeclContext &context) { + return !!llvm::dyn_cast(&context); +} + +static bool isFunctionDecl(clang::DeclContext &context) { + return !!llvm::dyn_cast(&context); +} + +static bool isBlockDecl(clang::DeclContext &context) { + return !!llvm::dyn_cast(&context); +} + +void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf( + llvm::Optional parent) { + TypeIndex ti{m_index.tpi().TypeIndexBegin()}; + for (const CVType &cvt : m_index.tpi().typeArray()) { + PdbTypeSymId tid{ti}; + ++ti; + + if (!IsTagRecord(cvt)) + continue; + + CVTagRecord tag = CVTagRecord::create(cvt); + + if (!parent.hasValue()) { + clang::QualType qt = GetOrCreateType(tid); + CompleteType(qt); + continue; + } + + // Call CreateDeclInfoForType unconditionally so that the namespace info + // gets created. But only call CreateRecordType if the namespace name + // matches. + clang::DeclContext *context = nullptr; + std::string uname; + std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index); + if (!context->isNamespace()) + continue; + + clang::NamespaceDecl *ns = llvm::dyn_cast(context); + std::string actual_ns = ns->getQualifiedNameAsString(); + if (llvm::StringRef(actual_ns).startswith(*parent)) { + clang::QualType qt = GetOrCreateType(tid); + CompleteType(qt); + continue; + } + } + + uint32_t module_count = m_index.dbi().modules().getModuleCount(); + for (uint16_t modi = 0; modi < module_count; ++modi) { + CompilandIndexItem &cii = m_index.compilands().GetOrCreateCompiland(modi); + const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray(); + auto iter = symbols.begin(); + while (iter != symbols.end()) { + PdbCompilandSymId sym_id{modi, iter.offset()}; + + switch (iter->kind()) { + case S_GPROC32: + case S_LPROC32: + GetOrCreateFunctionDecl(sym_id); + iter = symbols.at(getScopeEndOffset(*iter)); + break; + case S_GDATA32: + case S_GTHREAD32: + case S_LDATA32: + case S_LTHREAD32: + GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id); + ++iter; + break; + default: + ++iter; + continue; + } + } + } +} + +static CVSymbolArray skipFunctionParameters(clang::Decl &decl, + const CVSymbolArray &symbols) { + clang::FunctionDecl *func_decl = llvm::dyn_cast(&decl); + if (!func_decl) + return symbols; + unsigned int params = func_decl->getNumParams(); + if (params == 0) + return symbols; + + CVSymbolArray result = symbols; + + while (!result.empty()) { + if (params == 0) + return result; + + CVSymbol sym = *result.begin(); + result.drop_front(); + + if (!isLocalVariableType(sym.kind())) + continue; + + --params; + } + return result; +} + +void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) { + CVSymbol sym = m_index.ReadSymbolRecord(block_id); + lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 || + sym.kind() == S_BLOCK32); + CompilandIndexItem &cii = + m_index.compilands().GetOrCreateCompiland(block_id.modi); + CVSymbolArray symbols = + cii.m_debug_stream.getSymbolArrayForScope(block_id.offset); + + // Function parameters should already have been created when the function was + // parsed. + if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) + symbols = + skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols); + + auto begin = symbols.begin(); + while (begin != symbols.end()) { + PdbCompilandSymId child_sym_id(block_id.modi, begin.offset()); + GetOrCreateSymbolForId(child_sym_id); + if (begin->kind() == S_BLOCK32) { + ParseBlockChildren(child_sym_id); + begin = symbols.at(getScopeEndOffset(*begin)); + } + ++begin; + } +} + +void PdbAstBuilder::ParseDeclsForSimpleContext(clang::DeclContext &context) { + + clang::Decl *decl = clang::Decl::castFromDeclContext(&context); + lldbassert(decl); + + auto iter = m_decl_to_status.find(decl); + lldbassert(iter != m_decl_to_status.end()); + + if (auto *tag = llvm::dyn_cast(&context)) { + CompleteTagDecl(*tag); + return; + } + + if (isFunctionDecl(context) || isBlockDecl(context)) { + PdbCompilandSymId block_id = PdbSymUid(iter->second.uid).asCompilandSym(); + ParseBlockChildren(block_id); + } +} + +void PdbAstBuilder::ParseDeclsForContext(clang::DeclContext &context) { + // Namespaces aren't explicitly represented in the debug info, and the only + // way to parse them is to parse all type info, demangling every single type + // and trying to reconstruct the DeclContext hierarchy this way. Since this + // is an expensive operation, we have to special case it so that we do other + // work (such as parsing the items that appear within the namespaces) at the + // same time. + if (context.isTranslationUnit()) { + ParseAllNamespacesPlusChildrenOf(llvm::None); + return; + } + + if (context.isNamespace()) { + clang::NamespaceDecl &ns = *llvm::dyn_cast(&context); + std::string qname = ns.getQualifiedNameAsString(); + ParseAllNamespacesPlusChildrenOf(llvm::StringRef{qname}); + return; + } + + if (isTagDecl(context) || isFunctionDecl(context) || isBlockDecl(context)) { + ParseDeclsForSimpleContext(context); + return; + } +} + +CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) { + return {&m_clang, &decl}; +} + +CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) { + return {&m_clang, qt.getAsOpaquePtr()}; +} + +CompilerDeclContext +PdbAstBuilder::ToCompilerDeclContext(clang::DeclContext &context) { + return {&m_clang, &context}; +} + +clang::DeclContext * +PdbAstBuilder::FromCompilerDeclContext(CompilerDeclContext context) { + return static_cast(context.GetOpaqueDeclContext()); +} + +void PdbAstBuilder::Dump(Stream &stream) { m_clang.Dump(stream); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h new file mode 100644 index 000000000000..e3c0346f935e --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -0,0 +1,144 @@ +//===-- PdbAstBuilder.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H +#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_PDBASTBUILDER_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringRef.h" + +#include "lldb/Symbol/ClangASTImporter.h" + +#include "PdbIndex.h" +#include "PdbSymUid.h" + +namespace clang { +class TagDecl; +class DeclContext; +class Decl; +class QualType; +class FunctionDecl; +class NamespaceDecl; +} // namespace clang + +namespace llvm { +namespace codeview { +class ProcSym; +} +} // namespace llvm + +namespace lldb_private { +class ClangASTImporter; +class ObjectFile; + +namespace npdb { +class PdbIndex; +struct VariableInfo; + +struct DeclStatus { + DeclStatus() = default; + DeclStatus(lldb::user_id_t uid, bool resolved) + : uid(uid), resolved(resolved) {} + lldb::user_id_t uid = 0; + bool resolved = false; +}; + +class PdbAstBuilder { +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + PdbAstBuilder(ObjectFile &obj, PdbIndex &index); + + clang::DeclContext &GetTranslationUnitDecl(); + + clang::Decl *GetOrCreateDeclForUid(PdbSymUid uid); + clang::DeclContext *GetOrCreateDeclContextForUid(PdbSymUid uid); + clang::DeclContext *GetParentDeclContext(PdbSymUid uid); + + clang::NamespaceDecl *GetOrCreateNamespaceDecl(llvm::StringRef name, + clang::DeclContext &context); + clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id); + clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id); + clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id, + PdbCompilandSymId var_id); + clang::VarDecl *GetOrCreateVariableDecl(PdbGlobalSymId var_id); + clang::TypedefNameDecl *GetOrCreateTypedefDecl(PdbGlobalSymId id); + void ParseDeclsForContext(clang::DeclContext &context); + + clang::QualType GetBasicType(lldb::BasicType type); + clang::QualType GetOrCreateType(PdbTypeSymId type); + + bool CompleteTagDecl(clang::TagDecl &tag); + bool CompleteType(clang::QualType qt); + + CompilerDecl ToCompilerDecl(clang::Decl &decl); + CompilerType ToCompilerType(clang::QualType qt); + CompilerDeclContext ToCompilerDeclContext(clang::DeclContext &context); + clang::DeclContext *FromCompilerDeclContext(CompilerDeclContext context); + + ClangASTContext &clang() { return m_clang; } + ClangASTImporter &importer() { return m_importer; } + + void Dump(Stream &stream); + +private: + clang::Decl *TryGetDecl(PdbSymUid uid) const; + + using TypeIndex = llvm::codeview::TypeIndex; + + clang::QualType + CreatePointerType(const llvm::codeview::PointerRecord &pointer); + clang::QualType + CreateModifierType(const llvm::codeview::ModifierRecord &modifier); + clang::QualType CreateArrayType(const llvm::codeview::ArrayRecord &array); + clang::QualType CreateRecordType(PdbTypeSymId id, + const llvm::codeview::TagRecord &record); + clang::QualType CreateEnumType(PdbTypeSymId id, + const llvm::codeview::EnumRecord &record); + clang::QualType + CreateProcedureType(const llvm::codeview::ProcedureRecord &proc); + clang::QualType CreateType(PdbTypeSymId type); + + void CreateFunctionParameters(PdbCompilandSymId func_id, + clang::FunctionDecl &function_decl, + uint32_t param_count); + clang::Decl *GetOrCreateSymbolForId(PdbCompilandSymId id); + clang::VarDecl *CreateVariableDecl(PdbSymUid uid, + llvm::codeview::CVSymbol sym, + clang::DeclContext &scope); + clang::DeclContext * + GetParentDeclContextForSymbol(const llvm::codeview::CVSymbol &sym); + + void ParseAllNamespacesPlusChildrenOf(llvm::Optional parent); + void ParseDeclsForSimpleContext(clang::DeclContext &context); + void ParseBlockChildren(PdbCompilandSymId block_id); + + void BuildParentMap(); + std::pair + CreateDeclInfoForType(const llvm::codeview::TagRecord &record, TypeIndex ti); + std::pair + CreateDeclInfoForUndecoratedName(llvm::StringRef uname); + clang::QualType CreateSimpleType(TypeIndex ti); + + PdbIndex &m_index; + ClangASTContext &m_clang; + + ClangASTImporter m_importer; + + llvm::DenseMap m_parent_types; + llvm::DenseMap m_decl_to_status; + llvm::DenseMap m_uid_to_decl; + llvm::DenseMap m_uid_to_type; +}; + +} // namespace npdb +} // namespace lldb_private + +#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp new file mode 100644 index 000000000000..9f5dab6c2e84 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp @@ -0,0 +1,200 @@ +//===-- PdbIndex.cpp --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PdbIndex.h" +#include "PdbUtil.h" + +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" +#include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" +#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/PublicsStream.h" +#include "llvm/DebugInfo/PDB/Native/SymbolStream.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/Object/COFF.h" +#include "llvm/Support/Error.h" + +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/lldb-defines.h" + +using namespace lldb_private; +using namespace lldb_private::npdb; +using namespace llvm::codeview; +using namespace llvm::pdb; + +PdbIndex::PdbIndex() : m_cus(*this), m_va_to_modi(m_allocator) {} + +#define ASSIGN_PTR_OR_RETURN(result_ptr, expr) \ + { \ + auto expected_result = expr; \ + if (!expected_result) \ + return expected_result.takeError(); \ + result_ptr = &expected_result.get(); \ + } + +llvm::Expected> +PdbIndex::create(std::unique_ptr file) { + lldbassert(file); + + std::unique_ptr result(new PdbIndex()); + ASSIGN_PTR_OR_RETURN(result->m_dbi, file->getPDBDbiStream()); + ASSIGN_PTR_OR_RETURN(result->m_tpi, file->getPDBTpiStream()); + ASSIGN_PTR_OR_RETURN(result->m_ipi, file->getPDBIpiStream()); + ASSIGN_PTR_OR_RETURN(result->m_info, file->getPDBInfoStream()); + ASSIGN_PTR_OR_RETURN(result->m_publics, file->getPDBPublicsStream()); + ASSIGN_PTR_OR_RETURN(result->m_globals, file->getPDBGlobalsStream()); + ASSIGN_PTR_OR_RETURN(result->m_symrecords, file->getPDBSymbolStream()); + + result->m_tpi->buildHashMap(); + + result->m_file = std::move(file); + + return std::move(result); +} + +lldb::addr_t PdbIndex::MakeVirtualAddress(uint16_t segment, + uint32_t offset) const { + // Segment indices are 1-based. + lldbassert(segment > 0); + + uint32_t max_section = dbi().getSectionHeaders().size(); + lldbassert(segment <= max_section + 1); + + // If this is an absolute symbol, it's indicated by the magic section index + // |max_section+1|. In this case, the offset is meaningless, so just return. + if (segment == max_section + 1) + return LLDB_INVALID_ADDRESS; + + const llvm::object::coff_section &cs = dbi().getSectionHeaders()[segment - 1]; + return m_load_address + static_cast(cs.VirtualAddress) + + static_cast(offset); +} + +lldb::addr_t PdbIndex::MakeVirtualAddress(const SegmentOffset &so) const { + return MakeVirtualAddress(so.segment, so.offset); +} + +llvm::Optional +PdbIndex::GetModuleIndexForAddr(uint16_t segment, uint32_t offset) const { + return GetModuleIndexForVa(MakeVirtualAddress(segment, offset)); +} + +llvm::Optional PdbIndex::GetModuleIndexForVa(lldb::addr_t va) const { + auto iter = m_va_to_modi.find(va); + if (iter == m_va_to_modi.end()) + return llvm::None; + + return iter.value(); +} + +void PdbIndex::ParseSectionContribs() { + class Visitor : public ISectionContribVisitor { + PdbIndex &m_ctx; + llvm::IntervalMap &m_imap; + + public: + Visitor(PdbIndex &ctx, llvm::IntervalMap &imap) + : m_ctx(ctx), m_imap(imap) {} + + void visit(const SectionContrib &C) override { + if (C.Size == 0) + return; + + uint64_t va = m_ctx.MakeVirtualAddress(C.ISect, C.Off); + uint64_t end = va + C.Size; + // IntervalMap's start and end represent a closed range, not a half-open + // range, so we have to subtract 1. + m_imap.insert(va, end - 1, C.Imod); + } + void visit(const SectionContrib2 &C) override { visit(C.Base); } + }; + Visitor v(*this, m_va_to_modi); + dbi().visitSectionContributions(v); +} + +void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) { + lldbassert(cci.m_symbols_by_va.empty() && + "Addr to symbol map is already built!"); + uint16_t modi = cci.m_id.modi; + const CVSymbolArray &syms = cci.m_debug_stream.getSymbolArray(); + for (auto iter = syms.begin(); iter != syms.end(); ++iter) { + if (!SymbolHasAddress(*iter)) + continue; + + SegmentOffset so = GetSegmentAndOffset(*iter); + lldb::addr_t va = MakeVirtualAddress(so); + + PdbCompilandSymId cu_sym_id(modi, iter.offset()); + + // If the debug info is incorrect, we could have multiple symbols with the + // same address. So use try_emplace instead of insert, and the first one + // will win. + cci.m_symbols_by_va.insert(std::make_pair(va, PdbSymUid(cu_sym_id))); + } +} + +std::vector PdbIndex::FindSymbolsByVa(lldb::addr_t va) { + std::vector result; + + llvm::Optional modi = GetModuleIndexForVa(va); + if (!modi) + return result; + + CompilandIndexItem &cci = compilands().GetOrCreateCompiland(*modi); + if (cci.m_symbols_by_va.empty()) + BuildAddrToSymbolMap(cci); + + // The map is sorted by starting address of the symbol. So for example + // we could (in theory) have this situation + // + // [------------------] + // [----------] + // [-----------] + // [-------------] + // [----] + // [-----] + // ^ Address we're searching for + // In order to find this, we use the upper_bound of the key value which would + // be the first symbol whose starting address is higher than the element we're + // searching for. + + auto ub = cci.m_symbols_by_va.upper_bound(va); + + for (auto iter = cci.m_symbols_by_va.begin(); iter != ub; ++iter) { + PdbCompilandSymId cu_sym_id = iter->second.asCompilandSym(); + CVSymbol sym = ReadSymbolRecord(cu_sym_id); + + SegmentOffsetLength sol; + if (SymbolIsCode(sym)) + sol = GetSegmentOffsetAndLength(sym); + else + sol.so = GetSegmentAndOffset(sym); + + lldb::addr_t start = MakeVirtualAddress(sol.so); + lldb::addr_t end = start + sol.length; + if (va >= start && va < end) + result.push_back({std::move(sym), iter->second}); + } + + return result; +} + +CVSymbol PdbIndex::ReadSymbolRecord(PdbCompilandSymId cu_sym) const { + // We need to subtract 4 here to adjust for the codeview debug magic + // at the beginning of the debug info stream. + const CompilandIndexItem *cci = compilands().GetCompiland(cu_sym.modi); + auto iter = cci->m_debug_stream.getSymbolArray().at(cu_sym.offset); + lldbassert(iter != cci->m_debug_stream.getSymbolArray().end()); + return *iter; +} + +CVSymbol PdbIndex::ReadSymbolRecord(PdbGlobalSymId global) const { + return symrecords().readRecord(global.offset); +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h new file mode 100644 index 000000000000..839d4e6606e4 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h @@ -0,0 +1,162 @@ +//===-- PdbIndex.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H +#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBINDEX_H + +#include "lldb/lldb-types.h" +#include "llvm/ADT/IntervalMap.h" +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +#include "CompileUnitIndex.h" +#include "PdbSymUid.h" + +#include +#include + +namespace llvm { +namespace pdb { +class DbiStream; +class TpiStream; +class TpiStream; +class InfoStream; +class PublicsStream; +class GlobalsStream; +class SymbolStream; +} // namespace pdb +} // namespace llvm + +namespace lldb_private { +namespace npdb { +struct SegmentOffset; + +/// PdbIndex - Lazy access to the important parts of a PDB file. +/// +/// This is a layer on top of LLVM's native PDB support libraries which cache +/// certain data when it is accessed the first time. The entire PDB file is +/// mapped into memory, and the underlying support libraries vend out memory +/// that is always backed by the file, so it is safe to hold StringRefs and +/// ArrayRefs into the backing memory as long as the PdbIndex instance is +/// alive. +class PdbIndex { + + /// The underlying PDB file. + std::unique_ptr m_file; + + /// The DBI stream. This contains general high level information about the + /// features present in the PDB file, compile units (such as the information + /// necessary to locate full symbol information for each compile unit), + /// section contributions, and other data which is not specifically symbol or + /// type records. + llvm::pdb::DbiStream *m_dbi = nullptr; + + /// TPI (types) and IPI (indices) streams. These are both in the exact same + /// format with different data. Most type records are stored in the TPI + /// stream but certain specific types of records are stored in the IPI stream. + /// The IPI stream records can refer to the records in the TPI stream, but not + /// the other way around. + llvm::pdb::TpiStream *m_tpi = nullptr; + llvm::pdb::TpiStream *m_ipi = nullptr; + + /// This is called the "PDB Stream" in the Microsoft reference implementation. + /// It contains information about the structure of the file, as well as fields + /// used to match EXE and PDB. + llvm::pdb::InfoStream *m_info = nullptr; + + /// Publics stream. Is actually a serialized hash table where the keys are + /// addresses of symbols in the executable, and values are a record containing + /// mangled names and an index which can be used to locate more detailed info + /// about the symbol in the Symbol Records stream. The publics stream only + /// contains info about externally visible symbols. + llvm::pdb::PublicsStream *m_publics = nullptr; + + /// Globals stream. Contrary to its name, this does not contain information + /// about all "global variables" or "global functions". Rather, it is the + /// "global symbol table", i.e. it contains information about *every* symbol + /// in the executable. It is a hash table keyed on name, whose values are + /// indices into the symbol records stream to find the full record. + llvm::pdb::GlobalsStream *m_globals = nullptr; + + /// Symbol records stream. The publics and globals stream refer to records + /// in this stream. For some records, like constants and typedefs, the + /// complete record lives in this stream. For other symbol types, such as + /// functions, data, and other things that have been materialied into a + /// specific compile unit, the records here simply provide a reference + /// necessary to locate the full information. + llvm::pdb::SymbolStream *m_symrecords = nullptr; + + /// Index of all compile units, mapping identifier to |CompilandIndexItem| + /// instance. + CompileUnitIndex m_cus; + + /// An allocator for the interval maps + llvm::IntervalMap::Allocator m_allocator; + + /// Maps virtual address to module index + llvm::IntervalMap m_va_to_modi; + + /// The address at which the program has been loaded into memory. + lldb::addr_t m_load_address = 0; + + PdbIndex(); + + void BuildAddrToSymbolMap(CompilandIndexItem &cci); + +public: + static llvm::Expected> + create(std::unique_ptr); + + void SetLoadAddress(lldb::addr_t addr) { m_load_address = addr; } + void ParseSectionContribs(); + + llvm::pdb::PDBFile &pdb() { return *m_file; } + const llvm::pdb::PDBFile &pdb() const { return *m_file; } + + llvm::pdb::DbiStream &dbi() { return *m_dbi; } + const llvm::pdb::DbiStream &dbi() const { return *m_dbi; } + + llvm::pdb::TpiStream &tpi() { return *m_tpi; } + const llvm::pdb::TpiStream &tpi() const { return *m_tpi; } + + llvm::pdb::TpiStream &ipi() { return *m_ipi; } + const llvm::pdb::TpiStream &ipi() const { return *m_ipi; } + + llvm::pdb::InfoStream &info() { return *m_info; } + const llvm::pdb::InfoStream &info() const { return *m_info; } + + llvm::pdb::PublicsStream &publics() { return *m_publics; } + const llvm::pdb::PublicsStream &publics() const { return *m_publics; } + + llvm::pdb::GlobalsStream &globals() { return *m_globals; } + const llvm::pdb::GlobalsStream &globals() const { return *m_globals; } + + llvm::pdb::SymbolStream &symrecords() { return *m_symrecords; } + const llvm::pdb::SymbolStream &symrecords() const { return *m_symrecords; } + + CompileUnitIndex &compilands() { return m_cus; } + const CompileUnitIndex &compilands() const { return m_cus; } + + lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const; + lldb::addr_t MakeVirtualAddress(const SegmentOffset &so) const; + + std::vector FindSymbolsByVa(lldb::addr_t va); + + llvm::codeview::CVSymbol ReadSymbolRecord(PdbCompilandSymId cu_sym) const; + llvm::codeview::CVSymbol ReadSymbolRecord(PdbGlobalSymId global) const; + + llvm::Optional GetModuleIndexForAddr(uint16_t segment, + uint32_t offset) const; + llvm::Optional GetModuleIndexForVa(lldb::addr_t va) const; +}; +} // namespace npdb +} // namespace lldb_private + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp new file mode 100644 index 000000000000..e5424568da47 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.cpp @@ -0,0 +1,161 @@ +//===-- PdbSymUid.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PdbSymUid.h" + +using namespace lldb_private; +using namespace lldb_private::npdb; +using namespace llvm::codeview; + +namespace { +struct GenericIdRepr { + uint64_t tag : 4; + uint64_t data : 60; +}; + +struct CompilandIdRepr { + uint64_t tag : 4; + uint64_t modi : 16; + uint64_t unused : 44; +}; + +struct CompilandSymIdRepr { + uint64_t tag : 4; + uint64_t modi : 16; + uint64_t offset : 32; + uint64_t unused : 12; +}; + +struct GlobalSymIdRepr { + uint64_t tag : 4; + uint64_t offset : 32; + uint64_t pub : 1; + uint64_t unused : 27; +}; + +struct TypeSymIdRepr { + uint64_t tag : 4; + uint64_t index : 32; + uint64_t ipi : 1; + uint64_t unused : 27; +}; + +struct FieldListMemberIdRepr { + uint64_t tag : 4; + uint64_t index : 32; + uint64_t offset : 16; + uint64_t unused : 12; +}; + +static_assert(sizeof(CompilandIdRepr) == 8, "Invalid structure size!"); +static_assert(sizeof(CompilandSymIdRepr) == 8, "Invalid structure size!"); +static_assert(sizeof(GlobalSymIdRepr) == 8, "Invalid structure size!"); +static_assert(sizeof(TypeSymIdRepr) == 8, "Invalid structure size!"); +static_assert(sizeof(FieldListMemberIdRepr) == 8, "Invalid structure size!"); +} // namespace + +template static OutT repr_cast(const InT &value) { + OutT result; + ::memcpy(&result, &value, sizeof(value)); + return result; +} + +PdbSymUid::PdbSymUid(const PdbCompilandId &cid) { + CompilandIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.modi = cid.modi; + repr.tag = static_cast(PdbSymUidKind::Compiland); + m_repr = repr_cast(repr); +} + +PdbSymUid::PdbSymUid(const PdbCompilandSymId &csid) { + CompilandSymIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.modi = csid.modi; + repr.offset = csid.offset; + repr.tag = static_cast(PdbSymUidKind::CompilandSym); + m_repr = repr_cast(repr); +} + +PdbSymUid::PdbSymUid(const PdbGlobalSymId &gsid) { + GlobalSymIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.pub = gsid.is_public; + repr.offset = gsid.offset; + repr.tag = static_cast(PdbSymUidKind::GlobalSym); + m_repr = repr_cast(repr); +} + +PdbSymUid::PdbSymUid(const PdbTypeSymId &tsid) { + TypeSymIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.index = tsid.index.getIndex(); + repr.ipi = tsid.is_ipi; + repr.tag = static_cast(PdbSymUidKind::Type); + m_repr = repr_cast(repr); +} + +PdbSymUid::PdbSymUid(const PdbFieldListMemberId &flmid) { + FieldListMemberIdRepr repr; + ::memset(&repr, 0, sizeof(repr)); + repr.index = flmid.index.getIndex(); + repr.offset = flmid.offset; + repr.tag = static_cast(PdbSymUidKind::FieldListMember); + m_repr = repr_cast(repr); +} + +PdbSymUidKind PdbSymUid::kind() const { + GenericIdRepr generic = repr_cast(m_repr); + return static_cast(generic.tag); +} + +PdbCompilandId PdbSymUid::asCompiland() const { + assert(kind() == PdbSymUidKind::Compiland); + auto repr = repr_cast(m_repr); + PdbCompilandId result; + result.modi = repr.modi; + return result; +} + +PdbCompilandSymId PdbSymUid::asCompilandSym() const { + assert(kind() == PdbSymUidKind::CompilandSym); + auto repr = repr_cast(m_repr); + PdbCompilandSymId result; + result.modi = repr.modi; + result.offset = repr.offset; + return result; +} + +PdbGlobalSymId PdbSymUid::asGlobalSym() const { + assert(kind() == PdbSymUidKind::GlobalSym || + kind() == PdbSymUidKind::PublicSym); + auto repr = repr_cast(m_repr); + PdbGlobalSymId result; + result.is_public = repr.pub; + result.offset = repr.offset; + return result; +} + +PdbTypeSymId PdbSymUid::asTypeSym() const { + assert(kind() == PdbSymUidKind::Type); + auto repr = repr_cast(m_repr); + PdbTypeSymId result; + result.index.setIndex(repr.index); + result.is_ipi = repr.ipi; + return result; +} + +PdbFieldListMemberId PdbSymUid::asFieldListMember() const { + assert(kind() == PdbSymUidKind::FieldListMember); + auto repr = repr_cast(m_repr); + PdbFieldListMemberId result; + result.index.setIndex(repr.index); + result.offset = repr.offset; + return result; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h new file mode 100644 index 000000000000..1166bee4e327 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h @@ -0,0 +1,126 @@ +//===-- PdbSymUid.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// A unique identification scheme for Pdb records. +// The scheme is to partition a 64-bit integer into an 8-bit tag field, which +// will contain some value from the PDB_SymType enumeration. The format of the +// other 48-bits depend on the tag, but must be sufficient to locate the +// corresponding entry in the underlying PDB file quickly. For example, for +// a compile unit, we use 2 bytes to represent the index, which allows fast +// access to the compile unit's information. +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H +#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBSYMUID_H + +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/Support/Compiler.h" + +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/lldb-types.h" + +namespace lldb_private { +namespace npdb { + +enum class PdbSymUidKind : uint8_t { + Compiland, + CompilandSym, + PublicSym, + GlobalSym, + Type, + FieldListMember +}; + +struct PdbCompilandId { + // 0-based index of module in PDB + uint16_t modi; +}; + +struct PdbCompilandSymId { + PdbCompilandSymId() = default; + PdbCompilandSymId(uint16_t modi, uint32_t offset) + : modi(modi), offset(offset) {} + // 0-based index of module in PDB + uint16_t modi = 0; + + // Offset of symbol's record in module stream. This is + // offset by 4 from the CVSymbolArray's notion of offset + // due to the debug magic at the beginning of the stream. + uint32_t offset = 0; +}; + +struct PdbGlobalSymId { + PdbGlobalSymId() = default; + PdbGlobalSymId(uint32_t offset, bool is_public) + : offset(offset), is_public(is_public) {} + + // Offset of symbol's record in globals or publics stream. + uint32_t offset = 0; + + // True if this symbol is in the public stream, false if it's in the globals + // stream. + bool is_public = false; +}; + +struct PdbTypeSymId { + PdbTypeSymId() = default; + PdbTypeSymId(llvm::codeview::TypeIndex index, bool is_ipi = false) + : index(index), is_ipi(is_ipi) {} + + // The index of the of the type in the TPI or IPI stream. + llvm::codeview::TypeIndex index; + + // True if this symbol comes from the IPI stream, false if it's from the TPI + // stream. + bool is_ipi = false; +}; + +struct PdbFieldListMemberId { + // The TypeIndex of the LF_FIELDLIST record. + llvm::codeview::TypeIndex index; + + // The offset from the beginning of the LF_FIELDLIST record to this record. + uint16_t offset = 0; +}; + +class PdbSymUid { + uint64_t m_repr = 0; + +public: + PdbSymUid() = default; + PdbSymUid(uint64_t repr) : m_repr(repr) {} + PdbSymUid(const PdbCompilandId &cid); + PdbSymUid(const PdbCompilandSymId &csid); + PdbSymUid(const PdbGlobalSymId &gsid); + PdbSymUid(const PdbTypeSymId &tsid); + PdbSymUid(const PdbFieldListMemberId &flmid); + + uint64_t toOpaqueId() const { return m_repr; } + + PdbSymUidKind kind() const; + + PdbCompilandId asCompiland() const; + PdbCompilandSymId asCompilandSym() const; + PdbGlobalSymId asGlobalSym() const; + PdbTypeSymId asTypeSym() const; + PdbFieldListMemberId asFieldListMember() const; +}; + +template uint64_t toOpaqueUid(const T &cid) { + return PdbSymUid(cid).toOpaqueId(); +} + +struct SymbolAndUid { + llvm::codeview::CVSymbol sym; + PdbSymUid uid; +}; +} // namespace npdb +} // namespace lldb_private + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp new file mode 100644 index 000000000000..317725dd250e --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -0,0 +1,750 @@ +//===-- PdbUtil.cpp ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "PdbUtil.h" + +#include "DWARFLocationExpression.h" +#include "PdbIndex.h" +#include "PdbSymUid.h" + +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" + +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/lldb-enumerations.h" + +using namespace lldb_private; +using namespace lldb_private::npdb; +using namespace llvm::codeview; +using namespace llvm::pdb; + +static Variable::RangeList +MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, + llvm::ArrayRef gaps) { + lldb::addr_t start = + index.MakeVirtualAddress(range.ISectStart, range.OffsetStart); + lldb::addr_t end = start + range.Range; + + Variable::RangeList result; + while (!gaps.empty()) { + const LocalVariableAddrGap &gap = gaps.front(); + + lldb::addr_t size = gap.GapStartOffset - start; + result.Append(start, size); + start += gap.Range; + gaps = gaps.drop_front(); + } + + result.Append(start, end); + return result; +} + +CVTagRecord CVTagRecord::create(CVType type) { + assert(IsTagRecord(type) && "type is not a tag record!"); + switch (type.kind()) { + case LF_CLASS: + case LF_STRUCTURE: + case LF_INTERFACE: { + ClassRecord cr; + llvm::cantFail(TypeDeserializer::deserializeAs(type, cr)); + return CVTagRecord(std::move(cr)); + } + case LF_UNION: { + UnionRecord ur; + llvm::cantFail(TypeDeserializer::deserializeAs(type, ur)); + return CVTagRecord(std::move(ur)); + } + case LF_ENUM: { + EnumRecord er; + llvm::cantFail(TypeDeserializer::deserializeAs(type, er)); + return CVTagRecord(std::move(er)); + } + default: + llvm_unreachable("Unreachable!"); + } +} + +CVTagRecord::CVTagRecord(ClassRecord &&c) + : cvclass(std::move(c)), + m_kind(cvclass.Kind == TypeRecordKind::Struct ? Struct : Class) {} +CVTagRecord::CVTagRecord(UnionRecord &&u) + : cvunion(std::move(u)), m_kind(Union) {} +CVTagRecord::CVTagRecord(EnumRecord &&e) : cvenum(std::move(e)), m_kind(Enum) {} + +PDB_SymType lldb_private::npdb::CVSymToPDBSym(SymbolKind kind) { + switch (kind) { + case S_COMPILE3: + case S_OBJNAME: + return PDB_SymType::CompilandDetails; + case S_ENVBLOCK: + return PDB_SymType::CompilandEnv; + case S_THUNK32: + case S_TRAMPOLINE: + return PDB_SymType::Thunk; + case S_COFFGROUP: + return PDB_SymType::CoffGroup; + case S_EXPORT: + return PDB_SymType::Export; + case S_LPROC32: + case S_GPROC32: + case S_LPROC32_DPC: + return PDB_SymType::Function; + case S_PUB32: + return PDB_SymType::PublicSymbol; + case S_INLINESITE: + return PDB_SymType::InlineSite; + case S_LOCAL: + case S_BPREL32: + case S_REGREL32: + case S_MANCONSTANT: + case S_CONSTANT: + case S_LDATA32: + case S_GDATA32: + case S_LMANDATA: + case S_GMANDATA: + case S_LTHREAD32: + case S_GTHREAD32: + return PDB_SymType::Data; + case S_BLOCK32: + return PDB_SymType::Block; + case S_LABEL32: + return PDB_SymType::Label; + case S_CALLSITEINFO: + return PDB_SymType::CallSite; + case S_HEAPALLOCSITE: + return PDB_SymType::HeapAllocationSite; + case S_CALLEES: + return PDB_SymType::Callee; + case S_CALLERS: + return PDB_SymType::Caller; + default: + lldbassert(false && "Invalid symbol record kind!"); + } + return PDB_SymType::None; +} + +PDB_SymType lldb_private::npdb::CVTypeToPDBType(TypeLeafKind kind) { + switch (kind) { + case LF_ARRAY: + return PDB_SymType::ArrayType; + case LF_ARGLIST: + return PDB_SymType::FunctionSig; + case LF_BCLASS: + return PDB_SymType::BaseClass; + case LF_BINTERFACE: + return PDB_SymType::BaseInterface; + case LF_CLASS: + case LF_STRUCTURE: + case LF_INTERFACE: + case LF_UNION: + return PDB_SymType::UDT; + case LF_POINTER: + return PDB_SymType::PointerType; + case LF_ENUM: + return PDB_SymType::Enum; + case LF_PROCEDURE: + return PDB_SymType::FunctionSig; + case LF_BITFIELD: + return PDB_SymType::BuiltinType; + default: + lldbassert(false && "Invalid type record kind!"); + } + return PDB_SymType::None; +} + +bool lldb_private::npdb::SymbolHasAddress(const CVSymbol &sym) { + switch (sym.kind()) { + case S_GPROC32: + case S_LPROC32: + case S_GPROC32_ID: + case S_LPROC32_ID: + case S_LPROC32_DPC: + case S_LPROC32_DPC_ID: + case S_THUNK32: + case S_TRAMPOLINE: + case S_COFFGROUP: + case S_BLOCK32: + case S_LABEL32: + case S_CALLSITEINFO: + case S_HEAPALLOCSITE: + case S_LDATA32: + case S_GDATA32: + case S_LMANDATA: + case S_GMANDATA: + case S_LTHREAD32: + case S_GTHREAD32: + return true; + default: + return false; + } +} + +bool lldb_private::npdb::SymbolIsCode(const CVSymbol &sym) { + switch (sym.kind()) { + case S_GPROC32: + case S_LPROC32: + case S_GPROC32_ID: + case S_LPROC32_ID: + case S_LPROC32_DPC: + case S_LPROC32_DPC_ID: + case S_THUNK32: + case S_TRAMPOLINE: + case S_COFFGROUP: + case S_BLOCK32: + return true; + default: + return false; + } +} + +template RecordT createRecord(const CVSymbol &sym) { + RecordT record(static_cast(sym.kind())); + cantFail(SymbolDeserializer::deserializeAs(sym, record)); + return record; +} + +template +static SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { + RecordT record = createRecord(sym); + return {record.Segment, record.CodeOffset}; +} + +template <> +SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { + TrampolineSym record = createRecord(sym); + return {record.ThunkSection, record.ThunkOffset}; +} + +template <> SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { + Thunk32Sym record = createRecord(sym); + return {record.Segment, record.Offset}; +} + +template <> +SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { + CoffGroupSym record = createRecord(sym); + return {record.Segment, record.Offset}; +} + +template <> SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { + DataSym record = createRecord(sym); + return {record.Segment, record.DataOffset}; +} + +template <> +SegmentOffset GetSegmentAndOffset(const CVSymbol &sym) { + ThreadLocalDataSym record = createRecord(sym); + return {record.Segment, record.DataOffset}; +} + +SegmentOffset lldb_private::npdb::GetSegmentAndOffset(const CVSymbol &sym) { + switch (sym.kind()) { + case S_GPROC32: + case S_LPROC32: + case S_GPROC32_ID: + case S_LPROC32_ID: + case S_LPROC32_DPC: + case S_LPROC32_DPC_ID: + return ::GetSegmentAndOffset(sym); + case S_THUNK32: + return ::GetSegmentAndOffset(sym); + break; + case S_TRAMPOLINE: + return ::GetSegmentAndOffset(sym); + break; + case S_COFFGROUP: + return ::GetSegmentAndOffset(sym); + break; + case S_BLOCK32: + return ::GetSegmentAndOffset(sym); + break; + case S_LABEL32: + return ::GetSegmentAndOffset(sym); + break; + case S_CALLSITEINFO: + return ::GetSegmentAndOffset(sym); + break; + case S_HEAPALLOCSITE: + return ::GetSegmentAndOffset(sym); + break; + case S_LDATA32: + case S_GDATA32: + case S_LMANDATA: + case S_GMANDATA: + return ::GetSegmentAndOffset(sym); + break; + case S_LTHREAD32: + case S_GTHREAD32: + return ::GetSegmentAndOffset(sym); + break; + default: + lldbassert(false && "Record does not have a segment/offset!"); + } + return {0, 0}; +} + +template +SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) { + RecordT record = createRecord(sym); + return {record.Segment, record.CodeOffset, record.CodeSize}; +} + +template <> +SegmentOffsetLength +GetSegmentOffsetAndLength(const CVSymbol &sym) { + TrampolineSym record = createRecord(sym); + return {record.ThunkSection, record.ThunkOffset, record.Size}; +} + +template <> +SegmentOffsetLength GetSegmentOffsetAndLength(const CVSymbol &sym) { + Thunk32Sym record = createRecord(sym); + return SegmentOffsetLength{record.Segment, record.Offset, record.Length}; +} + +template <> +SegmentOffsetLength +GetSegmentOffsetAndLength(const CVSymbol &sym) { + CoffGroupSym record = createRecord(sym); + return SegmentOffsetLength{record.Segment, record.Offset, record.Size}; +} + +SegmentOffsetLength +lldb_private::npdb::GetSegmentOffsetAndLength(const CVSymbol &sym) { + switch (sym.kind()) { + case S_GPROC32: + case S_LPROC32: + case S_GPROC32_ID: + case S_LPROC32_ID: + case S_LPROC32_DPC: + case S_LPROC32_DPC_ID: + return ::GetSegmentOffsetAndLength(sym); + case S_THUNK32: + return ::GetSegmentOffsetAndLength(sym); + break; + case S_TRAMPOLINE: + return ::GetSegmentOffsetAndLength(sym); + break; + case S_COFFGROUP: + return ::GetSegmentOffsetAndLength(sym); + break; + case S_BLOCK32: + return ::GetSegmentOffsetAndLength(sym); + break; + default: + lldbassert(false && "Record does not have a segment/offset/length triple!"); + } + return {0, 0, 0}; +} + +bool lldb_private::npdb::IsForwardRefUdt(CVType cvt) { + ClassRecord cr; + UnionRecord ur; + EnumRecord er; + switch (cvt.kind()) { + case LF_CLASS: + case LF_STRUCTURE: + case LF_INTERFACE: + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, cr)); + return cr.isForwardRef(); + case LF_UNION: + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ur)); + return ur.isForwardRef(); + case LF_ENUM: + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, er)); + return er.isForwardRef(); + default: + return false; + } +} + +bool lldb_private::npdb::IsTagRecord(llvm::codeview::CVType cvt) { + switch (cvt.kind()) { + case LF_CLASS: + case LF_STRUCTURE: + case LF_UNION: + case LF_ENUM: + return true; + default: + return false; + } +} + +bool lldb_private::npdb::IsClassStructUnion(llvm::codeview::CVType cvt) { + switch (cvt.kind()) { + case LF_CLASS: + case LF_STRUCTURE: + case LF_UNION: + return true; + default: + return false; + } +} + +bool lldb_private::npdb::IsForwardRefUdt(const PdbTypeSymId &id, + TpiStream &tpi) { + if (id.is_ipi || id.index.isSimple()) + return false; + return IsForwardRefUdt(tpi.getType(id.index)); +} + +bool lldb_private::npdb::IsTagRecord(const PdbTypeSymId &id, TpiStream &tpi) { + if (id.is_ipi || id.index.isSimple()) + return false; + return IsTagRecord(tpi.getType(id.index)); +} + +lldb::AccessType +lldb_private::npdb::TranslateMemberAccess(MemberAccess access) { + switch (access) { + case MemberAccess::Private: + return lldb::eAccessPrivate; + case MemberAccess::Protected: + return lldb::eAccessProtected; + case MemberAccess::Public: + return lldb::eAccessPublic; + case MemberAccess::None: + return lldb::eAccessNone; + } + llvm_unreachable("unreachable"); +} + +TypeIndex lldb_private::npdb::GetFieldListIndex(CVType cvt) { + switch (cvt.kind()) { + case LF_CLASS: + case LF_STRUCTURE: + case LF_INTERFACE: { + ClassRecord cr; + cantFail(TypeDeserializer::deserializeAs(cvt, cr)); + return cr.FieldList; + } + case LF_UNION: { + UnionRecord ur; + cantFail(TypeDeserializer::deserializeAs(cvt, ur)); + return ur.FieldList; + } + case LF_ENUM: { + EnumRecord er; + cantFail(TypeDeserializer::deserializeAs(cvt, er)); + return er.FieldList; + } + default: + llvm_unreachable("Unreachable!"); + } +} + +TypeIndex lldb_private::npdb::LookThroughModifierRecord(CVType modifier) { + lldbassert(modifier.kind() == LF_MODIFIER); + ModifierRecord mr; + llvm::cantFail(TypeDeserializer::deserializeAs(modifier, mr)); + return mr.ModifiedType; +} + +llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) { + return MSVCUndecoratedNameParser::DropScope(name); +} + +VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) { + VariableInfo result; + + if (sym.kind() == S_REGREL32) { + RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); + cantFail(SymbolDeserializer::deserializeAs(sym, reg)); + result.type = reg.Type; + result.name = reg.Name; + return result; + } + + if (sym.kind() == S_REGISTER) { + RegisterSym reg(SymbolRecordKind::RegisterSym); + cantFail(SymbolDeserializer::deserializeAs(sym, reg)); + result.type = reg.Index; + result.name = reg.Name; + return result; + } + + if (sym.kind() == S_LOCAL) { + LocalSym local(SymbolRecordKind::LocalSym); + cantFail(SymbolDeserializer::deserializeAs(sym, local)); + result.type = local.Type; + result.name = local.Name; + return result; + } + + if (sym.kind() == S_GDATA32 || sym.kind() == S_LDATA32) { + DataSym data(SymbolRecordKind::DataSym); + cantFail(SymbolDeserializer::deserializeAs(sym, data)); + result.type = data.Type; + result.name = data.Name; + return result; + } + + if (sym.kind() == S_GTHREAD32 || sym.kind() == S_LTHREAD32) { + ThreadLocalDataSym data(SymbolRecordKind::ThreadLocalDataSym); + cantFail(SymbolDeserializer::deserializeAs(sym, data)); + result.type = data.Type; + result.name = data.Name; + return result; + } + + if (sym.kind() == S_CONSTANT) { + ConstantSym constant(SymbolRecordKind::ConstantSym); + cantFail(SymbolDeserializer::deserializeAs(sym, constant)); + result.type = constant.Type; + result.name = constant.Name; + return result; + } + + lldbassert(false && "Invalid variable record kind!"); + return {}; +} + +VariableInfo lldb_private::npdb::GetVariableLocationInfo( + PdbIndex &index, PdbCompilandSymId var_id, lldb::ModuleSP module) { + + CVSymbol sym = index.ReadSymbolRecord(var_id); + + VariableInfo result = GetVariableNameInfo(sym); + + if (sym.kind() == S_REGREL32) { + RegRelativeSym reg(SymbolRecordKind::RegRelativeSym); + cantFail(SymbolDeserializer::deserializeAs(sym, reg)); + result.location = + MakeRegRelLocationExpression(reg.Register, reg.Offset, module); + result.ranges.emplace(); + return result; + } + + if (sym.kind() == S_REGISTER) { + RegisterSym reg(SymbolRecordKind::RegisterSym); + cantFail(SymbolDeserializer::deserializeAs(sym, reg)); + result.location = MakeEnregisteredLocationExpression(reg.Register, module); + result.ranges.emplace(); + return result; + } + + if (sym.kind() == S_LOCAL) { + LocalSym local(SymbolRecordKind::LocalSym); + cantFail(SymbolDeserializer::deserializeAs(sym, local)); + + PdbCompilandSymId loc_specifier_id(var_id.modi, + var_id.offset + sym.RecordData.size()); + CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); + if (loc_specifier_cvs.kind() == S_DEFRANGE_FRAMEPOINTER_REL) { + DefRangeFramePointerRelSym loc( + SymbolRecordKind::DefRangeFramePointerRelSym); + cantFail(SymbolDeserializer::deserializeAs( + loc_specifier_cvs, loc)); + // FIXME: The register needs to come from the S_FRAMEPROC symbol. + result.location = + MakeRegRelLocationExpression(RegisterId::RSP, loc.Offset, module); + result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); + } else { + // FIXME: Handle other kinds + } + return result; + } + llvm_unreachable("Symbol is not a local variable!"); + return result; +} + +lldb::BasicType +lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) { + switch (kind) { + case SimpleTypeKind::Boolean128: + case SimpleTypeKind::Boolean16: + case SimpleTypeKind::Boolean32: + case SimpleTypeKind::Boolean64: + case SimpleTypeKind::Boolean8: + return lldb::eBasicTypeBool; + case SimpleTypeKind::Byte: + case SimpleTypeKind::UnsignedCharacter: + return lldb::eBasicTypeUnsignedChar; + case SimpleTypeKind::NarrowCharacter: + return lldb::eBasicTypeChar; + case SimpleTypeKind::SignedCharacter: + case SimpleTypeKind::SByte: + return lldb::eBasicTypeSignedChar; + case SimpleTypeKind::Character16: + return lldb::eBasicTypeChar16; + case SimpleTypeKind::Character32: + return lldb::eBasicTypeChar32; + case SimpleTypeKind::Complex80: + return lldb::eBasicTypeLongDoubleComplex; + case SimpleTypeKind::Complex64: + return lldb::eBasicTypeDoubleComplex; + case SimpleTypeKind::Complex32: + return lldb::eBasicTypeFloatComplex; + case SimpleTypeKind::Float128: + case SimpleTypeKind::Float80: + return lldb::eBasicTypeLongDouble; + case SimpleTypeKind::Float64: + return lldb::eBasicTypeDouble; + case SimpleTypeKind::Float32: + return lldb::eBasicTypeFloat; + case SimpleTypeKind::Float16: + return lldb::eBasicTypeHalf; + case SimpleTypeKind::Int128: + return lldb::eBasicTypeInt128; + case SimpleTypeKind::Int64: + case SimpleTypeKind::Int64Quad: + return lldb::eBasicTypeLongLong; + case SimpleTypeKind::Int32: + return lldb::eBasicTypeInt; + case SimpleTypeKind::Int16: + case SimpleTypeKind::Int16Short: + return lldb::eBasicTypeShort; + case SimpleTypeKind::UInt128: + return lldb::eBasicTypeUnsignedInt128; + case SimpleTypeKind::UInt64: + case SimpleTypeKind::UInt64Quad: + return lldb::eBasicTypeUnsignedLongLong; + case SimpleTypeKind::HResult: + case SimpleTypeKind::UInt32: + return lldb::eBasicTypeUnsignedInt; + case SimpleTypeKind::UInt16: + case SimpleTypeKind::UInt16Short: + return lldb::eBasicTypeUnsignedShort; + case SimpleTypeKind::Int32Long: + return lldb::eBasicTypeLong; + case SimpleTypeKind::UInt32Long: + return lldb::eBasicTypeUnsignedLong; + case SimpleTypeKind::Void: + return lldb::eBasicTypeVoid; + case SimpleTypeKind::WideCharacter: + return lldb::eBasicTypeWChar; + default: + return lldb::eBasicTypeInvalid; + } +} + +size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) { + switch (kind) { + case SimpleTypeKind::Boolean128: + case SimpleTypeKind::Int128: + case SimpleTypeKind::UInt128: + case SimpleTypeKind::Float128: + return 16; + case SimpleTypeKind::Complex80: + case SimpleTypeKind::Float80: + return 10; + case SimpleTypeKind::Boolean64: + case SimpleTypeKind::Complex64: + case SimpleTypeKind::UInt64: + case SimpleTypeKind::UInt64Quad: + case SimpleTypeKind::Float64: + case SimpleTypeKind::Int64: + case SimpleTypeKind::Int64Quad: + return 8; + case SimpleTypeKind::Boolean32: + case SimpleTypeKind::Character32: + case SimpleTypeKind::Complex32: + case SimpleTypeKind::Float32: + case SimpleTypeKind::Int32: + case SimpleTypeKind::Int32Long: + case SimpleTypeKind::UInt32Long: + case SimpleTypeKind::HResult: + case SimpleTypeKind::UInt32: + return 4; + case SimpleTypeKind::Boolean16: + case SimpleTypeKind::Character16: + case SimpleTypeKind::Float16: + case SimpleTypeKind::Int16: + case SimpleTypeKind::Int16Short: + case SimpleTypeKind::UInt16: + case SimpleTypeKind::UInt16Short: + case SimpleTypeKind::WideCharacter: + return 2; + case SimpleTypeKind::Boolean8: + case SimpleTypeKind::Byte: + case SimpleTypeKind::UnsignedCharacter: + case SimpleTypeKind::NarrowCharacter: + case SimpleTypeKind::SignedCharacter: + case SimpleTypeKind::SByte: + return 1; + case SimpleTypeKind::Void: + default: + return 0; + } +} + +PdbTypeSymId lldb_private::npdb::GetBestPossibleDecl(PdbTypeSymId id, + TpiStream &tpi) { + if (id.index.isSimple()) + return id; + + CVType cvt = tpi.getType(id.index); + + // Only tag records have a best and a worst record. + if (!IsTagRecord(cvt)) + return id; + + // Tag records that are not forward decls are full decls, hence they are the + // best. + if (!IsForwardRefUdt(cvt)) + return id; + + return llvm::cantFail(tpi.findFullDeclForForwardRef(id.index)); +} + +template static size_t GetSizeOfTypeInternal(CVType cvt) { + RecordType record; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, record)); + return record.getSize(); +} + +size_t lldb_private::npdb::GetSizeOfType(PdbTypeSymId id, + llvm::pdb::TpiStream &tpi) { + if (id.index.isSimple()) { + switch (id.index.getSimpleMode()) { + case SimpleTypeMode::Direct: + return GetTypeSizeForSimpleKind(id.index.getSimpleKind()); + case SimpleTypeMode::NearPointer32: + case SimpleTypeMode::FarPointer32: + return 4; + case SimpleTypeMode::NearPointer64: + return 8; + case SimpleTypeMode::NearPointer128: + return 16; + default: + break; + } + return 0; + } + + TypeIndex index = id.index; + if (IsForwardRefUdt(index, tpi)) + index = llvm::cantFail(tpi.findFullDeclForForwardRef(index)); + + CVType cvt = tpi.getType(index); + switch (cvt.kind()) { + case LF_MODIFIER: + return GetSizeOfType({LookThroughModifierRecord(cvt)}, tpi); + case LF_ENUM: { + EnumRecord record; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, record)); + return GetSizeOfType({record.UnderlyingType}, tpi); + } + case LF_POINTER: + return GetSizeOfTypeInternal(cvt); + case LF_ARRAY: + return GetSizeOfTypeInternal(cvt); + case LF_CLASS: + case LF_STRUCTURE: + case LF_INTERFACE: + return GetSizeOfTypeInternal(cvt); + case LF_UNION: + return GetSizeOfTypeInternal(cvt); + default: + break; + } + return 0; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h new file mode 100644 index 000000000000..570c300b6a2b --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -0,0 +1,159 @@ +//===-- PdbUtil.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H +#define LLDB_PLUGINS_SYMBOLFILENATIVEPDB_PDBUTIL_H + +#include "lldb/Expression/DWARFExpression.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/lldb-enumerations.h" + +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +#include "PdbSymUid.h" + +#include +#include + +namespace llvm { +namespace pdb { +class TpiStream; +} +} // namespace llvm + +namespace lldb_private { +namespace npdb { + +class PdbIndex; + +struct CVTagRecord { + enum Kind { Class, Struct, Union, Enum }; + + static CVTagRecord create(llvm::codeview::CVType type); + + Kind kind() const { return m_kind; } + + const llvm::codeview::TagRecord &asTag() const { + if (m_kind == Struct || m_kind == Class) + return cvclass; + if (m_kind == Enum) + return cvenum; + return cvunion; + } + + const llvm::codeview::ClassRecord &asClass() const { + assert(m_kind == Struct || m_kind == Class); + return cvclass; + } + + const llvm::codeview::EnumRecord &asEnum() const { + assert(m_kind == Enum); + return cvenum; + } + + const llvm::codeview::UnionRecord &asUnion() const { + assert(m_kind == Union); + return cvunion; + } + + llvm::StringRef name() const { + if (m_kind == Struct || m_kind == Union) + return cvclass.Name; + if (m_kind == Enum) + return cvenum.Name; + return cvunion.Name; + } + +private: + CVTagRecord(llvm::codeview::ClassRecord &&c); + CVTagRecord(llvm::codeview::UnionRecord &&u); + CVTagRecord(llvm::codeview::EnumRecord &&e); + union { + llvm::codeview::ClassRecord cvclass; + llvm::codeview::EnumRecord cvenum; + llvm::codeview::UnionRecord cvunion; + }; + Kind m_kind; +}; + +struct SegmentOffset { + SegmentOffset() = default; + SegmentOffset(uint16_t s, uint32_t o) : segment(s), offset(o) {} + uint16_t segment = 0; + uint32_t offset = 0; +}; + +struct SegmentOffsetLength { + SegmentOffsetLength() = default; + SegmentOffsetLength(uint16_t s, uint32_t o, uint32_t l) + : so(s, o), length(l) {} + SegmentOffset so; + uint32_t length = 0; +}; + +struct VariableInfo { + llvm::StringRef name; + llvm::codeview::TypeIndex type; + llvm::Optional location; + llvm::Optional ranges; +}; + +llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind); +llvm::pdb::PDB_SymType CVTypeToPDBType(llvm::codeview::TypeLeafKind kind); + +bool SymbolHasAddress(const llvm::codeview::CVSymbol &sym); +bool SymbolIsCode(const llvm::codeview::CVSymbol &sym); + +SegmentOffset GetSegmentAndOffset(const llvm::codeview::CVSymbol &sym); +SegmentOffsetLength +GetSegmentOffsetAndLength(const llvm::codeview::CVSymbol &sym); + +template bool IsValidRecord(const RecordT &sym) { + return true; +} + +inline bool IsValidRecord(const llvm::codeview::ProcRefSym &sym) { + // S_PROCREF symbols have 1-based module indices. + return sym.Module > 0; +} + +bool IsForwardRefUdt(llvm::codeview::CVType cvt); +bool IsTagRecord(llvm::codeview::CVType cvt); +bool IsClassStructUnion(llvm::codeview::CVType cvt); + +bool IsForwardRefUdt(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); +bool IsTagRecord(const PdbTypeSymId &id, llvm::pdb::TpiStream &tpi); + +lldb::AccessType TranslateMemberAccess(llvm::codeview::MemberAccess access); +llvm::codeview::TypeIndex GetFieldListIndex(llvm::codeview::CVType cvt); +llvm::codeview::TypeIndex +LookThroughModifierRecord(llvm::codeview::CVType modifier); + +llvm::StringRef DropNameScope(llvm::StringRef name); + +VariableInfo GetVariableNameInfo(llvm::codeview::CVSymbol symbol); +VariableInfo GetVariableLocationInfo(PdbIndex &index, PdbCompilandSymId var_id, + lldb::ModuleSP module); + +size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind); +lldb::BasicType +GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind); + +PdbTypeSymId GetBestPossibleDecl(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); + +size_t GetSizeOfType(PdbTypeSymId id, llvm::pdb::TpiStream &tpi); + +} // namespace npdb +} // namespace lldb_private + +#endif diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp new file mode 100644 index 000000000000..7e97e2b37724 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -0,0 +1,1571 @@ +//===-- SymbolFileNativePDB.cpp ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SymbolFileNativePDB.h" + +#include "clang/AST/Attr.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/Type.h" + +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "lldb/Core/Module.h" +#include "lldb/Core/PluginManager.h" +#include "lldb/Core/StreamBuffer.h" +#include "lldb/Core/StreamFile.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangASTImporter.h" +#include "lldb/Symbol/ClangExternalASTSourceCommon.h" +#include "lldb/Symbol/ClangUtil.h" +#include "lldb/Symbol/CompileUnit.h" +#include "lldb/Symbol/LineTable.h" +#include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolContext.h" +#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/Variable.h" +#include "lldb/Symbol/VariableList.h" + +#include "llvm/DebugInfo/CodeView/CVRecord.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" +#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h" +#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h" +#include "llvm/DebugInfo/CodeView/RecordName.h" +#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" +#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/PDB/Native/DbiStream.h" +#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" +#include "llvm/DebugInfo/PDB/Native/InfoStream.h" +#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/SymbolStream.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/Demangle/MicrosoftDemangle.h" +#include "llvm/Object/COFF.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/MemoryBuffer.h" + +#include "DWARFLocationExpression.h" +#include "PdbAstBuilder.h" +#include "PdbSymUid.h" +#include "PdbUtil.h" +#include "UdtRecordCompleter.h" + +using namespace lldb; +using namespace lldb_private; +using namespace npdb; +using namespace llvm::codeview; +using namespace llvm::pdb; + +static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { + switch (lang) { + case PDB_Lang::Cpp: + return lldb::LanguageType::eLanguageTypeC_plus_plus; + case PDB_Lang::C: + return lldb::LanguageType::eLanguageTypeC; + default: + return lldb::LanguageType::eLanguageTypeUnknown; + } +} + +static std::unique_ptr loadPDBFile(std::string PdbPath, + llvm::BumpPtrAllocator &Allocator) { + llvm::ErrorOr> ErrorOrBuffer = + llvm::MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1, + /*RequiresNullTerminator=*/false); + if (!ErrorOrBuffer) + return nullptr; + std::unique_ptr Buffer = std::move(*ErrorOrBuffer); + + llvm::StringRef Path = Buffer->getBufferIdentifier(); + auto Stream = llvm::make_unique( + std::move(Buffer), llvm::support::little); + + auto File = llvm::make_unique(Path, std::move(Stream), Allocator); + if (auto EC = File->parseFileHeaders()) { + llvm::consumeError(std::move(EC)); + return nullptr; + } + if (auto EC = File->parseStreamData()) { + llvm::consumeError(std::move(EC)); + return nullptr; + } + + return File; +} + +static std::unique_ptr +loadMatchingPDBFile(std::string exe_path, llvm::BumpPtrAllocator &allocator) { + // Try to find a matching PDB for an EXE. + using namespace llvm::object; + auto expected_binary = createBinary(exe_path); + + // If the file isn't a PE/COFF executable, fail. + if (!expected_binary) { + llvm::consumeError(expected_binary.takeError()); + return nullptr; + } + OwningBinary binary = std::move(*expected_binary); + + auto *obj = llvm::dyn_cast(binary.getBinary()); + if (!obj) + return nullptr; + const llvm::codeview::DebugInfo *pdb_info = nullptr; + + // If it doesn't have a debug directory, fail. + llvm::StringRef pdb_file; + auto ec = obj->getDebugPDBInfo(pdb_info, pdb_file); + if (ec) + return nullptr; + + // if the file doesn't exist, is not a pdb, or doesn't have a matching guid, + // fail. + llvm::file_magic magic; + ec = llvm::identify_magic(pdb_file, magic); + if (ec || magic != llvm::file_magic::pdb) + return nullptr; + std::unique_ptr pdb = loadPDBFile(pdb_file, allocator); + if (!pdb) + return nullptr; + + auto expected_info = pdb->getPDBInfoStream(); + if (!expected_info) { + llvm::consumeError(expected_info.takeError()); + return nullptr; + } + llvm::codeview::GUID guid; + memcpy(&guid, pdb_info->PDB70.Signature, 16); + + if (expected_info->getGuid() != guid) + return nullptr; + return pdb; +} + +static bool IsFunctionPrologue(const CompilandIndexItem &cci, + lldb::addr_t addr) { + // FIXME: Implement this. + return false; +} + +static bool IsFunctionEpilogue(const CompilandIndexItem &cci, + lldb::addr_t addr) { + // FIXME: Implement this. + return false; +} + +static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) { + switch (kind) { + case SimpleTypeKind::Boolean128: + case SimpleTypeKind::Boolean16: + case SimpleTypeKind::Boolean32: + case SimpleTypeKind::Boolean64: + case SimpleTypeKind::Boolean8: + return "bool"; + case SimpleTypeKind::Byte: + case SimpleTypeKind::UnsignedCharacter: + return "unsigned char"; + case SimpleTypeKind::NarrowCharacter: + return "char"; + case SimpleTypeKind::SignedCharacter: + case SimpleTypeKind::SByte: + return "signed char"; + case SimpleTypeKind::Character16: + return "char16_t"; + case SimpleTypeKind::Character32: + return "char32_t"; + case SimpleTypeKind::Complex80: + case SimpleTypeKind::Complex64: + case SimpleTypeKind::Complex32: + return "complex"; + case SimpleTypeKind::Float128: + case SimpleTypeKind::Float80: + return "long double"; + case SimpleTypeKind::Float64: + return "double"; + case SimpleTypeKind::Float32: + return "float"; + case SimpleTypeKind::Float16: + return "single"; + case SimpleTypeKind::Int128: + return "__int128"; + case SimpleTypeKind::Int64: + case SimpleTypeKind::Int64Quad: + return "int64_t"; + case SimpleTypeKind::Int32: + return "int"; + case SimpleTypeKind::Int16: + return "short"; + case SimpleTypeKind::UInt128: + return "unsigned __int128"; + case SimpleTypeKind::UInt64: + case SimpleTypeKind::UInt64Quad: + return "uint64_t"; + case SimpleTypeKind::HResult: + return "HRESULT"; + case SimpleTypeKind::UInt32: + return "unsigned"; + case SimpleTypeKind::UInt16: + case SimpleTypeKind::UInt16Short: + return "unsigned short"; + case SimpleTypeKind::Int32Long: + return "long"; + case SimpleTypeKind::UInt32Long: + return "unsigned long"; + case SimpleTypeKind::Void: + return "void"; + case SimpleTypeKind::WideCharacter: + return "wchar_t"; + default: + return ""; + } +} + +static bool IsClassRecord(TypeLeafKind kind) { + switch (kind) { + case LF_STRUCTURE: + case LF_CLASS: + case LF_INTERFACE: + return true; + default: + return false; + } +} + +void SymbolFileNativePDB::Initialize() { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); +} + +void SymbolFileNativePDB::Terminate() { + PluginManager::UnregisterPlugin(CreateInstance); +} + +void SymbolFileNativePDB::DebuggerInitialize(Debugger &debugger) {} + +ConstString SymbolFileNativePDB::GetPluginNameStatic() { + static ConstString g_name("native-pdb"); + return g_name; +} + +const char *SymbolFileNativePDB::GetPluginDescriptionStatic() { + return "Microsoft PDB debug symbol cross-platform file reader."; +} + +SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFile *obj_file) { + return new SymbolFileNativePDB(obj_file); +} + +SymbolFileNativePDB::SymbolFileNativePDB(ObjectFile *object_file) + : SymbolFile(object_file) {} + +SymbolFileNativePDB::~SymbolFileNativePDB() {} + +uint32_t SymbolFileNativePDB::CalculateAbilities() { + uint32_t abilities = 0; + if (!m_obj_file) + return 0; + + if (!m_index) { + // Lazily load and match the PDB file, but only do this once. + std::unique_ptr file_up = + loadMatchingPDBFile(m_obj_file->GetFileSpec().GetPath(), m_allocator); + + if (!file_up) { + auto module_sp = m_obj_file->GetModule(); + if (!module_sp) + return 0; + // See if any symbol file is specified through `--symfile` option. + FileSpec symfile = module_sp->GetSymbolFileFileSpec(); + if (!symfile) + return 0; + file_up = loadPDBFile(symfile.GetPath(), m_allocator); + } + + if (!file_up) + return 0; + + auto expected_index = PdbIndex::create(std::move(file_up)); + if (!expected_index) { + llvm::consumeError(expected_index.takeError()); + return 0; + } + m_index = std::move(*expected_index); + } + if (!m_index) + return 0; + + // We don't especially have to be precise here. We only distinguish between + // stripped and not stripped. + abilities = kAllAbilities; + + if (m_index->dbi().isStripped()) + abilities &= ~(Blocks | LocalVariables); + return abilities; +} + +void SymbolFileNativePDB::InitializeObject() { + m_obj_load_address = m_obj_file->GetFileOffset(); + m_index->SetLoadAddress(m_obj_load_address); + m_index->ParseSectionContribs(); + + TypeSystem *ts = m_obj_file->GetModule()->GetTypeSystemForLanguage( + lldb::eLanguageTypeC_plus_plus); + if (ts) + ts->SetSymbolFile(this); + + m_ast = llvm::make_unique(*m_obj_file, *m_index); +} + +uint32_t SymbolFileNativePDB::GetNumCompileUnits() { + const DbiModuleList &modules = m_index->dbi().modules(); + uint32_t count = modules.getModuleCount(); + if (count == 0) + return count; + + // The linker can inject an additional "dummy" compilation unit into the + // PDB. Ignore this special compile unit for our purposes, if it is there. + // It is always the last one. + DbiModuleDescriptor last = modules.getModuleDescriptor(count - 1); + if (last.getModuleName() == "* Linker *") + --count; + return count; +} + +Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) { + CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); + CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); + + if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) { + // This is a function. It must be global. Creating the Function entry for + // it automatically creates a block for it. + CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii); + return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false); + } + + lldbassert(sym.kind() == S_BLOCK32); + + // This is a block. Its parent is either a function or another block. In + // either case, its parent can be viewed as a block (e.g. a function contains + // 1 big block. So just get the parent block and add this block to it. + BlockSym block(static_cast(sym.kind())); + cantFail(SymbolDeserializer::deserializeAs(sym, block)); + lldbassert(block.Parent != 0); + PdbCompilandSymId parent_id(block_id.modi, block.Parent); + Block &parent_block = GetOrCreateBlock(parent_id); + lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id); + BlockSP child_block = std::make_shared(opaque_block_uid); + parent_block.AddChild(child_block); + + m_ast->GetOrCreateBlockDecl(block_id); + + m_blocks.insert({opaque_block_uid, child_block}); + return *child_block; +} + +lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, + CompileUnit &comp_unit) { + const CompilandIndexItem *cci = + m_index->compilands().GetCompiland(func_id.modi); + lldbassert(cci); + CVSymbol sym_record = cci->m_debug_stream.readSymbolAtOffset(func_id.offset); + + lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); + SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); + + auto file_vm_addr = m_index->MakeVirtualAddress(sol.so); + if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) + return nullptr; + + AddressRange func_range(file_vm_addr, sol.length, + comp_unit.GetModule()->GetSectionList()); + if (!func_range.GetBaseAddress().IsValid()) + return nullptr; + + ProcSym proc(static_cast(sym_record.kind())); + cantFail(SymbolDeserializer::deserializeAs(sym_record, proc)); + if (proc.FunctionType == TypeIndex::None()) + return nullptr; + TypeSP func_type = GetOrCreateType(proc.FunctionType); + if (!func_type) + return nullptr; + + PdbTypeSymId sig_id(proc.FunctionType, false); + Mangled mangled(proc.Name); + FunctionSP func_sp = std::make_shared( + &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled, + func_type.get(), func_range); + + comp_unit.AddFunction(func_sp); + + m_ast->GetOrCreateFunctionDecl(func_id); + + return func_sp; +} + +CompUnitSP +SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { + lldb::LanguageType lang = + cci.m_compile_opts ? TranslateLanguage(cci.m_compile_opts->getLanguage()) + : lldb::eLanguageTypeUnknown; + + LazyBool optimized = eLazyBoolNo; + if (cci.m_compile_opts && cci.m_compile_opts->hasOptimizations()) + optimized = eLazyBoolYes; + + llvm::SmallString<64> source_file_name = + m_index->compilands().GetMainSourceFile(cci); + FileSpec fs(source_file_name); + + CompUnitSP cu_sp = + std::make_shared(m_obj_file->GetModule(), nullptr, fs, + toOpaqueUid(cci.m_id), lang, optimized); + + m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex( + cci.m_id.modi, cu_sp); + return cu_sp; +} + +lldb::TypeSP SymbolFileNativePDB::CreateModifierType(PdbTypeSymId type_id, + const ModifierRecord &mr, + CompilerType ct) { + TpiStream &stream = m_index->tpi(); + + std::string name; + if (mr.ModifiedType.isSimple()) + name = GetSimpleTypeName(mr.ModifiedType.getSimpleKind()); + else + name = computeTypeName(stream.typeCollection(), mr.ModifiedType); + Declaration decl; + lldb::TypeSP modified_type = GetOrCreateType(mr.ModifiedType); + + return std::make_shared(toOpaqueUid(type_id), this, ConstString(name), + modified_type->GetByteSize(), nullptr, + LLDB_INVALID_UID, Type::eEncodingIsUID, decl, + ct, Type::eResolveStateFull); +} + +lldb::TypeSP +SymbolFileNativePDB::CreatePointerType(PdbTypeSymId type_id, + const llvm::codeview::PointerRecord &pr, + CompilerType ct) { + TypeSP pointee = GetOrCreateType(pr.ReferentType); + if (!pointee) + return nullptr; + + if (pr.isPointerToMember()) { + MemberPointerInfo mpi = pr.getMemberInfo(); + GetOrCreateType(mpi.ContainingType); + } + + Declaration decl; + return std::make_shared(toOpaqueUid(type_id), this, ConstString(), + pr.getSize(), nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, ct, + Type::eResolveStateFull); +} + +lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti, + CompilerType ct) { + uint64_t uid = toOpaqueUid(PdbTypeSymId(ti, false)); + if (ti == TypeIndex::NullptrT()) { + Declaration decl; + return std::make_shared( + uid, this, ConstString("std::nullptr_t"), 0, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull); + } + + if (ti.getSimpleMode() != SimpleTypeMode::Direct) { + TypeSP direct_sp = GetOrCreateType(ti.makeDirect()); + uint32_t pointer_size = 0; + switch (ti.getSimpleMode()) { + case SimpleTypeMode::FarPointer32: + case SimpleTypeMode::NearPointer32: + pointer_size = 4; + break; + case SimpleTypeMode::NearPointer64: + pointer_size = 8; + break; + default: + // 128-bit and 16-bit pointers unsupported. + return nullptr; + } + Declaration decl; + return std::make_shared( + uid, this, ConstString(), pointer_size, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, ct, Type::eResolveStateFull); + } + + if (ti.getSimpleKind() == SimpleTypeKind::NotTranslated) + return nullptr; + + size_t size = GetTypeSizeForSimpleKind(ti.getSimpleKind()); + llvm::StringRef type_name = GetSimpleTypeName(ti.getSimpleKind()); + + Declaration decl; + return std::make_shared(uid, this, ConstString(type_name), size, + nullptr, LLDB_INVALID_UID, Type::eEncodingIsUID, + decl, ct, Type::eResolveStateFull); +} + +static std::string GetUnqualifiedTypeName(const TagRecord &record) { + if (!record.hasUniqueName()) { + MSVCUndecoratedNameParser parser(record.Name); + llvm::ArrayRef specs = parser.GetSpecifiers(); + + return specs.back().GetBaseName(); + } + + llvm::ms_demangle::Demangler demangler; + StringView sv(record.UniqueName.begin(), record.UniqueName.size()); + llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); + if (demangler.Error) + return record.Name; + + llvm::ms_demangle::IdentifierNode *idn = + ttn->QualifiedName->getUnqualifiedIdentifier(); + return idn->toString(); +} + +lldb::TypeSP +SymbolFileNativePDB::CreateClassStructUnion(PdbTypeSymId type_id, + const TagRecord &record, + size_t size, CompilerType ct) { + + std::string uname = GetUnqualifiedTypeName(record); + + // FIXME: Search IPI stream for LF_UDT_MOD_SRC_LINE. + Declaration decl; + return std::make_shared(toOpaqueUid(type_id), this, ConstString(uname), + size, nullptr, LLDB_INVALID_UID, + Type::eEncodingIsUID, decl, ct, + Type::eResolveStateForward); +} + +lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, + const ClassRecord &cr, + CompilerType ct) { + return CreateClassStructUnion(type_id, cr, cr.getSize(), ct); +} + +lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, + const UnionRecord &ur, + CompilerType ct) { + return CreateClassStructUnion(type_id, ur, ur.getSize(), ct); +} + +lldb::TypeSP SymbolFileNativePDB::CreateTagType(PdbTypeSymId type_id, + const EnumRecord &er, + CompilerType ct) { + std::string uname = GetUnqualifiedTypeName(er); + + Declaration decl; + TypeSP underlying_type = GetOrCreateType(er.UnderlyingType); + + return std::make_shared( + toOpaqueUid(type_id), this, ConstString(uname), + underlying_type->GetByteSize(), nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, decl, ct, + lldb_private::Type::eResolveStateForward); +} + +TypeSP SymbolFileNativePDB::CreateArrayType(PdbTypeSymId type_id, + const ArrayRecord &ar, + CompilerType ct) { + TypeSP element_type = GetOrCreateType(ar.ElementType); + + Declaration decl; + TypeSP array_sp = std::make_shared( + toOpaqueUid(type_id), this, ConstString(), ar.Size, nullptr, + LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, ct, + lldb_private::Type::eResolveStateFull); + array_sp->SetEncodingType(element_type.get()); + return array_sp; +} + +TypeSP SymbolFileNativePDB::CreateProcedureType(PdbTypeSymId type_id, + const ProcedureRecord &pr, + CompilerType ct) { + Declaration decl; + return std::make_shared( + toOpaqueUid(type_id), this, ConstString(), 0, nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, decl, ct, + lldb_private::Type::eResolveStateFull); +} + +TypeSP SymbolFileNativePDB::CreateType(PdbTypeSymId type_id, CompilerType ct) { + if (type_id.index.isSimple()) + return CreateSimpleType(type_id.index, ct); + + TpiStream &stream = type_id.is_ipi ? m_index->ipi() : m_index->tpi(); + CVType cvt = stream.getType(type_id.index); + + if (cvt.kind() == LF_MODIFIER) { + ModifierRecord modifier; + llvm::cantFail( + TypeDeserializer::deserializeAs(cvt, modifier)); + return CreateModifierType(type_id, modifier, ct); + } + + if (cvt.kind() == LF_POINTER) { + PointerRecord pointer; + llvm::cantFail( + TypeDeserializer::deserializeAs(cvt, pointer)); + return CreatePointerType(type_id, pointer, ct); + } + + if (IsClassRecord(cvt.kind())) { + ClassRecord cr; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, cr)); + return CreateTagType(type_id, cr, ct); + } + + if (cvt.kind() == LF_ENUM) { + EnumRecord er; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, er)); + return CreateTagType(type_id, er, ct); + } + + if (cvt.kind() == LF_UNION) { + UnionRecord ur; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ur)); + return CreateTagType(type_id, ur, ct); + } + + if (cvt.kind() == LF_ARRAY) { + ArrayRecord ar; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, ar)); + return CreateArrayType(type_id, ar, ct); + } + + if (cvt.kind() == LF_PROCEDURE) { + ProcedureRecord pr; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, pr)); + return CreateProcedureType(type_id, pr, ct); + } + + return nullptr; +} + +TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) { + // If they search for a UDT which is a forward ref, try and resolve the full + // decl and just map the forward ref uid to the full decl record. + llvm::Optional full_decl_uid; + if (IsForwardRefUdt(type_id, m_index->tpi())) { + auto expected_full_ti = + m_index->tpi().findFullDeclForForwardRef(type_id.index); + if (!expected_full_ti) + llvm::consumeError(expected_full_ti.takeError()); + else if (*expected_full_ti != type_id.index) { + full_decl_uid = PdbTypeSymId(*expected_full_ti, false); + + // It's possible that a lookup would occur for the full decl causing it + // to be cached, then a second lookup would occur for the forward decl. + // We don't want to create a second full decl, so make sure the full + // decl hasn't already been cached. + auto full_iter = m_types.find(toOpaqueUid(*full_decl_uid)); + if (full_iter != m_types.end()) { + TypeSP result = full_iter->second; + // Map the forward decl to the TypeSP for the full decl so we can take + // the fast path next time. + m_types[toOpaqueUid(type_id)] = result; + return result; + } + } + } + + PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id; + + clang::QualType qt = m_ast->GetOrCreateType(best_decl_id); + + TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt)); + if (!result) + return nullptr; + + uint64_t best_uid = toOpaqueUid(best_decl_id); + m_types[best_uid] = result; + // If we had both a forward decl and a full decl, make both point to the new + // type. + if (full_decl_uid) + m_types[toOpaqueUid(type_id)] = result; + + return result; +} + +TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) { + // We can't use try_emplace / overwrite here because the process of creating + // a type could create nested types, which could invalidate iterators. So + // we have to do a 2-phase lookup / insert. + auto iter = m_types.find(toOpaqueUid(type_id)); + if (iter != m_types.end()) + return iter->second; + + TypeSP type = CreateAndCacheType(type_id); + if (type) + m_obj_file->GetModule()->GetTypeList()->Insert(type); + return type; +} + +VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { + CVSymbol sym = m_index->symrecords().readRecord(var_id.offset); + if (sym.kind() == S_CONSTANT) + return CreateConstantSymbol(var_id, sym); + + lldb::ValueType scope = eValueTypeInvalid; + TypeIndex ti; + llvm::StringRef name; + lldb::addr_t addr = 0; + uint16_t section = 0; + uint32_t offset = 0; + bool is_external = false; + switch (sym.kind()) { + case S_GDATA32: + is_external = true; + LLVM_FALLTHROUGH; + case S_LDATA32: { + DataSym ds(sym.kind()); + llvm::cantFail(SymbolDeserializer::deserializeAs(sym, ds)); + ti = ds.Type; + scope = (sym.kind() == S_GDATA32) ? eValueTypeVariableGlobal + : eValueTypeVariableStatic; + name = ds.Name; + section = ds.Segment; + offset = ds.DataOffset; + addr = m_index->MakeVirtualAddress(ds.Segment, ds.DataOffset); + break; + } + case S_GTHREAD32: + is_external = true; + LLVM_FALLTHROUGH; + case S_LTHREAD32: { + ThreadLocalDataSym tlds(sym.kind()); + llvm::cantFail( + SymbolDeserializer::deserializeAs(sym, tlds)); + ti = tlds.Type; + name = tlds.Name; + section = tlds.Segment; + offset = tlds.DataOffset; + addr = m_index->MakeVirtualAddress(tlds.Segment, tlds.DataOffset); + scope = eValueTypeVariableThreadLocal; + break; + } + default: + llvm_unreachable("unreachable!"); + } + + CompUnitSP comp_unit; + llvm::Optional modi = m_index->GetModuleIndexForVa(addr); + if (modi) { + CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); + comp_unit = GetOrCreateCompileUnit(cci); + } + + Declaration decl; + PdbTypeSymId tid(ti, false); + SymbolFileTypeSP type_sp = + std::make_shared(*this, toOpaqueUid(tid)); + Variable::RangeList ranges; + + m_ast->GetOrCreateVariableDecl(var_id); + + DWARFExpression location = MakeGlobalLocationExpression( + section, offset, GetObjectFile()->GetModule()); + + std::string global_name("::"); + global_name += name; + VariableSP var_sp = std::make_shared( + toOpaqueUid(var_id), name.str().c_str(), global_name.c_str(), type_sp, + scope, comp_unit.get(), ranges, &decl, location, is_external, false, + false); + var_sp->SetLocationIsConstantValueData(false); + + return var_sp; +} + +lldb::VariableSP +SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, + const CVSymbol &cvs) { + TpiStream &tpi = m_index->tpi(); + ConstantSym constant(cvs.kind()); + + llvm::cantFail(SymbolDeserializer::deserializeAs(cvs, constant)); + std::string global_name("::"); + global_name += constant.Name; + PdbTypeSymId tid(constant.Type, false); + SymbolFileTypeSP type_sp = + std::make_shared(*this, toOpaqueUid(tid)); + + Declaration decl; + Variable::RangeList ranges; + ModuleSP module = GetObjectFile()->GetModule(); + DWARFExpression location = MakeConstantLocationExpression( + constant.Type, tpi, constant.Value, module); + + VariableSP var_sp = std::make_shared( + toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), + type_sp, eValueTypeVariableGlobal, module.get(), ranges, &decl, location, + false, false, false); + var_sp->SetLocationIsConstantValueData(true); + return var_sp; +} + +VariableSP +SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) { + auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr); + if (emplace_result.second) + emplace_result.first->second = CreateGlobalVariable(var_id); + + return emplace_result.first->second; +} + +lldb::TypeSP SymbolFileNativePDB::GetOrCreateType(TypeIndex ti) { + return GetOrCreateType(PdbTypeSymId(ti, false)); +} + +FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id, + CompileUnit &comp_unit) { + auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr); + if (emplace_result.second) + emplace_result.first->second = CreateFunction(func_id, comp_unit); + + return emplace_result.first->second; +} + +CompUnitSP +SymbolFileNativePDB::GetOrCreateCompileUnit(const CompilandIndexItem &cci) { + + auto emplace_result = + m_compilands.try_emplace(toOpaqueUid(cci.m_id), nullptr); + if (emplace_result.second) + emplace_result.first->second = CreateCompileUnit(cci); + + lldbassert(emplace_result.first->second); + return emplace_result.first->second; +} + +Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) { + auto iter = m_blocks.find(toOpaqueUid(block_id)); + if (iter != m_blocks.end()) + return *iter->second; + + return CreateBlock(block_id); +} + +void SymbolFileNativePDB::ParseDeclsForContext( + lldb_private::CompilerDeclContext decl_ctx) { + clang::DeclContext *context = m_ast->FromCompilerDeclContext(decl_ctx); + if (!context) + return; + m_ast->ParseDeclsForContext(*context); +} + +lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) { + if (index >= GetNumCompileUnits()) + return CompUnitSP(); + lldbassert(index < UINT16_MAX); + if (index >= UINT16_MAX) + return nullptr; + + CompilandIndexItem &item = m_index->compilands().GetOrCreateCompiland(index); + + return GetOrCreateCompileUnit(item); +} + +lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) { + PdbSymUid uid(comp_unit.GetID()); + lldbassert(uid.kind() == PdbSymUidKind::Compiland); + + CompilandIndexItem *item = + m_index->compilands().GetCompiland(uid.asCompiland().modi); + lldbassert(item); + if (!item->m_compile_opts) + return lldb::eLanguageTypeUnknown; + + return TranslateLanguage(item->m_compile_opts->getLanguage()); +} + +void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; } + +size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) { + PdbSymUid uid{comp_unit.GetID()}; + lldbassert(uid.kind() == PdbSymUidKind::Compiland); + uint16_t modi = uid.asCompiland().modi; + CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi); + + size_t count = comp_unit.GetNumFunctions(); + const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray(); + for (auto iter = syms.begin(); iter != syms.end(); ++iter) { + if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) + continue; + + PdbCompilandSymId sym_id{modi, iter.offset()}; + + FunctionSP func = GetOrCreateFunction(sym_id, comp_unit); + } + + size_t new_count = comp_unit.GetNumFunctions(); + lldbassert(new_count >= count); + return new_count - count; +} + +static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) { + // If any of these flags are set, we need to resolve the compile unit. + uint32_t flags = eSymbolContextCompUnit; + flags |= eSymbolContextVariable; + flags |= eSymbolContextFunction; + flags |= eSymbolContextBlock; + flags |= eSymbolContextLineEntry; + return (resolve_scope & flags) != 0; +} + +uint32_t SymbolFileNativePDB::ResolveSymbolContext( + const Address &addr, SymbolContextItem resolve_scope, SymbolContext &sc) { + uint32_t resolved_flags = 0; + lldb::addr_t file_addr = addr.GetFileAddress(); + + if (NeedsResolvedCompileUnit(resolve_scope)) { + llvm::Optional modi = m_index->GetModuleIndexForVa(file_addr); + if (!modi) + return 0; + CompilandIndexItem *cci = m_index->compilands().GetCompiland(*modi); + if (!cci) + return 0; + + sc.comp_unit = GetOrCreateCompileUnit(*cci).get(); + resolved_flags |= eSymbolContextCompUnit; + } + + if (resolve_scope & eSymbolContextFunction || + resolve_scope & eSymbolContextBlock) { + lldbassert(sc.comp_unit); + std::vector matches = m_index->FindSymbolsByVa(file_addr); + // Search the matches in reverse. This way if there are multiple matches + // (for example we are 3 levels deep in a nested scope) it will find the + // innermost one first. + for (const auto &match : llvm::reverse(matches)) { + if (match.uid.kind() != PdbSymUidKind::CompilandSym) + continue; + + PdbCompilandSymId csid = match.uid.asCompilandSym(); + CVSymbol cvs = m_index->ReadSymbolRecord(csid); + PDB_SymType type = CVSymToPDBSym(cvs.kind()); + if (type != PDB_SymType::Function && type != PDB_SymType::Block) + continue; + if (type == PDB_SymType::Function) { + sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get(); + sc.block = sc.GetFunctionBlock(); + } + + if (type == PDB_SymType::Block) { + sc.block = &GetOrCreateBlock(csid); + sc.function = sc.block->CalculateSymbolContextFunction(); + } + resolved_flags |= eSymbolContextFunction; + resolved_flags |= eSymbolContextBlock; + break; + } + } + + if (resolve_scope & eSymbolContextLineEntry) { + lldbassert(sc.comp_unit); + if (auto *line_table = sc.comp_unit->GetLineTable()) { + if (line_table->FindLineEntryByAddress(addr, sc.line_entry)) + resolved_flags |= eSymbolContextLineEntry; + } + } + + return resolved_flags; +} + +uint32_t SymbolFileNativePDB::ResolveSymbolContext( + const FileSpec &file_spec, uint32_t line, bool check_inlines, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { + return 0; +} + +static void AppendLineEntryToSequence(LineTable &table, LineSequence &sequence, + const CompilandIndexItem &cci, + lldb::addr_t base_addr, + uint32_t file_number, + const LineFragmentHeader &block, + const LineNumberEntry &cur) { + LineInfo cur_info(cur.Flags); + + if (cur_info.isAlwaysStepInto() || cur_info.isNeverStepInto()) + return; + + uint64_t addr = base_addr + cur.Offset; + + bool is_statement = cur_info.isStatement(); + bool is_prologue = IsFunctionPrologue(cci, addr); + bool is_epilogue = IsFunctionEpilogue(cci, addr); + + uint32_t lno = cur_info.getStartLine(); + + table.AppendLineEntryToSequence(&sequence, addr, lno, 0, file_number, + is_statement, false, is_prologue, is_epilogue, + false); +} + +static void TerminateLineSequence(LineTable &table, + const LineFragmentHeader &block, + lldb::addr_t base_addr, uint32_t file_number, + uint32_t last_line, + std::unique_ptr seq) { + // The end is always a terminal entry, so insert it regardless. + table.AppendLineEntryToSequence(seq.get(), base_addr + block.CodeSize, + last_line, 0, file_number, false, false, + false, false, true); + table.InsertSequence(seq.release()); +} + +bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { + // Unfortunately LLDB is set up to parse the entire compile unit line table + // all at once, even if all it really needs is line info for a specific + // function. In the future it would be nice if it could set the sc.m_function + // member, and we could only get the line info for the function in question. + PdbSymUid cu_id(comp_unit.GetID()); + lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); + CompilandIndexItem *cci = + m_index->compilands().GetCompiland(cu_id.asCompiland().modi); + lldbassert(cci); + auto line_table = llvm::make_unique(&comp_unit); + + // This is basically a copy of the .debug$S subsections from all original COFF + // object files merged together with address relocations applied. We are + // looking for all DEBUG_S_LINES subsections. + for (const DebugSubsectionRecord &dssr : + cci->m_debug_stream.getSubsectionsArray()) { + if (dssr.kind() != DebugSubsectionKind::Lines) + continue; + + DebugLinesSubsectionRef lines; + llvm::BinaryStreamReader reader(dssr.getRecordData()); + if (auto EC = lines.initialize(reader)) { + llvm::consumeError(std::move(EC)); + return false; + } + + const LineFragmentHeader *lfh = lines.header(); + uint64_t virtual_addr = + m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); + + const auto &checksums = cci->m_strings.checksums().getArray(); + const auto &strings = cci->m_strings.strings(); + for (const LineColumnEntry &group : lines) { + // Indices in this structure are actually offsets of records in the + // DEBUG_S_FILECHECKSUMS subsection. Those entries then have an index + // into the global PDB string table. + auto iter = checksums.at(group.NameIndex); + if (iter == checksums.end()) + continue; + + llvm::Expected efn = + strings.getString(iter->FileNameOffset); + if (!efn) { + llvm::consumeError(efn.takeError()); + continue; + } + + // LLDB wants the index of the file in the list of support files. + auto fn_iter = llvm::find(cci->m_file_list, *efn); + lldbassert(fn_iter != cci->m_file_list.end()); + // LLDB support file indices are 1-based. + uint32_t file_index = + 1 + std::distance(cci->m_file_list.begin(), fn_iter); + + std::unique_ptr sequence( + line_table->CreateLineSequenceContainer()); + lldbassert(!group.LineNumbers.empty()); + + for (const LineNumberEntry &entry : group.LineNumbers) { + AppendLineEntryToSequence(*line_table, *sequence, *cci, virtual_addr, + file_index, *lfh, entry); + } + LineInfo last_line(group.LineNumbers.back().Flags); + TerminateLineSequence(*line_table, *lfh, virtual_addr, file_index, + last_line.getEndLine(), std::move(sequence)); + } + } + + if (line_table->GetSize() == 0) + return false; + + comp_unit.SetLineTable(line_table.release()); + return true; +} + +bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) { + // PDB doesn't contain information about macros + return false; +} + +bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) { + PdbSymUid cu_id(comp_unit.GetID()); + lldbassert(cu_id.kind() == PdbSymUidKind::Compiland); + CompilandIndexItem *cci = + m_index->compilands().GetCompiland(cu_id.asCompiland().modi); + lldbassert(cci); + + for (llvm::StringRef f : cci->m_file_list) { + FileSpec::Style style = + f.startswith("/") ? FileSpec::Style::posix : FileSpec::Style::windows; + FileSpec spec(f, style); + support_files.Append(spec); + } + + llvm::SmallString<64> main_source_file = + m_index->compilands().GetMainSourceFile(*cci); + FileSpec::Style style = main_source_file.startswith("/") + ? FileSpec::Style::posix + : FileSpec::Style::windows; + FileSpec spec(main_source_file, style); + support_files.Insert(0, spec); + return true; +} + +bool SymbolFileNativePDB::ParseImportedModules( + const SymbolContext &sc, std::vector &imported_modules) { + // PDB does not yet support module debug info + return false; +} + +size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { + GetOrCreateBlock(PdbSymUid(func.GetID()).asCompilandSym()); + // FIXME: Parse child blocks + return 1; +} + +void SymbolFileNativePDB::DumpClangAST(Stream &s) { m_ast->Dump(s); } + +uint32_t SymbolFileNativePDB::FindGlobalVariables( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + uint32_t max_matches, VariableList &variables) { + using SymbolAndOffset = std::pair; + + std::vector results = m_index->globals().findRecordsByName( + name.GetStringRef(), m_index->symrecords()); + for (const SymbolAndOffset &result : results) { + VariableSP var; + switch (result.second.kind()) { + case SymbolKind::S_GDATA32: + case SymbolKind::S_LDATA32: + case SymbolKind::S_GTHREAD32: + case SymbolKind::S_LTHREAD32: + case SymbolKind::S_CONSTANT: { + PdbGlobalSymId global(result.first, false); + var = GetOrCreateGlobalVariable(global); + variables.AddVariable(var); + break; + } + default: + continue; + } + } + return variables.GetSize(); +} + +uint32_t SymbolFileNativePDB::FindFunctions( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + FunctionNameType name_type_mask, bool include_inlines, bool append, + SymbolContextList &sc_list) { + // For now we only support lookup by method name. + if (!(name_type_mask & eFunctionNameTypeMethod)) + return 0; + + using SymbolAndOffset = std::pair; + + std::vector matches = m_index->globals().findRecordsByName( + name.GetStringRef(), m_index->symrecords()); + for (const SymbolAndOffset &match : matches) { + if (match.second.kind() != S_PROCREF && match.second.kind() != S_LPROCREF) + continue; + ProcRefSym proc(match.second.kind()); + cantFail(SymbolDeserializer::deserializeAs(match.second, proc)); + + if (!IsValidRecord(proc)) + continue; + + CompilandIndexItem &cci = + m_index->compilands().GetOrCreateCompiland(proc.modi()); + SymbolContext sc; + + sc.comp_unit = GetOrCreateCompileUnit(cci).get(); + PdbCompilandSymId func_id(proc.modi(), proc.SymOffset); + sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get(); + + sc_list.Append(sc); + } + + return sc_list.GetSize(); +} + +uint32_t SymbolFileNativePDB::FindFunctions(const RegularExpression ®ex, + bool include_inlines, bool append, + SymbolContextList &sc_list) { + return 0; +} + +uint32_t SymbolFileNativePDB::FindTypes( + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, + llvm::DenseSet &searched_symbol_files, TypeMap &types) { + if (!append) + types.Clear(); + if (!name) + return 0; + + searched_symbol_files.clear(); + searched_symbol_files.insert(this); + + // There is an assumption 'name' is not a regex + size_t match_count = FindTypesByName(name.GetStringRef(), max_matches, types); + + return match_count; +} + +size_t +SymbolFileNativePDB::FindTypes(const std::vector &context, + bool append, TypeMap &types) { + return 0; +} + +size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name, + uint32_t max_matches, + TypeMap &types) { + + size_t match_count = 0; + std::vector matches = m_index->tpi().findRecordsByName(name); + if (max_matches > 0 && max_matches < matches.size()) + matches.resize(max_matches); + + for (TypeIndex ti : matches) { + TypeSP type = GetOrCreateType(ti); + if (!type) + continue; + + types.Insert(type); + ++match_count; + } + return match_count; +} + +size_t SymbolFileNativePDB::ParseTypes(CompileUnit &comp_unit) { + // Only do the full type scan the first time. + if (m_done_full_type_scan) + return 0; + + size_t old_count = m_obj_file->GetModule()->GetTypeList()->GetSize(); + LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); + + // First process the entire TPI stream. + for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { + TypeSP type = GetOrCreateType(*ti); + if (type) + (void)type->GetFullCompilerType(); + } + + // Next look for S_UDT records in the globals stream. + for (const uint32_t gid : m_index->globals().getGlobalsTable()) { + PdbGlobalSymId global{gid, false}; + CVSymbol sym = m_index->ReadSymbolRecord(global); + if (sym.kind() != S_UDT) + continue; + + UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs(sym)); + bool is_typedef = true; + if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) { + CVType cvt = m_index->tpi().getType(udt.Type); + llvm::StringRef name = CVTagRecord::create(cvt).name(); + if (name == udt.Name) + is_typedef = false; + } + + if (is_typedef) + GetOrCreateTypedef(global); + } + + size_t new_count = m_obj_file->GetModule()->GetTypeList()->GetSize(); + + m_done_full_type_scan = true; + + return new_count - old_count; +} + +size_t +SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit, + VariableList &variables) { + PdbSymUid sym_uid(comp_unit.GetID()); + lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland); + return 0; +} + +VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, + PdbCompilandSymId var_id, + bool is_param) { + ModuleSP module = GetObjectFile()->GetModule(); + VariableInfo var_info = GetVariableLocationInfo(*m_index, var_id, module); + if (!var_info.location || !var_info.ranges) + return nullptr; + + CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi); + CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii); + TypeSP type_sp = GetOrCreateType(var_info.type); + std::string name = var_info.name.str(); + Declaration decl; + SymbolFileTypeSP sftype = + std::make_shared(*this, type_sp->GetID()); + + ValueType var_scope = + is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal; + VariableSP var_sp = std::make_shared( + toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, + comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false, + false, false); + + if (!is_param) + m_ast->GetOrCreateVariableDecl(scope_id, var_id); + + m_local_variables[toOpaqueUid(var_id)] = var_sp; + return var_sp; +} + +VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable( + PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) { + auto iter = m_local_variables.find(toOpaqueUid(var_id)); + if (iter != m_local_variables.end()) + return iter->second; + + return CreateLocalVariable(scope_id, var_id, is_param); +} + +TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) { + CVSymbol sym = m_index->ReadSymbolRecord(id); + lldbassert(sym.kind() == SymbolKind::S_UDT); + + UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs(sym)); + + TypeSP target_type = GetOrCreateType(udt.Type); + + (void)m_ast->GetOrCreateTypedefDecl(id); + + Declaration decl; + return std::make_shared( + toOpaqueUid(id), this, ConstString(udt.Name), target_type->GetByteSize(), + nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, + decl, target_type->GetForwardCompilerType(), + lldb_private::Type::eResolveStateForward); +} + +TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) { + auto iter = m_types.find(toOpaqueUid(id)); + if (iter != m_types.end()) + return iter->second; + + return CreateTypedef(id); +} + +size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { + Block &block = GetOrCreateBlock(block_id); + + size_t count = 0; + + CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi); + CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset); + uint32_t params_remaining = 0; + switch (sym.kind()) { + case S_GPROC32: + case S_LPROC32: { + ProcSym proc(static_cast(sym.kind())); + cantFail(SymbolDeserializer::deserializeAs(sym, proc)); + CVType signature = m_index->tpi().getType(proc.FunctionType); + ProcedureRecord sig; + cantFail(TypeDeserializer::deserializeAs(signature, sig)); + params_remaining = sig.getParameterCount(); + break; + } + case S_BLOCK32: + break; + default: + lldbassert(false && "Symbol is not a block!"); + return 0; + } + + VariableListSP variables = block.GetBlockVariableList(false); + if (!variables) { + variables = std::make_shared(); + block.SetVariableList(variables); + } + + CVSymbolArray syms = limitSymbolArrayToScope( + cii->m_debug_stream.getSymbolArray(), block_id.offset); + + // Skip the first record since it's a PROC32 or BLOCK32, and there's + // no point examining it since we know it's not a local variable. + syms.drop_front(); + auto iter = syms.begin(); + auto end = syms.end(); + + while (iter != end) { + uint32_t record_offset = iter.offset(); + CVSymbol variable_cvs = *iter; + PdbCompilandSymId child_sym_id(block_id.modi, record_offset); + ++iter; + + // If this is a block, recurse into its children and then skip it. + if (variable_cvs.kind() == S_BLOCK32) { + uint32_t block_end = getScopeEndOffset(variable_cvs); + count += ParseVariablesForBlock(child_sym_id); + iter = syms.at(block_end); + continue; + } + + bool is_param = params_remaining > 0; + VariableSP variable; + switch (variable_cvs.kind()) { + case S_REGREL32: + case S_REGISTER: + case S_LOCAL: + variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param); + if (is_param) + --params_remaining; + if (variable) + variables->AddVariableIfUnique(variable); + break; + default: + break; + } + } + + // Pass false for set_children, since we call this recursively so that the + // children will call this for themselves. + block.SetDidParseVariables(true, false); + + return count; +} + +size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) { + lldbassert(sc.function || sc.comp_unit); + + VariableListSP variables; + if (sc.block) { + PdbSymUid block_id(sc.block->GetID()); + + size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); + return count; + } + + if (sc.function) { + PdbSymUid block_id(sc.function->GetID()); + + size_t count = ParseVariablesForBlock(block_id.asCompilandSym()); + return count; + } + + if (sc.comp_unit) { + variables = sc.comp_unit->GetVariableList(false); + if (!variables) { + variables = std::make_shared(); + sc.comp_unit->SetVariableList(variables); + } + return ParseVariablesForCompileUnit(*sc.comp_unit, *variables); + } + + llvm_unreachable("Unreachable!"); +} + +CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) { + clang::Decl *decl = m_ast->GetOrCreateDeclForUid(PdbSymUid(uid)); + + return m_ast->ToCompilerDecl(*decl); +} + +CompilerDeclContext +SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) { + clang::DeclContext *context = + m_ast->GetOrCreateDeclContextForUid(PdbSymUid(uid)); + if (!context) + return {}; + + return m_ast->ToCompilerDeclContext(*context); +} + +CompilerDeclContext +SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { + clang::DeclContext *context = m_ast->GetParentDeclContext(PdbSymUid(uid)); + return m_ast->ToCompilerDeclContext(*context); +} + +Type *SymbolFileNativePDB::ResolveTypeUID(lldb::user_id_t type_uid) { + auto iter = m_types.find(type_uid); + // lldb should not be passing us non-sensical type uids. the only way it + // could have a type uid in the first place is if we handed it out, in which + // case we should know about the type. However, that doesn't mean we've + // instantiated it yet. We can vend out a UID for a future type. So if the + // type doesn't exist, let's instantiate it now. + if (iter != m_types.end()) + return &*iter->second; + + PdbSymUid uid(type_uid); + lldbassert(uid.kind() == PdbSymUidKind::Type); + PdbTypeSymId type_id = uid.asTypeSym(); + if (type_id.index.isNoneType()) + return nullptr; + + TypeSP type_sp = CreateAndCacheType(type_id); + return &*type_sp; +} + +llvm::Optional +SymbolFileNativePDB::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + return llvm::None; +} + + +bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) { + clang::QualType qt = + clang::QualType::getFromOpaquePtr(compiler_type.GetOpaqueQualType()); + + return m_ast->CompleteType(qt); +} + +size_t SymbolFileNativePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, + TypeClass type_mask, + lldb_private::TypeList &type_list) { + return 0; +} + +CompilerDeclContext +SymbolFileNativePDB::FindNamespace(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx) { + return {}; +} + +TypeSystem * +SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { + auto type_system = + m_obj_file->GetModule()->GetTypeSystemForLanguage(language); + if (type_system) + type_system->SetSymbolFile(this); + return type_system; +} + +ConstString SymbolFileNativePDB::GetPluginName() { + static ConstString g_name("pdb"); + return g_name; +} + +uint32_t SymbolFileNativePDB::GetPluginVersion() { return 1; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h new file mode 100644 index 000000000000..dcf3fe365ef1 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -0,0 +1,245 @@ +//===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H +#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_SYMBOLFILENATIVEPDB_H + +#include "lldb/Symbol/ClangASTImporter.h" +#include "lldb/Symbol/SymbolFile.h" + +#include "llvm/ADT/DenseMap.h" +#include "llvm/DebugInfo/CodeView/CVRecord.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +#include "CompileUnitIndex.h" +#include "PdbIndex.h" + +namespace clang { +class TagDecl; +} + +namespace llvm { +namespace codeview { +class ClassRecord; +class EnumRecord; +class ModifierRecord; +class PointerRecord; +struct UnionRecord; +} // namespace codeview +} // namespace llvm + +namespace lldb_private { +class ClangASTImporter; + +namespace npdb { +class PdbAstBuilder; + +class SymbolFileNativePDB : public SymbolFile { + friend class UdtRecordCompleter; + +public: + //------------------------------------------------------------------ + // Static Functions + //------------------------------------------------------------------ + static void Initialize(); + + static void Terminate(); + + static void DebuggerInitialize(Debugger &debugger); + + static ConstString GetPluginNameStatic(); + + static const char *GetPluginDescriptionStatic(); + + static SymbolFile *CreateInstance(ObjectFile *obj_file); + + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + SymbolFileNativePDB(ObjectFile *ofile); + + ~SymbolFileNativePDB() override; + + uint32_t CalculateAbilities() override; + + void InitializeObject() override; + + //------------------------------------------------------------------ + // Compile Unit function calls + //------------------------------------------------------------------ + + uint32_t GetNumCompileUnits() override; + + void + ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; + + lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; + + lldb::LanguageType + ParseLanguage(lldb_private::CompileUnit &comp_unit) override; + + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; + + bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; + + bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; + + bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, + FileSpecList &support_files) override; + size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; + + bool + ParseImportedModules(const SymbolContext &sc, + std::vector &imported_modules) override; + + size_t ParseBlocksRecursive(Function &func) override; + + uint32_t FindGlobalVariables(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + uint32_t max_matches, + VariableList &variables) override; + + size_t ParseVariablesForContext(const SymbolContext &sc) override; + + void AddSymbols(Symtab &symtab) override; + + CompilerDecl GetDeclForUID(lldb::user_id_t uid) override; + CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override; + CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override; + Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; + + bool CompleteType(CompilerType &compiler_type) override; + uint32_t ResolveSymbolContext(const Address &so_addr, + lldb::SymbolContextItem resolve_scope, + SymbolContext &sc) override; + uint32_t ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, + bool check_inlines, + lldb::SymbolContextItem resolve_scope, + SymbolContextList &sc_list) override; + + size_t GetTypes(SymbolContextScope *sc_scope, lldb::TypeClass type_mask, + TypeList &type_list) override; + + uint32_t FindFunctions(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, + lldb::FunctionNameType name_type_mask, + bool include_inlines, bool append, + SymbolContextList &sc_list) override; + + uint32_t FindFunctions(const RegularExpression ®ex, bool include_inlines, + bool append, SymbolContextList &sc_list) override; + + uint32_t FindTypes(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx, bool append, + uint32_t max_matches, + llvm::DenseSet &searched_symbol_files, + TypeMap &types) override; + + size_t FindTypes(const std::vector &context, bool append, + TypeMap &types) override; + + TypeSystem *GetTypeSystemForLanguage(lldb::LanguageType language) override; + + CompilerDeclContext + FindNamespace(const ConstString &name, + const CompilerDeclContext *parent_decl_ctx) override; + + ConstString GetPluginName() override; + + uint32_t GetPluginVersion() override; + + llvm::pdb::PDBFile &GetPDBFile() { return m_index->pdb(); } + const llvm::pdb::PDBFile &GetPDBFile() const { return m_index->pdb(); } + + void DumpClangAST(Stream &s) override; + +private: + + size_t FindTypesByName(llvm::StringRef name, uint32_t max_matches, + TypeMap &types); + + lldb::TypeSP CreateModifierType(PdbTypeSymId type_id, + const llvm::codeview::ModifierRecord &mr, + CompilerType ct); + lldb::TypeSP CreatePointerType(PdbTypeSymId type_id, + const llvm::codeview::PointerRecord &pr, + CompilerType ct); + lldb::TypeSP CreateSimpleType(llvm::codeview::TypeIndex ti, CompilerType ct); + lldb::TypeSP CreateTagType(PdbTypeSymId type_id, + const llvm::codeview::ClassRecord &cr, + CompilerType ct); + lldb::TypeSP CreateTagType(PdbTypeSymId type_id, + const llvm::codeview::EnumRecord &er, + CompilerType ct); + lldb::TypeSP CreateTagType(PdbTypeSymId type_id, + const llvm::codeview::UnionRecord &ur, + CompilerType ct); + lldb::TypeSP CreateArrayType(PdbTypeSymId type_id, + const llvm::codeview::ArrayRecord &ar, + CompilerType ct); + lldb::TypeSP CreateProcedureType(PdbTypeSymId type_id, + const llvm::codeview::ProcedureRecord &pr, + CompilerType ct); + lldb::TypeSP CreateClassStructUnion(PdbTypeSymId type_id, + const llvm::codeview::TagRecord &record, + size_t size, CompilerType ct); + + lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id, + CompileUnit &comp_unit); + lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci); + lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id); + lldb::TypeSP GetOrCreateType(llvm::codeview::TypeIndex ti); + lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id); + Block &GetOrCreateBlock(PdbCompilandSymId block_id); + lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id, + PdbCompilandSymId var_id, + bool is_param); + lldb::TypeSP GetOrCreateTypedef(PdbGlobalSymId id); + + lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id, + CompileUnit &comp_unit); + Block &CreateBlock(PdbCompilandSymId block_id); + lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id, + PdbCompilandSymId var_id, bool is_param); + lldb::TypeSP CreateTypedef(PdbGlobalSymId id); + lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci); + lldb::TypeSP CreateType(PdbTypeSymId type_id, CompilerType ct); + lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id); + lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id); + lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id, + const llvm::codeview::CVSymbol &cvs); + size_t ParseVariablesForCompileUnit(CompileUnit &comp_unit, + VariableList &variables); + size_t ParseVariablesForBlock(PdbCompilandSymId block_id); + + llvm::BumpPtrAllocator m_allocator; + + lldb::addr_t m_obj_load_address = 0; + bool m_done_full_type_scan = false; + + std::unique_ptr m_index; + + std::unique_ptr m_ast; + + llvm::DenseMap m_global_vars; + llvm::DenseMap m_local_variables; + llvm::DenseMap m_blocks; + llvm::DenseMap m_functions; + llvm::DenseMap m_compilands; + llvm::DenseMap m_types; +}; + +} // namespace npdb +} // namespace lldb_private + +#endif // lldb_Plugins_SymbolFile_PDB_SymbolFilePDB_h_ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp new file mode 100644 index 000000000000..239dfbee625d --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -0,0 +1,191 @@ +#include "UdtRecordCompleter.h" + +#include "PdbAstBuilder.h" +#include "PdbIndex.h" +#include "PdbSymUid.h" +#include "PdbUtil.h" + +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangASTImporter.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Utility/LLDBAssert.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" + +#include "llvm/DebugInfo/CodeView/TypeDeserializer.h" +#include "llvm/DebugInfo/CodeView/TypeIndex.h" +#include "llvm/DebugInfo/PDB/Native/TpiStream.h" +#include "llvm/DebugInfo/PDB/PDBTypes.h" + +using namespace llvm::codeview; +using namespace llvm::pdb; +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::npdb; + +using Error = llvm::Error; + +UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id, + CompilerType &derived_ct, + clang::TagDecl &tag_decl, + PdbAstBuilder &ast_builder, + TpiStream &tpi) + : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl), + m_ast_builder(ast_builder), m_tpi(tpi) { + CVType cvt = m_tpi.getType(m_id.index); + switch (cvt.kind()) { + case LF_ENUM: + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, m_cvr.er)); + break; + case LF_UNION: + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, m_cvr.ur)); + break; + case LF_CLASS: + case LF_STRUCTURE: + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, m_cvr.cr)); + break; + default: + llvm_unreachable("unreachable!"); + } +} + +clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex( + llvm::codeview::TypeIndex ti, llvm::codeview::MemberAccess access) { + PdbTypeSymId type_id(ti); + clang::QualType qt = m_ast_builder.GetOrCreateType(type_id); + + CVType udt_cvt = m_tpi.getType(ti); + + std::unique_ptr base_spec = + m_ast_builder.clang().CreateBaseClassSpecifier( + qt.getAsOpaquePtr(), TranslateMemberAccess(access), false, + udt_cvt.kind() == LF_CLASS); + lldbassert(base_spec); + m_bases.push_back(std::move(base_spec)); + return qt; +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + BaseClassRecord &base) { + clang::QualType base_qt = + AddBaseClassForTypeIndex(base.Type, base.getAccess()); + + auto decl = + m_ast_builder.clang().GetAsCXXRecordDecl(base_qt.getAsOpaquePtr()); + lldbassert(decl); + + auto offset = clang::CharUnits::fromQuantity(base.getBaseOffset()); + m_layout.base_offsets.insert(std::make_pair(decl, offset)); + + return llvm::Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + VirtualBaseClassRecord &base) { + AddBaseClassForTypeIndex(base.BaseType, base.getAccess()); + + // FIXME: Handle virtual base offsets. + return Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + ListContinuationRecord &cont) { + return Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + VFPtrRecord &vfptr) { + return Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember( + CVMemberRecord &cvr, StaticDataMemberRecord &static_data_member) { + clang::QualType member_type = + m_ast_builder.GetOrCreateType(PdbTypeSymId(static_data_member.Type)); + + m_ast_builder.CompleteType(member_type); + + CompilerType member_ct = m_ast_builder.ToCompilerType(member_type); + + lldb::AccessType access = + TranslateMemberAccess(static_data_member.getAccess()); + ClangASTContext::AddVariableToRecordType( + m_derived_ct, static_data_member.Name, member_ct, access); + + // FIXME: Add a PdbSymUid namespace for field list members and update + // the m_uid_to_decl map with this decl. + return Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + NestedTypeRecord &nested) { + return Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + DataMemberRecord &data_member) { + + uint64_t offset = data_member.FieldOffset * 8; + uint32_t bitfield_width = 0; + + TypeIndex ti(data_member.Type); + if (!ti.isSimple()) { + CVType cvt = m_tpi.getType(ti); + if (cvt.kind() == LF_BITFIELD) { + BitFieldRecord bfr; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, bfr)); + offset += bfr.BitOffset; + bitfield_width = bfr.BitSize; + ti = bfr.Type; + } + } + + clang::QualType member_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(ti)); + m_ast_builder.CompleteType(member_qt); + + lldb::AccessType access = TranslateMemberAccess(data_member.getAccess()); + + clang::FieldDecl *decl = ClangASTContext::AddFieldToRecordType( + m_derived_ct, data_member.Name, m_ast_builder.ToCompilerType(member_qt), + access, bitfield_width); + // FIXME: Add a PdbSymUid namespace for field list members and update + // the m_uid_to_decl map with this decl. + + m_layout.field_offsets.insert(std::make_pair(decl, offset)); + + return Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + OneMethodRecord &one_method) { + return Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + OverloadedMethodRecord &overloaded) { + return Error::success(); +} + +Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, + EnumeratorRecord &enumerator) { + Declaration decl; + llvm::StringRef name = DropNameScope(enumerator.getName()); + + m_ast_builder.clang().AddEnumerationValueToEnumerationType( + m_derived_ct, decl, name.str().c_str(), enumerator.Value); + return Error::success(); +} + +void UdtRecordCompleter::complete() { + ClangASTContext &clang = m_ast_builder.clang(); + clang.TransferBaseClasses(m_derived_ct.GetOpaqueQualType(), + std::move(m_bases)); + + clang.AddMethodOverridesForCXXRecordType(m_derived_ct.GetOpaqueQualType()); + ClangASTContext::BuildIndirectFields(m_derived_ct); + ClangASTContext::CompleteTagDeclarationDefinition(m_derived_ct); + + if (auto *record_decl = llvm::dyn_cast(&m_tag_decl)) { + m_ast_builder.importer().InsertRecordDecl(record_decl, m_layout); + } +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h new file mode 100644 index 000000000000..469685126e59 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h @@ -0,0 +1,75 @@ +//===-- SymbolFileNativePDB.h -----------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H +#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H + +#include "lldb/Symbol/ClangASTImporter.h" +#include "llvm/DebugInfo/CodeView/CVRecord.h" +#include "llvm/DebugInfo/CodeView/TypeRecord.h" +#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h" + +#include "PdbSymUid.h" + +namespace clang { +class CXXBaseSpecifier; +class QualType; +class TagDecl; +} // namespace clang + +namespace llvm { +namespace pdb { +class TpiStream; +} +} // namespace llvm + +namespace lldb_private { +class Type; +class CompilerType; +namespace npdb { +class PdbAstBuilder; + +class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { + union UdtTagRecord { + UdtTagRecord() {} + llvm::codeview::UnionRecord ur; + llvm::codeview::ClassRecord cr; + llvm::codeview::EnumRecord er; + } m_cvr; + + PdbTypeSymId m_id; + CompilerType &m_derived_ct; + clang::TagDecl &m_tag_decl; + PdbAstBuilder &m_ast_builder; + llvm::pdb::TpiStream &m_tpi; + std::vector> m_bases; + ClangASTImporter::LayoutInfo m_layout; + +public: + UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct, + clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder, + llvm::pdb::TpiStream &tpi); + +#define MEMBER_RECORD(EnumName, EnumVal, Name) \ + llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR, \ + llvm::codeview::Name##Record &Record) override; +#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#include "llvm/DebugInfo/CodeView/CodeViewTypes.def" + + void complete(); + +private: + clang::QualType AddBaseClassForTypeIndex(llvm::codeview::TypeIndex ti, + llvm::codeview::MemberAccess access); +}; + +} // namespace npdb +} // namespace lldb_private + +#endif // LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_UDTRECORDCOMPLETER_H diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index 8bea994aae5d..65e718bedaf1 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -9,14 +9,19 @@ #include "PDBASTParser.h" +#include "SymbolFilePDB.h" + #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "lldb/Core/Module.h" #include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Symbol/ClangExternalASTSourceCommon.h" #include "lldb/Symbol/ClangUtil.h" #include "lldb/Symbol/Declaration.h" #include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" @@ -33,12 +38,13 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" + using namespace lldb; using namespace lldb_private; using namespace llvm::pdb; -namespace { -int TranslateUdtKind(PDB_UdtType pdb_kind) { +static int TranslateUdtKind(PDB_UdtType pdb_kind) { switch (pdb_kind) { case PDB_UdtType::Class: return clang::TTK_Class; @@ -49,10 +55,10 @@ int TranslateUdtKind(PDB_UdtType pdb_kind) { case PDB_UdtType::Interface: return clang::TTK_Interface; } - return -1; + llvm_unreachable("unsuported PDB UDT type"); } -lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) { +static lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) { switch (type) { case PDB_BuiltinType::Float: return lldb::eEncodingIEEE754; @@ -73,7 +79,7 @@ lldb::Encoding TranslateBuiltinEncoding(PDB_BuiltinType type) { } } -lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) { +static lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) { switch (type) { case PDB_VariantType::Int8: case PDB_VariantType::Int16: @@ -94,7 +100,7 @@ lldb::Encoding TranslateEnumEncoding(PDB_VariantType type) { return lldb::eEncodingSint; } -CompilerType +static CompilerType GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast, const PDBSymbolTypeBuiltin &pdb_type, Encoding encoding, uint32_t width) { @@ -109,6 +115,8 @@ GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast, return CompilerType(); case PDB_BuiltinType::Void: return clang_ast.GetBasicType(eBasicTypeVoid); + case PDB_BuiltinType::Char: + return clang_ast.GetBasicType(eBasicTypeChar); case PDB_BuiltinType::Bool: return clang_ast.GetBasicType(eBasicTypeBool); case PDB_BuiltinType::Long: @@ -143,8 +151,8 @@ GetBuiltinTypeForPDBEncodingAndBitSize(ClangASTContext &clang_ast, return clang_ast.GetBuiltinTypeForEncodingAndBitSize(encoding, width); } -ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type, - CompilerType &compiler_type) { +static ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type, + CompilerType &compiler_type) { PDB_BuiltinType kind = pdb_type.getBuiltinType(); switch (kind) { default: @@ -175,7 +183,8 @@ ConstString GetPDBBuiltinTypeName(const PDBSymbolTypeBuiltin &pdb_type, return compiler_type.GetTypeName(); } -bool GetDeclarationForSymbol(const PDBSymbol &symbol, Declaration &decl) { +static bool GetDeclarationForSymbol(const PDBSymbol &symbol, + Declaration &decl) { auto &raw_sym = symbol.getRawSymbol(); auto first_line_up = raw_sym.getSrcLineOnTypeDefn(); @@ -193,13 +202,159 @@ bool GetDeclarationForSymbol(const PDBSymbol &symbol, Declaration &decl) { if (!src_file_up) return false; - FileSpec spec(src_file_up->getFileName(), /*resolve_path*/ false); + FileSpec spec(src_file_up->getFileName()); decl.SetFile(spec); decl.SetColumn(first_line_up->getColumnNumber()); decl.SetLine(first_line_up->getLineNumber()); return true; } -} // namespace + +static AccessType TranslateMemberAccess(PDB_MemberAccess access) { + switch (access) { + case PDB_MemberAccess::Private: + return eAccessPrivate; + case PDB_MemberAccess::Protected: + return eAccessProtected; + case PDB_MemberAccess::Public: + return eAccessPublic; + } + return eAccessNone; +} + +static AccessType GetDefaultAccessibilityForUdtKind(PDB_UdtType udt_kind) { + switch (udt_kind) { + case PDB_UdtType::Struct: + case PDB_UdtType::Union: + return eAccessPublic; + case PDB_UdtType::Class: + case PDB_UdtType::Interface: + return eAccessPrivate; + } + llvm_unreachable("unsupported PDB UDT type"); +} + +static AccessType GetAccessibilityForUdt(const PDBSymbolTypeUDT &udt) { + AccessType access = TranslateMemberAccess(udt.getAccess()); + if (access != lldb::eAccessNone || !udt.isNested()) + return access; + + auto parent = udt.getClassParent(); + if (!parent) + return lldb::eAccessNone; + + auto parent_udt = llvm::dyn_cast(parent.get()); + if (!parent_udt) + return lldb::eAccessNone; + + return GetDefaultAccessibilityForUdtKind(parent_udt->getUdtKind()); +} + +static clang::MSInheritanceAttr::Spelling +GetMSInheritance(const PDBSymbolTypeUDT &udt) { + int base_count = 0; + bool has_virtual = false; + + auto bases_enum = udt.findAllChildren(); + if (bases_enum) { + while (auto base = bases_enum->getNext()) { + base_count++; + has_virtual |= base->isVirtualBaseClass(); + } + } + + if (has_virtual) + return clang::MSInheritanceAttr::Keyword_virtual_inheritance; + if (base_count > 1) + return clang::MSInheritanceAttr::Keyword_multiple_inheritance; + return clang::MSInheritanceAttr::Keyword_single_inheritance; +} + +static std::unique_ptr +GetClassOrFunctionParent(const llvm::pdb::PDBSymbol &symbol) { + const IPDBSession &session = symbol.getSession(); + const IPDBRawSymbol &raw = symbol.getRawSymbol(); + auto tag = symbol.getSymTag(); + + // For items that are nested inside of a class, return the class that it is + // nested inside of. + // Note that only certain items can be nested inside of classes. + switch (tag) { + case PDB_SymType::Function: + case PDB_SymType::Data: + case PDB_SymType::UDT: + case PDB_SymType::Enum: + case PDB_SymType::FunctionSig: + case PDB_SymType::Typedef: + case PDB_SymType::BaseClass: + case PDB_SymType::VTable: { + auto class_parent_id = raw.getClassParentId(); + if (auto class_parent = session.getSymbolById(class_parent_id)) + return class_parent; + break; + } + default: + break; + } + + // Otherwise, if it is nested inside of a function, return the function. + // Note that only certain items can be nested inside of functions. + switch (tag) { + case PDB_SymType::Block: + case PDB_SymType::Data: { + auto lexical_parent_id = raw.getLexicalParentId(); + auto lexical_parent = session.getSymbolById(lexical_parent_id); + if (!lexical_parent) + return nullptr; + + auto lexical_parent_tag = lexical_parent->getSymTag(); + if (lexical_parent_tag == PDB_SymType::Function) + return lexical_parent; + if (lexical_parent_tag == PDB_SymType::Exe) + return nullptr; + + return GetClassOrFunctionParent(*lexical_parent); + } + default: + return nullptr; + } +} + +static clang::NamedDecl * +GetDeclFromContextByName(const clang::ASTContext &ast, + const clang::DeclContext &decl_context, + llvm::StringRef name) { + clang::IdentifierInfo &ident = ast.Idents.get(name); + clang::DeclarationName decl_name = ast.DeclarationNames.getIdentifier(&ident); + clang::DeclContext::lookup_result result = decl_context.lookup(decl_name); + if (result.empty()) + return nullptr; + + return result[0]; +} + +static bool IsAnonymousNamespaceName(llvm::StringRef name) { + return name == "`anonymous namespace'" || name == "`anonymous-namespace'"; +} + +static clang::CallingConv TranslateCallingConvention(PDB_CallingConv pdb_cc) { + switch (pdb_cc) { + case llvm::codeview::CallingConvention::NearC: + return clang::CC_C; + case llvm::codeview::CallingConvention::NearStdCall: + return clang::CC_X86StdCall; + case llvm::codeview::CallingConvention::NearFast: + return clang::CC_X86FastCall; + case llvm::codeview::CallingConvention::ThisCall: + return clang::CC_X86ThisCall; + case llvm::codeview::CallingConvention::NearVector: + return clang::CC_X86VectorCall; + case llvm::codeview::CallingConvention::NearPascal: + return clang::CC_X86Pascal; + default: + assert(false && "Unknown calling convention"); + return clang::CC_C; + } +} PDBASTParser::PDBASTParser(lldb_private::ClangASTContext &ast) : m_ast(ast) {} @@ -208,76 +363,167 @@ PDBASTParser::~PDBASTParser() {} // DebugInfoASTParser interface lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { - // PDB doesn't maintain enough information to robustly rebuild the entire - // tree, and this is most problematic when it comes to figure out the right - // DeclContext to put a type in. So for now, everything goes in the - // translation unit decl as a fully qualified type. - clang::DeclContext *tu_decl_ctx = m_ast.GetTranslationUnitDecl(); Declaration decl; - switch (type.getSymTag()) { + case PDB_SymType::BaseClass: { + auto symbol_file = m_ast.GetSymbolFile(); + if (!symbol_file) + return nullptr; + + auto ty = symbol_file->ResolveTypeUID(type.getRawSymbol().getTypeId()); + return ty ? ty->shared_from_this() : nullptr; + } break; case PDB_SymType::UDT: { auto udt = llvm::dyn_cast(&type); assert(udt); - AccessType access = lldb::eAccessPublic; - PDB_UdtType udt_kind = udt->getUdtKind(); - auto tag_type_kind = TranslateUdtKind(udt_kind); - if (tag_type_kind == -1) + + // Note that, unnamed UDT being typedef-ed is generated as a UDT symbol + // other than a Typedef symbol in PDB. For example, + // typedef union { short Row; short Col; } Union; + // is generated as a named UDT in PDB: + // union Union { short Row; short Col; } + // Such symbols will be handled here. + + // Some UDT with trival ctor has zero length. Just ignore. + if (udt->getLength() == 0) return nullptr; - if (udt_kind == PDB_UdtType::Class) - access = lldb::eAccessPrivate; + // Ignore unnamed-tag UDTs. + std::string name = MSVCUndecoratedNameParser::DropScope(udt->getName()); + if (name.empty()) + return nullptr; - CompilerType clang_type = m_ast.CreateRecordType( - tu_decl_ctx, access, udt->getName().c_str(), tag_type_kind, - lldb::eLanguageTypeC_plus_plus, nullptr); + auto decl_context = GetDeclContextContainingSymbol(type); - m_ast.SetHasExternalStorage(clang_type.GetOpaqueQualType(), true); + // Check if such an UDT already exists in the current context. + // This may occur with const or volatile types. There are separate type + // symbols in PDB for types with const or volatile modifiers, but we need + // to create only one declaration for them all. + Type::ResolveStateTag type_resolve_state_tag; + CompilerType clang_type = m_ast.GetTypeForIdentifier( + ConstString(name), decl_context); + if (!clang_type.IsValid()) { + auto access = GetAccessibilityForUdt(*udt); + auto tag_type_kind = TranslateUdtKind(udt->getUdtKind()); + + ClangASTMetadata metadata; + metadata.SetUserID(type.getSymIndexId()); + metadata.SetIsDynamicCXXType(false); + + clang_type = m_ast.CreateRecordType( + decl_context, access, name.c_str(), tag_type_kind, + lldb::eLanguageTypeC_plus_plus, &metadata); + assert(clang_type.IsValid()); + + auto record_decl = + m_ast.GetAsCXXRecordDecl(clang_type.GetOpaqueQualType()); + assert(record_decl); + m_uid_to_decl[type.getSymIndexId()] = record_decl; + + auto inheritance_attr = clang::MSInheritanceAttr::CreateImplicit( + *m_ast.getASTContext(), GetMSInheritance(*udt)); + record_decl->addAttr(inheritance_attr); + + ClangASTContext::StartTagDeclarationDefinition(clang_type); + + auto children = udt->findAllChildren(); + if (!children || children->getChildCount() == 0) { + // PDB does not have symbol of forwarder. We assume we get an udt w/o + // any fields. Just complete it at this point. + ClangASTContext::CompleteTagDeclarationDefinition(clang_type); + + ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(), + false); + + type_resolve_state_tag = Type::eResolveStateFull; + } else { + // Add the type to the forward declarations. It will help us to avoid + // an endless recursion in CompleteTypeFromUdt function. + m_forward_decl_to_uid[record_decl] = type.getSymIndexId(); + + ClangASTContext::SetHasExternalStorage(clang_type.GetOpaqueQualType(), + true); + + type_resolve_state_tag = Type::eResolveStateForward; + } + } else + type_resolve_state_tag = Type::eResolveStateForward; + + if (udt->isConstType()) + clang_type = clang_type.AddConstModifier(); + + if (udt->isVolatileType()) + clang_type = clang_type.AddVolatileModifier(); + + GetDeclarationForSymbol(type, decl); return std::make_shared( - type.getSymIndexId(), m_ast.GetSymbolFile(), - ConstString(udt->getName()), udt->getLength(), nullptr, - LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl, clang_type, - lldb_private::Type::eResolveStateForward); + type.getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), + udt->getLength(), nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, decl, clang_type, + type_resolve_state_tag); } break; case PDB_SymType::Enum: { auto enum_type = llvm::dyn_cast(&type); assert(enum_type); - auto underlying_type_up = enum_type->getUnderlyingType(); - if (!underlying_type_up) - return nullptr; - lldb::Encoding encoding = - TranslateBuiltinEncoding(underlying_type_up->getBuiltinType()); - // FIXME: Type of underlying builtin is always `Int`. We correct it with - // the very first enumerator's encoding if any. - auto first_child = enum_type->findOneChild(); - if (first_child) { - encoding = TranslateEnumEncoding(first_child->getValue().Type); - } - std::string name = enum_type->getName(); - uint64_t bytes = enum_type->getLength(); - CompilerType builtin_type; - if (bytes > 0) - builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize( - m_ast, *underlying_type_up, encoding, bytes * 8); - else - builtin_type = m_ast.GetBasicType(eBasicTypeInt); - // FIXME: PDB does not have information about scoped enumeration (Enum - // Class). Set it false for now. - bool isScoped = false; - CompilerType ast_enum = m_ast.CreateEnumerationType( - name.c_str(), tu_decl_ctx, decl, builtin_type, isScoped); - auto enum_values = enum_type->findAllChildren(); - if (enum_values) { - while (auto enum_value = enum_values->getNext()) { - if (enum_value->getDataKind() != PDB_DataKind::Constant) - continue; - AddEnumValue(ast_enum, *enum_value); + std::string name = + MSVCUndecoratedNameParser::DropScope(enum_type->getName()); + auto decl_context = GetDeclContextContainingSymbol(type); + uint64_t bytes = enum_type->getLength(); + + // Check if such an enum already exists in the current context + CompilerType ast_enum = m_ast.GetTypeForIdentifier( + ConstString(name), decl_context); + if (!ast_enum.IsValid()) { + auto underlying_type_up = enum_type->getUnderlyingType(); + if (!underlying_type_up) + return nullptr; + + lldb::Encoding encoding = + TranslateBuiltinEncoding(underlying_type_up->getBuiltinType()); + // FIXME: Type of underlying builtin is always `Int`. We correct it with + // the very first enumerator's encoding if any. + auto first_child = enum_type->findOneChild(); + if (first_child) + encoding = TranslateEnumEncoding(first_child->getValue().Type); + + CompilerType builtin_type; + if (bytes > 0) + builtin_type = GetBuiltinTypeForPDBEncodingAndBitSize( + m_ast, *underlying_type_up, encoding, bytes * 8); + else + builtin_type = m_ast.GetBasicType(eBasicTypeInt); + + // FIXME: PDB does not have information about scoped enumeration (Enum + // Class). Set it false for now. + bool isScoped = false; + + ast_enum = m_ast.CreateEnumerationType(name.c_str(), decl_context, decl, + builtin_type, isScoped); + + auto enum_decl = ClangASTContext::GetAsEnumDecl(ast_enum); + assert(enum_decl); + m_uid_to_decl[type.getSymIndexId()] = enum_decl; + + auto enum_values = enum_type->findAllChildren(); + if (enum_values) { + while (auto enum_value = enum_values->getNext()) { + if (enum_value->getDataKind() != PDB_DataKind::Constant) + continue; + AddEnumValue(ast_enum, *enum_value); + } } + + if (ClangASTContext::StartTagDeclarationDefinition(ast_enum)) + ClangASTContext::CompleteTagDeclarationDefinition(ast_enum); } - if (ClangASTContext::StartTagDeclarationDefinition(ast_enum)) - ClangASTContext::CompleteTagDeclarationDefinition(ast_enum); + + if (enum_type->isConstType()) + ast_enum = ast_enum.AddConstModifier(); + + if (enum_type->isVolatileType()) + ast_enum = ast_enum.AddVolatileModifier(); GetDeclarationForSymbol(type, decl); return std::make_shared( @@ -288,23 +534,43 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { case PDB_SymType::Typedef: { auto type_def = llvm::dyn_cast(&type); assert(type_def); + lldb_private::Type *target_type = m_ast.GetSymbolFile()->ResolveTypeUID(type_def->getTypeId()); if (!target_type) return nullptr; - std::string name = type_def->getName(); - uint64_t bytes = type_def->getLength(); - CompilerType target_ast_type = target_type->GetFullCompilerType(); - CompilerDeclContext target_decl_ctx = - m_ast.GetSymbolFile()->GetDeclContextForUID(target_type->GetID()); - CompilerType ast_typedef = - m_ast.CreateTypedefType(target_ast_type, name.c_str(), target_decl_ctx); - if (!ast_typedef) - return nullptr; + std::string name = + MSVCUndecoratedNameParser::DropScope(type_def->getName()); + auto decl_ctx = GetDeclContextContainingSymbol(type); + + // Check if such a typedef already exists in the current context + CompilerType ast_typedef = + m_ast.GetTypeForIdentifier(ConstString(name), + decl_ctx); + if (!ast_typedef.IsValid()) { + CompilerType target_ast_type = target_type->GetFullCompilerType(); + + ast_typedef = m_ast.CreateTypedefType( + target_ast_type, name.c_str(), CompilerDeclContext(&m_ast, decl_ctx)); + if (!ast_typedef) + return nullptr; + + auto typedef_decl = ClangASTContext::GetAsTypedefDecl(ast_typedef); + assert(typedef_decl); + m_uid_to_decl[type.getSymIndexId()] = typedef_decl; + } + + if (type_def->isConstType()) + ast_typedef = ast_typedef.AddConstModifier(); + + if (type_def->isVolatileType()) + ast_typedef = ast_typedef.AddVolatileModifier(); + + GetDeclarationForSymbol(type, decl); return std::make_shared( type_def->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(name), - bytes, nullptr, target_type->GetID(), + type_def->getLength(), nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, decl, ast_typedef, lldb_private::Type::eResolveStateFull); } break; @@ -321,7 +587,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; func_sig = sig.release(); // Function type is named. - name = pdb_func->getName(); + name = MSVCUndecoratedNameParser::DropScope(pdb_func->getName()); } else if (auto pdb_func_sig = llvm::dyn_cast(&type)) { func_sig = const_cast(pdb_func_sig); @@ -364,9 +630,10 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { type_quals |= clang::Qualifiers::Const; if (func_sig->isVolatileType()) type_quals |= clang::Qualifiers::Volatile; + auto cc = TranslateCallingConvention(func_sig->getCallingConvention()); CompilerType func_sig_ast_type = m_ast.CreateFunctionType(return_ast_type, arg_list.data(), - arg_list.size(), is_variadic, type_quals); + arg_list.size(), is_variadic, type_quals, cc); GetDeclarationForSymbol(type, decl); return std::make_shared( @@ -391,7 +658,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { CompilerType element_ast_type = element_type->GetForwardCompilerType(); // If element type is UDT, it needs to be complete. if (ClangASTContext::IsCXXClassType(element_ast_type) && - element_ast_type.GetCompleteType() == false) { + !element_ast_type.GetCompleteType()) { if (ClangASTContext::StartTagDeclarationDefinition(element_ast_type)) { ClangASTContext::CompleteTagDeclarationDefinition(element_ast_type); } else { @@ -441,6 +708,26 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { if (!pointee_type) return nullptr; + if (pointer_type->isPointerToDataMember() || + pointer_type->isPointerToMemberFunction()) { + auto class_parent_uid = pointer_type->getRawSymbol().getClassParentId(); + auto class_parent_type = + m_ast.GetSymbolFile()->ResolveTypeUID(class_parent_uid); + assert(class_parent_type); + + CompilerType pointer_ast_type; + pointer_ast_type = ClangASTContext::CreateMemberPointerType( + class_parent_type->GetLayoutCompilerType(), + pointee_type->GetForwardCompilerType()); + assert(pointer_ast_type); + + return std::make_shared( + pointer_type->getSymIndexId(), m_ast.GetSymbolFile(), ConstString(), + pointer_type->getLength(), nullptr, LLDB_INVALID_UID, + lldb_private::Type::eEncodingIsUID, decl, pointer_ast_type, + lldb_private::Type::eResolveStateForward); + } + CompilerType pointer_ast_type; pointer_ast_type = pointee_type->GetFullCompilerType(); if (pointer_type->isReference()) @@ -471,11 +758,363 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { return nullptr; } +bool PDBASTParser::CompleteTypeFromPDB( + lldb_private::CompilerType &compiler_type) { + if (GetClangASTImporter().CanImport(compiler_type)) + return GetClangASTImporter().CompleteType(compiler_type); + + // Remove the type from the forward declarations to avoid + // an endless recursion for types like a linked list. + clang::CXXRecordDecl *record_decl = + m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); + auto uid_it = m_forward_decl_to_uid.find(record_decl); + if (uid_it == m_forward_decl_to_uid.end()) + return true; + + auto symbol_file = static_cast(m_ast.GetSymbolFile()); + if (!symbol_file) + return false; + + std::unique_ptr symbol = + symbol_file->GetPDBSession().getSymbolById(uid_it->getSecond()); + if (!symbol) + return false; + + m_forward_decl_to_uid.erase(uid_it); + + ClangASTContext::SetHasExternalStorage(compiler_type.GetOpaqueQualType(), + false); + + switch (symbol->getSymTag()) { + case PDB_SymType::UDT: { + auto udt = llvm::dyn_cast(symbol.get()); + if (!udt) + return false; + + return CompleteTypeFromUDT(*symbol_file, compiler_type, *udt); + } + default: + llvm_unreachable("not a forward clang type decl!"); + } +} + +clang::Decl * +PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { + uint32_t sym_id = symbol.getSymIndexId(); + auto it = m_uid_to_decl.find(sym_id); + if (it != m_uid_to_decl.end()) + return it->second; + + auto symbol_file = static_cast(m_ast.GetSymbolFile()); + if (!symbol_file) + return nullptr; + + // First of all, check if the symbol is a member of a class. Resolve the full + // class type and return the declaration from the cache if so. + auto tag = symbol.getSymTag(); + if (tag == PDB_SymType::Data || tag == PDB_SymType::Function) { + const IPDBSession &session = symbol.getSession(); + const IPDBRawSymbol &raw = symbol.getRawSymbol(); + + auto class_parent_id = raw.getClassParentId(); + if (std::unique_ptr class_parent = + session.getSymbolById(class_parent_id)) { + auto class_parent_type = symbol_file->ResolveTypeUID(class_parent_id); + if (!class_parent_type) + return nullptr; + + CompilerType class_parent_ct = class_parent_type->GetFullCompilerType(); + + // Look a declaration up in the cache after completing the class + clang::Decl *decl = m_uid_to_decl.lookup(sym_id); + if (decl) + return decl; + + // A declaration was not found in the cache. It means that the symbol + // has the class parent, but the class doesn't have the symbol in its + // children list. + if (auto func = llvm::dyn_cast_or_null(&symbol)) { + // Try to find a class child method with the same RVA and use its + // declaration if found. + if (uint32_t rva = func->getRelativeVirtualAddress()) { + if (std::unique_ptr> + methods_enum = + class_parent->findAllChildren()) { + while (std::unique_ptr method = + methods_enum->getNext()) { + if (method->getRelativeVirtualAddress() == rva) { + decl = m_uid_to_decl.lookup(method->getSymIndexId()); + if (decl) + break; + } + } + } + } + + // If no class methods with the same RVA were found, then create a new + // method. It is possible for template methods. + if (!decl) + decl = AddRecordMethod(*symbol_file, class_parent_ct, *func); + } + + if (decl) + m_uid_to_decl[sym_id] = decl; + + return decl; + } + } + + // If we are here, then the symbol is not belonging to a class and is not + // contained in the cache. So create a declaration for it. + switch (symbol.getSymTag()) { + case PDB_SymType::Data: { + auto data = llvm::dyn_cast(&symbol); + assert(data); + + auto decl_context = GetDeclContextContainingSymbol(symbol); + assert(decl_context); + + // May be the current context is a class really, but we haven't found + // any class parent. This happens e.g. in the case of class static + // variables - they has two symbols, one is a child of the class when + // another is a child of the exe. So always complete the parent and use + // an existing declaration if possible. + if (auto parent_decl = llvm::dyn_cast_or_null(decl_context)) + m_ast.GetCompleteDecl(parent_decl); + + std::string name = MSVCUndecoratedNameParser::DropScope(data->getName()); + + // Check if the current context already contains the symbol with the name. + clang::Decl *decl = + GetDeclFromContextByName(*m_ast.getASTContext(), *decl_context, name); + if (!decl) { + auto type = symbol_file->ResolveTypeUID(data->getTypeId()); + if (!type) + return nullptr; + + decl = m_ast.CreateVariableDeclaration( + decl_context, name.c_str(), + ClangUtil::GetQualType(type->GetLayoutCompilerType())); + } + + m_uid_to_decl[sym_id] = decl; + + return decl; + } + case PDB_SymType::Function: { + auto func = llvm::dyn_cast(&symbol); + assert(func); + + auto decl_context = GetDeclContextContainingSymbol(symbol); + assert(decl_context); + + std::string name = MSVCUndecoratedNameParser::DropScope(func->getName()); + + Type *type = symbol_file->ResolveTypeUID(sym_id); + if (!type) + return nullptr; + + auto storage = func->isStatic() ? clang::StorageClass::SC_Static + : clang::StorageClass::SC_None; + + auto decl = m_ast.CreateFunctionDeclaration( + decl_context, name.c_str(), type->GetForwardCompilerType(), storage, + func->hasInlineAttribute()); + + std::vector params; + if (std::unique_ptr sig = func->getSignature()) { + if (std::unique_ptr> + arg_enum = sig->findAllChildren()) { + while (std::unique_ptr arg = + arg_enum->getNext()) { + Type *arg_type = symbol_file->ResolveTypeUID(arg->getTypeId()); + if (!arg_type) + continue; + + clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration( + decl, nullptr, arg_type->GetForwardCompilerType(), + clang::SC_None); + if (param) + params.push_back(param); + } + } + } + if (params.size()) + m_ast.SetFunctionParameters(decl, params.data(), params.size()); + + m_uid_to_decl[sym_id] = decl; + + return decl; + } + default: { + // It's not a variable and not a function, check if it's a type + Type *type = symbol_file->ResolveTypeUID(sym_id); + if (!type) + return nullptr; + + return m_uid_to_decl.lookup(sym_id); + } + } +} + +clang::DeclContext * +PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) { + if (symbol.getSymTag() == PDB_SymType::Function) { + clang::DeclContext *result = + llvm::dyn_cast_or_null(GetDeclForSymbol(symbol)); + + if (result) + m_decl_context_to_uid[result] = symbol.getSymIndexId(); + + return result; + } + + auto symbol_file = static_cast(m_ast.GetSymbolFile()); + if (!symbol_file) + return nullptr; + + auto type = symbol_file->ResolveTypeUID(symbol.getSymIndexId()); + if (!type) + return nullptr; + + clang::DeclContext *result = + m_ast.GetDeclContextForType(type->GetForwardCompilerType()); + + if (result) + m_decl_context_to_uid[result] = symbol.getSymIndexId(); + + return result; +} + +clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( + const llvm::pdb::PDBSymbol &symbol) { + auto parent = GetClassOrFunctionParent(symbol); + while (parent) { + if (auto parent_context = GetDeclContextForSymbol(*parent)) + return parent_context; + + parent = GetClassOrFunctionParent(*parent); + } + + // We can't find any class or function parent of the symbol. So analyze + // the full symbol name. The symbol may be belonging to a namespace + // or function (or even to a class if it's e.g. a static variable symbol). + + // TODO: Make clang to emit full names for variables in namespaces + // (as MSVC does) + + std::string name(symbol.getRawSymbol().getName()); + MSVCUndecoratedNameParser parser(name); + llvm::ArrayRef specs = parser.GetSpecifiers(); + if (specs.empty()) + return m_ast.GetTranslationUnitDecl(); + + auto symbol_file = static_cast(m_ast.GetSymbolFile()); + if (!symbol_file) + return m_ast.GetTranslationUnitDecl(); + + auto global = symbol_file->GetPDBSession().getGlobalScope(); + if (!global) + return m_ast.GetTranslationUnitDecl(); + + bool has_type_or_function_parent = false; + clang::DeclContext *curr_context = m_ast.GetTranslationUnitDecl(); + for (std::size_t i = 0; i < specs.size() - 1; i++) { + // Check if there is a function or a type with the current context's name. + if (std::unique_ptr children_enum = global->findChildren( + PDB_SymType::None, specs[i].GetFullName(), NS_CaseSensitive)) { + while (IPDBEnumChildren::ChildTypePtr child = + children_enum->getNext()) { + if (clang::DeclContext *child_context = + GetDeclContextForSymbol(*child)) { + // Note that `GetDeclContextForSymbol' retrieves + // a declaration context for functions and types only, + // so if we are here then `child_context' is guaranteed + // a function or a type declaration context. + has_type_or_function_parent = true; + curr_context = child_context; + } + } + } + + // If there were no functions or types above then retrieve a namespace with + // the current context's name. There can be no namespaces inside a function + // or a type. We check it to avoid fake namespaces such as `__l2': + // `N0::N1::CClass::PrivateFunc::__l2::InnerFuncStruct' + if (!has_type_or_function_parent) { + std::string namespace_name = specs[i].GetBaseName(); + const char *namespace_name_c_str = + IsAnonymousNamespaceName(namespace_name) ? nullptr + : namespace_name.data(); + clang::NamespaceDecl *namespace_decl = + m_ast.GetUniqueNamespaceDeclaration(namespace_name_c_str, + curr_context); + + m_parent_to_namespaces[curr_context].insert(namespace_decl); + m_namespaces.insert(namespace_decl); + + curr_context = namespace_decl; + } + } + + return curr_context; +} + +void PDBASTParser::ParseDeclsForDeclContext( + const clang::DeclContext *decl_context) { + auto symbol_file = static_cast(m_ast.GetSymbolFile()); + if (!symbol_file) + return; + + IPDBSession &session = symbol_file->GetPDBSession(); + auto symbol_up = + session.getSymbolById(m_decl_context_to_uid.lookup(decl_context)); + auto global_up = session.getGlobalScope(); + + PDBSymbol *symbol; + if (symbol_up) + symbol = symbol_up.get(); + else if (global_up) + symbol = global_up.get(); + else + return; + + if (auto children = symbol->findAllChildren()) + while (auto child = children->getNext()) + GetDeclForSymbol(*child); +} + +clang::NamespaceDecl * +PDBASTParser::FindNamespaceDecl(const clang::DeclContext *parent, + llvm::StringRef name) { + NamespacesSet *set; + if (parent) { + auto pit = m_parent_to_namespaces.find(parent); + if (pit == m_parent_to_namespaces.end()) + return nullptr; + + set = &pit->second; + } else { + set = &m_namespaces; + } + assert(set); + + for (clang::NamespaceDecl *namespace_decl : *set) + if (namespace_decl->getName().equals(name)) + return namespace_decl; + + for (clang::NamespaceDecl *namespace_decl : *set) + if (namespace_decl->isAnonymousNamespace()) + return FindNamespaceDecl(namespace_decl, name); + + return nullptr; +} + bool PDBASTParser::AddEnumValue(CompilerType enum_type, - const PDBSymbolData &enum_value) const { + const PDBSymbolData &enum_value) { Declaration decl; Variant v = enum_value.getValue(); - std::string name = enum_value.getName(); + std::string name = MSVCUndecoratedNameParser::DropScope(enum_value.getName()); int64_t raw_value; switch (v.Type) { case PDB_VariantType::Int8: @@ -509,7 +1148,213 @@ bool PDBASTParser::AddEnumValue(CompilerType enum_type, m_ast.GetEnumerationIntegerType(enum_type.GetOpaqueQualType()); uint32_t byte_size = m_ast.getASTContext()->getTypeSize( ClangUtil::GetQualType(underlying_type)); - return m_ast.AddEnumerationValueToEnumerationType( - enum_type.GetOpaqueQualType(), underlying_type, decl, name.c_str(), - raw_value, byte_size * 8); + auto enum_constant_decl = m_ast.AddEnumerationValueToEnumerationType( + enum_type, decl, name.c_str(), raw_value, byte_size * 8); + if (!enum_constant_decl) + return false; + + m_uid_to_decl[enum_value.getSymIndexId()] = enum_constant_decl; + + return true; +} + +bool PDBASTParser::CompleteTypeFromUDT( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &compiler_type, + llvm::pdb::PDBSymbolTypeUDT &udt) { + ClangASTImporter::LayoutInfo layout_info; + layout_info.bit_size = udt.getLength() * 8; + + auto nested_enums = udt.findAllChildren(); + if (nested_enums) + while (auto nested = nested_enums->getNext()) + symbol_file.ResolveTypeUID(nested->getSymIndexId()); + + auto bases_enum = udt.findAllChildren(); + if (bases_enum) + AddRecordBases(symbol_file, compiler_type, + TranslateUdtKind(udt.getUdtKind()), *bases_enum, + layout_info); + + auto members_enum = udt.findAllChildren(); + if (members_enum) + AddRecordMembers(symbol_file, compiler_type, *members_enum, layout_info); + + auto methods_enum = udt.findAllChildren(); + if (methods_enum) + AddRecordMethods(symbol_file, compiler_type, *methods_enum); + + m_ast.AddMethodOverridesForCXXRecordType(compiler_type.GetOpaqueQualType()); + ClangASTContext::BuildIndirectFields(compiler_type); + ClangASTContext::CompleteTagDeclarationDefinition(compiler_type); + + clang::CXXRecordDecl *record_decl = + m_ast.GetAsCXXRecordDecl(compiler_type.GetOpaqueQualType()); + if (!record_decl) + return static_cast(compiler_type); + + GetClangASTImporter().InsertRecordDecl(record_decl, layout_info); + + return static_cast(compiler_type); +} + +void PDBASTParser::AddRecordMembers( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + PDBDataSymbolEnumerator &members_enum, + lldb_private::ClangASTImporter::LayoutInfo &layout_info) { + while (auto member = members_enum.getNext()) { + if (member->isCompilerGenerated()) + continue; + + auto member_name = member->getName(); + + auto member_type = symbol_file.ResolveTypeUID(member->getTypeId()); + if (!member_type) + continue; + + auto member_comp_type = member_type->GetLayoutCompilerType(); + if (!member_comp_type.GetCompleteType()) { + symbol_file.GetObjectFile()->GetModule()->ReportError( + ":: Class '%s' has a member '%s' of type '%s' " + "which does not have a complete definition.", + record_type.GetTypeName().GetCString(), member_name.c_str(), + member_comp_type.GetTypeName().GetCString()); + if (ClangASTContext::StartTagDeclarationDefinition(member_comp_type)) + ClangASTContext::CompleteTagDeclarationDefinition(member_comp_type); + } + + auto access = TranslateMemberAccess(member->getAccess()); + + switch (member->getDataKind()) { + case PDB_DataKind::Member: { + auto location_type = member->getLocationType(); + + auto bit_size = member->getLength(); + if (location_type == PDB_LocType::ThisRel) + bit_size *= 8; + + auto decl = ClangASTContext::AddFieldToRecordType( + record_type, member_name.c_str(), member_comp_type, access, bit_size); + if (!decl) + continue; + + m_uid_to_decl[member->getSymIndexId()] = decl; + + auto offset = member->getOffset() * 8; + if (location_type == PDB_LocType::BitField) + offset += member->getBitPosition(); + + layout_info.field_offsets.insert(std::make_pair(decl, offset)); + + break; + } + case PDB_DataKind::StaticMember: { + auto decl = ClangASTContext::AddVariableToRecordType( + record_type, member_name.c_str(), member_comp_type, access); + if (!decl) + continue; + + m_uid_to_decl[member->getSymIndexId()] = decl; + + break; + } + default: + llvm_unreachable("unsupported PDB data kind"); + } + } +} + +void PDBASTParser::AddRecordBases( + lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, int record_kind, + PDBBaseClassSymbolEnumerator &bases_enum, + lldb_private::ClangASTImporter::LayoutInfo &layout_info) const { + std::vector> base_classes; + + while (auto base = bases_enum.getNext()) { + auto base_type = symbol_file.ResolveTypeUID(base->getTypeId()); + if (!base_type) + continue; + + auto base_comp_type = base_type->GetFullCompilerType(); + if (!base_comp_type.GetCompleteType()) { + symbol_file.GetObjectFile()->GetModule()->ReportError( + ":: Class '%s' has a base class '%s' " + "which does not have a complete definition.", + record_type.GetTypeName().GetCString(), + base_comp_type.GetTypeName().GetCString()); + if (ClangASTContext::StartTagDeclarationDefinition(base_comp_type)) + ClangASTContext::CompleteTagDeclarationDefinition(base_comp_type); + } + + auto access = TranslateMemberAccess(base->getAccess()); + + auto is_virtual = base->isVirtualBaseClass(); + + std::unique_ptr base_spec = + m_ast.CreateBaseClassSpecifier(base_comp_type.GetOpaqueQualType(), + access, is_virtual, + record_kind == clang::TTK_Class); + lldbassert(base_spec); + + base_classes.push_back(std::move(base_spec)); + + if (is_virtual) + continue; + + auto decl = m_ast.GetAsCXXRecordDecl(base_comp_type.GetOpaqueQualType()); + if (!decl) + continue; + + auto offset = clang::CharUnits::fromQuantity(base->getOffset()); + layout_info.base_offsets.insert(std::make_pair(decl, offset)); + } + + m_ast.TransferBaseClasses(record_type.GetOpaqueQualType(), + std::move(base_classes)); +} + +void PDBASTParser::AddRecordMethods(lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + PDBFuncSymbolEnumerator &methods_enum) { + while (std::unique_ptr method = methods_enum.getNext()) + if (clang::CXXMethodDecl *decl = + AddRecordMethod(symbol_file, record_type, *method)) + m_uid_to_decl[method->getSymIndexId()] = decl; +} + +clang::CXXMethodDecl * +PDBASTParser::AddRecordMethod(lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + const llvm::pdb::PDBSymbolFunc &method) const { + std::string name = MSVCUndecoratedNameParser::DropScope(method.getName()); + + Type *method_type = symbol_file.ResolveTypeUID(method.getSymIndexId()); + // MSVC specific __vecDelDtor. + if (!method_type) + return nullptr; + + CompilerType method_comp_type = method_type->GetFullCompilerType(); + if (!method_comp_type.GetCompleteType()) { + symbol_file.GetObjectFile()->GetModule()->ReportError( + ":: Class '%s' has a method '%s' whose type cannot be completed.", + record_type.GetTypeName().GetCString(), + method_comp_type.GetTypeName().GetCString()); + if (ClangASTContext::StartTagDeclarationDefinition(method_comp_type)) + ClangASTContext::CompleteTagDeclarationDefinition(method_comp_type); + } + + AccessType access = TranslateMemberAccess(method.getAccess()); + if (access == eAccessNone) + access = eAccessPublic; + + // TODO: get mangled name for the method. + return m_ast.AddMethodToCXXRecordType( + record_type.GetOpaqueQualType(), name.c_str(), + /*mangled_name*/ nullptr, method_comp_type, access, method.isVirtual(), + method.isStatic(), method.hasInlineAttribute(), + /*is_explicit*/ false, // FIXME: Need this field in CodeView. + /*is_attr_used*/ false, + /*is_artificial*/ method.isCompilerGenerated()); } diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h index d1ac138b8115..02353870ab60 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.h @@ -14,6 +14,8 @@ #include "lldb/Symbol/ClangASTImporter.h" +class SymbolFilePDB; + namespace clang { class CharUnits; class CXXRecordDecl; @@ -28,9 +30,14 @@ class CompilerType; namespace llvm { namespace pdb { +template class ConcreteSymbolEnumerator; + class PDBSymbol; class PDBSymbolData; +class PDBSymbolFunc; +class PDBSymbolTypeBaseClass; class PDBSymbolTypeBuiltin; +class PDBSymbolTypeUDT; } // namespace pdb } // namespace llvm @@ -40,13 +47,71 @@ public: ~PDBASTParser(); lldb::TypeSP CreateLLDBTypeFromPDBType(const llvm::pdb::PDBSymbol &type); + bool CompleteTypeFromPDB(lldb_private::CompilerType &compiler_type); + + clang::Decl *GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol); + + clang::DeclContext * + GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol); + clang::DeclContext * + GetDeclContextContainingSymbol(const llvm::pdb::PDBSymbol &symbol); + + void ParseDeclsForDeclContext(const clang::DeclContext *decl_context); + + clang::NamespaceDecl *FindNamespaceDecl(const clang::DeclContext *parent, + llvm::StringRef name); + + lldb_private::ClangASTImporter &GetClangASTImporter() { + return m_ast_importer; + } private: + typedef llvm::DenseMap + CXXRecordDeclToUidMap; + typedef llvm::DenseMap UidToDeclMap; + typedef std::set NamespacesSet; + typedef llvm::DenseMap + ParentToNamespacesMap; + typedef llvm::DenseMap + DeclContextToUidMap; + typedef llvm::pdb::ConcreteSymbolEnumerator + PDBDataSymbolEnumerator; + typedef llvm::pdb::ConcreteSymbolEnumerator + PDBBaseClassSymbolEnumerator; + typedef llvm::pdb::ConcreteSymbolEnumerator + PDBFuncSymbolEnumerator; + bool AddEnumValue(lldb_private::CompilerType enum_type, - const llvm::pdb::PDBSymbolData &data) const; + const llvm::pdb::PDBSymbolData &data); + bool CompleteTypeFromUDT(lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &compiler_type, + llvm::pdb::PDBSymbolTypeUDT &udt); + void + AddRecordMembers(lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + PDBDataSymbolEnumerator &members_enum, + lldb_private::ClangASTImporter::LayoutInfo &layout_info); + void + AddRecordBases(lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, int record_kind, + PDBBaseClassSymbolEnumerator &bases_enum, + lldb_private::ClangASTImporter::LayoutInfo &layout_info) const; + void AddRecordMethods(lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + PDBFuncSymbolEnumerator &methods_enum); + clang::CXXMethodDecl * + AddRecordMethod(lldb_private::SymbolFile &symbol_file, + lldb_private::CompilerType &record_type, + const llvm::pdb::PDBSymbolFunc &method) const; lldb_private::ClangASTContext &m_ast; lldb_private::ClangASTImporter m_ast_importer; + + CXXRecordDeclToUidMap m_forward_decl_to_uid; + UidToDeclMap m_uid_to_decl; + ParentToNamespacesMap m_parent_to_namespaces; + NamespacesSet m_namespaces; + DeclContextToUidMap m_decl_context_to_uid; }; #endif // LLDB_PLUGINS_SYMBOLFILE_PDB_PDBASTPARSER_H diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp index 69ef70cc508c..9f398ef9b047 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp @@ -26,51 +26,51 @@ using namespace llvm::pdb; namespace { const uint32_t g_code_view_to_lldb_registers_x86[] = { - LLDB_INVALID_REGNUM, // CVRegNONE - lldb_al_i386, // CVRegAL - lldb_cl_i386, // CVRegCL - lldb_dl_i386, // CVRegDL - lldb_bl_i386, // CVRegBL - lldb_ah_i386, // CVRegAH - lldb_ch_i386, // CVRegCH - lldb_dh_i386, // CVRegDH - lldb_bh_i386, // CVRegBH - lldb_ax_i386, // CVRegAX - lldb_cx_i386, // CVRegCX - lldb_dx_i386, // CVRegDX - lldb_bx_i386, // CVRegBX - lldb_sp_i386, // CVRegSP - lldb_bp_i386, // CVRegBP - lldb_si_i386, // CVRegSI - lldb_di_i386, // CVRegDI - lldb_eax_i386, // CVRegEAX - lldb_ecx_i386, // CVRegECX - lldb_edx_i386, // CVRegEDX - lldb_ebx_i386, // CVRegEBX - lldb_esp_i386, // CVRegESP - lldb_ebp_i386, // CVRegEBP - lldb_esi_i386, // CVRegESI - lldb_edi_i386, // CVRegEDI - lldb_es_i386, // CVRegES - lldb_cs_i386, // CVRegCS - lldb_ss_i386, // CVRegSS - lldb_ds_i386, // CVRegDS - lldb_fs_i386, // CVRegFS - lldb_gs_i386, // CVRegGS - LLDB_INVALID_REGNUM, // CVRegIP - LLDB_INVALID_REGNUM, // CVRegFLAGS - lldb_eip_i386, // CVRegEIP - lldb_eflags_i386, // CVRegEFLAGS + LLDB_INVALID_REGNUM, // NONE + lldb_al_i386, // AL + lldb_cl_i386, // CL + lldb_dl_i386, // DL + lldb_bl_i386, // BL + lldb_ah_i386, // AH + lldb_ch_i386, // CH + lldb_dh_i386, // DH + lldb_bh_i386, // BH + lldb_ax_i386, // AX + lldb_cx_i386, // CX + lldb_dx_i386, // DX + lldb_bx_i386, // BX + lldb_sp_i386, // SP + lldb_bp_i386, // BP + lldb_si_i386, // SI + lldb_di_i386, // DI + lldb_eax_i386, // EAX + lldb_ecx_i386, // ECX + lldb_edx_i386, // EDX + lldb_ebx_i386, // EBX + lldb_esp_i386, // ESP + lldb_ebp_i386, // EBP + lldb_esi_i386, // ESI + lldb_edi_i386, // EDI + lldb_es_i386, // ES + lldb_cs_i386, // CS + lldb_ss_i386, // SS + lldb_ds_i386, // DS + lldb_fs_i386, // FS + lldb_gs_i386, // GS + LLDB_INVALID_REGNUM, // IP + LLDB_INVALID_REGNUM, // FLAGS + lldb_eip_i386, // EIP + lldb_eflags_i386, // EFLAGS LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, // CVRegTEMP - LLDB_INVALID_REGNUM, // CVRegTEMPH - LLDB_INVALID_REGNUM, // CVRegQUOTE - LLDB_INVALID_REGNUM, // CVRegPCDR3 - LLDB_INVALID_REGNUM, // CVRegPCDR4 - LLDB_INVALID_REGNUM, // CVRegPCDR5 - LLDB_INVALID_REGNUM, // CVRegPCDR6 - LLDB_INVALID_REGNUM, // CVRegPCDR7 + LLDB_INVALID_REGNUM, // TEMP + LLDB_INVALID_REGNUM, // TEMPH + LLDB_INVALID_REGNUM, // QUOTE + LLDB_INVALID_REGNUM, // PCDR3 + LLDB_INVALID_REGNUM, // PCDR4 + LLDB_INVALID_REGNUM, // PCDR5 + LLDB_INVALID_REGNUM, // PCDR6 + LLDB_INVALID_REGNUM, // PCDR7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, @@ -82,123 +82,123 @@ const uint32_t g_code_view_to_lldb_registers_x86[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, // CVRegCR0 - LLDB_INVALID_REGNUM, // CVRegCR1 - LLDB_INVALID_REGNUM, // CVRegCR2 - LLDB_INVALID_REGNUM, // CVRegCR3 - LLDB_INVALID_REGNUM, // CVRegCR4 + LLDB_INVALID_REGNUM, // CR0 + LLDB_INVALID_REGNUM, // CR1 + LLDB_INVALID_REGNUM, // CR2 + LLDB_INVALID_REGNUM, // CR3 + LLDB_INVALID_REGNUM, // CR4 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - lldb_dr0_i386, // CVRegDR0 - lldb_dr1_i386, // CVRegDR1 - lldb_dr2_i386, // CVRegDR2 - lldb_dr3_i386, // CVRegDR3 - lldb_dr4_i386, // CVRegDR4 - lldb_dr5_i386, // CVRegDR5 - lldb_dr6_i386, // CVRegDR6 - lldb_dr7_i386, // CVRegDR7 + lldb_dr0_i386, // DR0 + lldb_dr1_i386, // DR1 + lldb_dr2_i386, // DR2 + lldb_dr3_i386, // DR3 + lldb_dr4_i386, // DR4 + lldb_dr5_i386, // DR5 + lldb_dr6_i386, // DR6 + lldb_dr7_i386, // DR7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, // CVRegGDTR - LLDB_INVALID_REGNUM, // CVRegGDTL - LLDB_INVALID_REGNUM, // CVRegIDTR - LLDB_INVALID_REGNUM, // CVRegIDTL - LLDB_INVALID_REGNUM, // CVRegLDTR - LLDB_INVALID_REGNUM, // CVRegTR - LLDB_INVALID_REGNUM, // CVRegPSEUDO1 - LLDB_INVALID_REGNUM, // CVRegPSEUDO2 - LLDB_INVALID_REGNUM, // CVRegPSEUDO3 - LLDB_INVALID_REGNUM, // CVRegPSEUDO4 - LLDB_INVALID_REGNUM, // CVRegPSEUDO5 - LLDB_INVALID_REGNUM, // CVRegPSEUDO6 - LLDB_INVALID_REGNUM, // CVRegPSEUDO7 - LLDB_INVALID_REGNUM, // CVRegPSEUDO8 - LLDB_INVALID_REGNUM, // CVRegPSEUDO9 + LLDB_INVALID_REGNUM, // GDTR + LLDB_INVALID_REGNUM, // GDTL + LLDB_INVALID_REGNUM, // IDTR + LLDB_INVALID_REGNUM, // IDTL + LLDB_INVALID_REGNUM, // LDTR + LLDB_INVALID_REGNUM, // TR + LLDB_INVALID_REGNUM, // PSEUDO1 + LLDB_INVALID_REGNUM, // PSEUDO2 + LLDB_INVALID_REGNUM, // PSEUDO3 + LLDB_INVALID_REGNUM, // PSEUDO4 + LLDB_INVALID_REGNUM, // PSEUDO5 + LLDB_INVALID_REGNUM, // PSEUDO6 + LLDB_INVALID_REGNUM, // PSEUDO7 + LLDB_INVALID_REGNUM, // PSEUDO8 + LLDB_INVALID_REGNUM, // PSEUDO9 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - lldb_st0_i386, // CVRegST0 - lldb_st1_i386, // CVRegST1 - lldb_st2_i386, // CVRegST2 - lldb_st3_i386, // CVRegST3 - lldb_st4_i386, // CVRegST4 - lldb_st5_i386, // CVRegST5 - lldb_st6_i386, // CVRegST6 - lldb_st7_i386, // CVRegST7 - LLDB_INVALID_REGNUM, // CVRegCTRL - LLDB_INVALID_REGNUM, // CVRegSTAT - LLDB_INVALID_REGNUM, // CVRegTAG - LLDB_INVALID_REGNUM, // CVRegFPIP - LLDB_INVALID_REGNUM, // CVRegFPCS - LLDB_INVALID_REGNUM, // CVRegFPDO - LLDB_INVALID_REGNUM, // CVRegFPDS - LLDB_INVALID_REGNUM, // CVRegISEM - LLDB_INVALID_REGNUM, // CVRegFPEIP - LLDB_INVALID_REGNUM, // CVRegFPEDO - lldb_mm0_i386, // CVRegMM0 - lldb_mm1_i386, // CVRegMM1 - lldb_mm2_i386, // CVRegMM2 - lldb_mm3_i386, // CVRegMM3 - lldb_mm4_i386, // CVRegMM4 - lldb_mm5_i386, // CVRegMM5 - lldb_mm6_i386, // CVRegMM6 - lldb_mm7_i386, // CVRegMM7 - lldb_xmm0_i386, // CVRegXMM0 - lldb_xmm1_i386, // CVRegXMM1 - lldb_xmm2_i386, // CVRegXMM2 - lldb_xmm3_i386, // CVRegXMM3 - lldb_xmm4_i386, // CVRegXMM4 - lldb_xmm5_i386, // CVRegXMM5 - lldb_xmm6_i386, // CVRegXMM6 - lldb_xmm7_i386 // CVRegXMM7 + lldb_st0_i386, // ST0 + lldb_st1_i386, // ST1 + lldb_st2_i386, // ST2 + lldb_st3_i386, // ST3 + lldb_st4_i386, // ST4 + lldb_st5_i386, // ST5 + lldb_st6_i386, // ST6 + lldb_st7_i386, // ST7 + LLDB_INVALID_REGNUM, // CTRL + LLDB_INVALID_REGNUM, // STAT + LLDB_INVALID_REGNUM, // TAG + LLDB_INVALID_REGNUM, // FPIP + LLDB_INVALID_REGNUM, // FPCS + LLDB_INVALID_REGNUM, // FPDO + LLDB_INVALID_REGNUM, // FPDS + LLDB_INVALID_REGNUM, // ISEM + LLDB_INVALID_REGNUM, // FPEIP + LLDB_INVALID_REGNUM, // FPEDO + lldb_mm0_i386, // MM0 + lldb_mm1_i386, // MM1 + lldb_mm2_i386, // MM2 + lldb_mm3_i386, // MM3 + lldb_mm4_i386, // MM4 + lldb_mm5_i386, // MM5 + lldb_mm6_i386, // MM6 + lldb_mm7_i386, // MM7 + lldb_xmm0_i386, // XMM0 + lldb_xmm1_i386, // XMM1 + lldb_xmm2_i386, // XMM2 + lldb_xmm3_i386, // XMM3 + lldb_xmm4_i386, // XMM4 + lldb_xmm5_i386, // XMM5 + lldb_xmm6_i386, // XMM6 + lldb_xmm7_i386 // XMM7 }; const uint32_t g_code_view_to_lldb_registers_x86_64[] = { - LLDB_INVALID_REGNUM, // CVRegNONE - lldb_al_x86_64, // CVRegAL - lldb_cl_x86_64, // CVRegCL - lldb_dl_x86_64, // CVRegDL - lldb_bl_x86_64, // CVRegBL - lldb_ah_x86_64, // CVRegAH - lldb_ch_x86_64, // CVRegCH - lldb_dh_x86_64, // CVRegDH - lldb_bh_x86_64, // CVRegBH - lldb_ax_x86_64, // CVRegAX - lldb_cx_x86_64, // CVRegCX - lldb_dx_x86_64, // CVRegDX - lldb_bx_x86_64, // CVRegBX - lldb_sp_x86_64, // CVRegSP - lldb_bp_x86_64, // CVRegBP - lldb_si_x86_64, // CVRegSI - lldb_di_x86_64, // CVRegDI - lldb_eax_x86_64, // CVRegEAX - lldb_ecx_x86_64, // CVRegECX - lldb_edx_x86_64, // CVRegEDX - lldb_ebx_x86_64, // CVRegEBX - lldb_esp_x86_64, // CVRegESP - lldb_ebp_x86_64, // CVRegEBP - lldb_esi_x86_64, // CVRegESI - lldb_edi_x86_64, // CVRegEDI - lldb_es_x86_64, // CVRegES - lldb_cs_x86_64, // CVRegCS - lldb_ss_x86_64, // CVRegSS - lldb_ds_x86_64, // CVRegDS - lldb_fs_x86_64, // CVRegFS - lldb_gs_x86_64, // CVRegGS - LLDB_INVALID_REGNUM, // CVRegIP - LLDB_INVALID_REGNUM, // CVRegFLAGS - LLDB_INVALID_REGNUM, // CVRegEIP - LLDB_INVALID_REGNUM, // CVRegEFLAGS + LLDB_INVALID_REGNUM, // NONE + lldb_al_x86_64, // AL + lldb_cl_x86_64, // CL + lldb_dl_x86_64, // DL + lldb_bl_x86_64, // BL + lldb_ah_x86_64, // AH + lldb_ch_x86_64, // CH + lldb_dh_x86_64, // DH + lldb_bh_x86_64, // BH + lldb_ax_x86_64, // AX + lldb_cx_x86_64, // CX + lldb_dx_x86_64, // DX + lldb_bx_x86_64, // BX + lldb_sp_x86_64, // SP + lldb_bp_x86_64, // BP + lldb_si_x86_64, // SI + lldb_di_x86_64, // DI + lldb_eax_x86_64, // EAX + lldb_ecx_x86_64, // ECX + lldb_edx_x86_64, // EDX + lldb_ebx_x86_64, // EBX + lldb_esp_x86_64, // ESP + lldb_ebp_x86_64, // EBP + lldb_esi_x86_64, // ESI + lldb_edi_x86_64, // EDI + lldb_es_x86_64, // ES + lldb_cs_x86_64, // CS + lldb_ss_x86_64, // SS + lldb_ds_x86_64, // DS + lldb_fs_x86_64, // FS + lldb_gs_x86_64, // GS + LLDB_INVALID_REGNUM, // IP + LLDB_INVALID_REGNUM, // FLAGS + LLDB_INVALID_REGNUM, // EIP + LLDB_INVALID_REGNUM, // EFLAGS LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, // CVRegTEMP - LLDB_INVALID_REGNUM, // CVRegTEMPH - LLDB_INVALID_REGNUM, // CVRegQUOTE - LLDB_INVALID_REGNUM, // CVRegPCDR3 - LLDB_INVALID_REGNUM, // CVRegPCDR4 - LLDB_INVALID_REGNUM, // CVRegPCDR5 - LLDB_INVALID_REGNUM, // CVRegPCDR6 - LLDB_INVALID_REGNUM, // CVRegPCDR7 + LLDB_INVALID_REGNUM, // TEMP + LLDB_INVALID_REGNUM, // TEMPH + LLDB_INVALID_REGNUM, // QUOTE + LLDB_INVALID_REGNUM, // PCDR3 + LLDB_INVALID_REGNUM, // PCDR4 + LLDB_INVALID_REGNUM, // PCDR5 + LLDB_INVALID_REGNUM, // PCDR6 + LLDB_INVALID_REGNUM, // PCDR7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, @@ -210,75 +210,75 @@ const uint32_t g_code_view_to_lldb_registers_x86_64[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, // CVRegCR0 - LLDB_INVALID_REGNUM, // CVRegCR1 - LLDB_INVALID_REGNUM, // CVRegCR2 - LLDB_INVALID_REGNUM, // CVRegCR3 - LLDB_INVALID_REGNUM, // CVRegCR4 + LLDB_INVALID_REGNUM, // CR0 + LLDB_INVALID_REGNUM, // CR1 + LLDB_INVALID_REGNUM, // CR2 + LLDB_INVALID_REGNUM, // CR3 + LLDB_INVALID_REGNUM, // CR4 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - lldb_dr0_x86_64, // CVRegDR0 - lldb_dr1_x86_64, // CVRegDR1 - lldb_dr2_x86_64, // CVRegDR2 - lldb_dr3_x86_64, // CVRegDR3 - lldb_dr4_x86_64, // CVRegDR4 - lldb_dr5_x86_64, // CVRegDR5 - lldb_dr6_x86_64, // CVRegDR6 - lldb_dr7_x86_64, // CVRegDR7 + lldb_dr0_x86_64, // DR0 + lldb_dr1_x86_64, // DR1 + lldb_dr2_x86_64, // DR2 + lldb_dr3_x86_64, // DR3 + lldb_dr4_x86_64, // DR4 + lldb_dr5_x86_64, // DR5 + lldb_dr6_x86_64, // DR6 + lldb_dr7_x86_64, // DR7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, // CVRegGDTR - LLDB_INVALID_REGNUM, // CVRegGDTL - LLDB_INVALID_REGNUM, // CVRegIDTR - LLDB_INVALID_REGNUM, // CVRegIDTL - LLDB_INVALID_REGNUM, // CVRegLDTR - LLDB_INVALID_REGNUM, // CVRegTR - LLDB_INVALID_REGNUM, // CVRegPSEUDO1 - LLDB_INVALID_REGNUM, // CVRegPSEUDO2 - LLDB_INVALID_REGNUM, // CVRegPSEUDO3 - LLDB_INVALID_REGNUM, // CVRegPSEUDO4 - LLDB_INVALID_REGNUM, // CVRegPSEUDO5 - LLDB_INVALID_REGNUM, // CVRegPSEUDO6 - LLDB_INVALID_REGNUM, // CVRegPSEUDO7 - LLDB_INVALID_REGNUM, // CVRegPSEUDO8 - LLDB_INVALID_REGNUM, // CVRegPSEUDO9 + LLDB_INVALID_REGNUM, // GDTR + LLDB_INVALID_REGNUM, // GDTL + LLDB_INVALID_REGNUM, // IDTR + LLDB_INVALID_REGNUM, // IDTL + LLDB_INVALID_REGNUM, // LDTR + LLDB_INVALID_REGNUM, // TR + LLDB_INVALID_REGNUM, // PSEUDO1 + LLDB_INVALID_REGNUM, // PSEUDO2 + LLDB_INVALID_REGNUM, // PSEUDO3 + LLDB_INVALID_REGNUM, // PSEUDO4 + LLDB_INVALID_REGNUM, // PSEUDO5 + LLDB_INVALID_REGNUM, // PSEUDO6 + LLDB_INVALID_REGNUM, // PSEUDO7 + LLDB_INVALID_REGNUM, // PSEUDO8 + LLDB_INVALID_REGNUM, // PSEUDO9 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - lldb_st0_x86_64, // CVRegST0 - lldb_st1_x86_64, // CVRegST1 - lldb_st2_x86_64, // CVRegST2 - lldb_st3_x86_64, // CVRegST3 - lldb_st4_x86_64, // CVRegST4 - lldb_st5_x86_64, // CVRegST5 - lldb_st6_x86_64, // CVRegST6 - lldb_st7_x86_64, // CVRegST7 - LLDB_INVALID_REGNUM, // CVRegCTRL - LLDB_INVALID_REGNUM, // CVRegSTAT - LLDB_INVALID_REGNUM, // CVRegTAG - LLDB_INVALID_REGNUM, // CVRegFPIP - LLDB_INVALID_REGNUM, // CVRegFPCS - LLDB_INVALID_REGNUM, // CVRegFPDO - LLDB_INVALID_REGNUM, // CVRegFPDS - LLDB_INVALID_REGNUM, // CVRegISEM - LLDB_INVALID_REGNUM, // CVRegFPEIP - LLDB_INVALID_REGNUM, // CVRegFPEDO - lldb_mm0_x86_64, // CVRegMM0 - lldb_mm1_x86_64, // CVRegMM1 - lldb_mm2_x86_64, // CVRegMM2 - lldb_mm3_x86_64, // CVRegMM3 - lldb_mm4_x86_64, // CVRegMM4 - lldb_mm5_x86_64, // CVRegMM5 - lldb_mm6_x86_64, // CVRegMM6 - lldb_mm7_x86_64, // CVRegMM7 - lldb_xmm0_x86_64, // CVRegXMM0 - lldb_xmm1_x86_64, // CVRegXMM1 - lldb_xmm2_x86_64, // CVRegXMM2 - lldb_xmm3_x86_64, // CVRegXMM3 - lldb_xmm4_x86_64, // CVRegXMM4 - lldb_xmm5_x86_64, // CVRegXMM5 - lldb_xmm6_x86_64, // CVRegXMM6 - lldb_xmm7_x86_64, // CVRegXMM7 + lldb_st0_x86_64, // ST0 + lldb_st1_x86_64, // ST1 + lldb_st2_x86_64, // ST2 + lldb_st3_x86_64, // ST3 + lldb_st4_x86_64, // ST4 + lldb_st5_x86_64, // ST5 + lldb_st6_x86_64, // ST6 + lldb_st7_x86_64, // ST7 + LLDB_INVALID_REGNUM, // CTRL + LLDB_INVALID_REGNUM, // STAT + LLDB_INVALID_REGNUM, // TAG + LLDB_INVALID_REGNUM, // FPIP + LLDB_INVALID_REGNUM, // FPCS + LLDB_INVALID_REGNUM, // FPDO + LLDB_INVALID_REGNUM, // FPDS + LLDB_INVALID_REGNUM, // ISEM + LLDB_INVALID_REGNUM, // FPEIP + LLDB_INVALID_REGNUM, // FPEDO + lldb_mm0_x86_64, // MM0 + lldb_mm1_x86_64, // MM1 + lldb_mm2_x86_64, // MM2 + lldb_mm3_x86_64, // MM3 + lldb_mm4_x86_64, // MM4 + lldb_mm5_x86_64, // MM5 + lldb_mm6_x86_64, // MM6 + lldb_mm7_x86_64, // MM7 + lldb_xmm0_x86_64, // XMM0 + lldb_xmm1_x86_64, // XMM1 + lldb_xmm2_x86_64, // XMM2 + lldb_xmm3_x86_64, // XMM3 + lldb_xmm4_x86_64, // XMM4 + lldb_xmm5_x86_64, // XMM5 + lldb_xmm6_x86_64, // XMM6 + lldb_xmm7_x86_64, // XMM7 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, @@ -296,51 +296,51 @@ const uint32_t g_code_view_to_lldb_registers_x86_64[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - lldb_mxcsr_x86_64, // CVRegMXCSR - LLDB_INVALID_REGNUM, // CVRegEDXEAX + lldb_mxcsr_x86_64, // MXCSR + LLDB_INVALID_REGNUM, // EDXEAX LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - LLDB_INVALID_REGNUM, // CVRegEMM0L - LLDB_INVALID_REGNUM, // CVRegEMM1L - LLDB_INVALID_REGNUM, // CVRegEMM2L - LLDB_INVALID_REGNUM, // CVRegEMM3L - LLDB_INVALID_REGNUM, // CVRegEMM4L - LLDB_INVALID_REGNUM, // CVRegEMM5L - LLDB_INVALID_REGNUM, // CVRegEMM6L - LLDB_INVALID_REGNUM, // CVRegEMM7L - LLDB_INVALID_REGNUM, // CVRegEMM0H - LLDB_INVALID_REGNUM, // CVRegEMM1H - LLDB_INVALID_REGNUM, // CVRegEMM2H - LLDB_INVALID_REGNUM, // CVRegEMM3H - LLDB_INVALID_REGNUM, // CVRegEMM4H - LLDB_INVALID_REGNUM, // CVRegEMM5H - LLDB_INVALID_REGNUM, // CVRegEMM6H - LLDB_INVALID_REGNUM, // CVRegEMM7H - LLDB_INVALID_REGNUM, // CVRegMM00 - LLDB_INVALID_REGNUM, // CVRegMM01 - LLDB_INVALID_REGNUM, // CVRegMM10 - LLDB_INVALID_REGNUM, // CVRegMM11 - LLDB_INVALID_REGNUM, // CVRegMM20 - LLDB_INVALID_REGNUM, // CVRegMM21 - LLDB_INVALID_REGNUM, // CVRegMM30 - LLDB_INVALID_REGNUM, // CVRegMM31 - LLDB_INVALID_REGNUM, // CVRegMM40 - LLDB_INVALID_REGNUM, // CVRegMM41 - LLDB_INVALID_REGNUM, // CVRegMM50 - LLDB_INVALID_REGNUM, // CVRegMM51 - LLDB_INVALID_REGNUM, // CVRegMM60 - LLDB_INVALID_REGNUM, // CVRegMM61 - LLDB_INVALID_REGNUM, // CVRegMM70 - LLDB_INVALID_REGNUM, // CVRegMM71 - lldb_xmm8_x86_64, // CVRegXMM8 - lldb_xmm9_x86_64, // CVRegXMM9 - lldb_xmm10_x86_64, // CVRegXMM10 - lldb_xmm11_x86_64, // CVRegXMM11 - lldb_xmm12_x86_64, // CVRegXMM12 - lldb_xmm13_x86_64, // CVRegXMM13 - lldb_xmm14_x86_64, // CVRegXMM14 - lldb_xmm15_x86_64, // CVRegXMM15 + LLDB_INVALID_REGNUM, // EMM0L + LLDB_INVALID_REGNUM, // EMM1L + LLDB_INVALID_REGNUM, // EMM2L + LLDB_INVALID_REGNUM, // EMM3L + LLDB_INVALID_REGNUM, // EMM4L + LLDB_INVALID_REGNUM, // EMM5L + LLDB_INVALID_REGNUM, // EMM6L + LLDB_INVALID_REGNUM, // EMM7L + LLDB_INVALID_REGNUM, // EMM0H + LLDB_INVALID_REGNUM, // EMM1H + LLDB_INVALID_REGNUM, // EMM2H + LLDB_INVALID_REGNUM, // EMM3H + LLDB_INVALID_REGNUM, // EMM4H + LLDB_INVALID_REGNUM, // EMM5H + LLDB_INVALID_REGNUM, // EMM6H + LLDB_INVALID_REGNUM, // EMM7H + LLDB_INVALID_REGNUM, // MM00 + LLDB_INVALID_REGNUM, // MM01 + LLDB_INVALID_REGNUM, // MM10 + LLDB_INVALID_REGNUM, // MM11 + LLDB_INVALID_REGNUM, // MM20 + LLDB_INVALID_REGNUM, // MM21 + LLDB_INVALID_REGNUM, // MM30 + LLDB_INVALID_REGNUM, // MM31 + LLDB_INVALID_REGNUM, // MM40 + LLDB_INVALID_REGNUM, // MM41 + LLDB_INVALID_REGNUM, // MM50 + LLDB_INVALID_REGNUM, // MM51 + LLDB_INVALID_REGNUM, // MM60 + LLDB_INVALID_REGNUM, // MM61 + LLDB_INVALID_REGNUM, // MM70 + LLDB_INVALID_REGNUM, // MM71 + lldb_xmm8_x86_64, // XMM8 + lldb_xmm9_x86_64, // XMM9 + lldb_xmm10_x86_64, // XMM10 + lldb_xmm11_x86_64, // XMM11 + lldb_xmm12_x86_64, // XMM12 + lldb_xmm13_x86_64, // XMM13 + lldb_xmm14_x86_64, // XMM14 + lldb_xmm15_x86_64, // XMM15 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, @@ -363,73 +363,73 @@ const uint32_t g_code_view_to_lldb_registers_x86_64[] = { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - lldb_sil_x86_64, // CVRegSIL - lldb_dil_x86_64, // CVRegDIL - lldb_bpl_x86_64, // CVRegBPL - lldb_spl_x86_64, // CVRegSPL - lldb_rax_x86_64, // CVRegRAX - lldb_rbx_x86_64, // CVRegRBX - lldb_rcx_x86_64, // CVRegRCX - lldb_rdx_x86_64, // CVRegRDX - lldb_rsi_x86_64, // CVRegRSI - lldb_rdi_x86_64, // CVRegRDI - lldb_rbp_x86_64, // CVRegRBP - lldb_rsp_x86_64, // CVRegRSP - lldb_r8_x86_64, // CVRegR8 - lldb_r9_x86_64, // CVRegR9 - lldb_r10_x86_64, // CVRegR10 - lldb_r11_x86_64, // CVRegR11 - lldb_r12_x86_64, // CVRegR12 - lldb_r13_x86_64, // CVRegR13 - lldb_r14_x86_64, // CVRegR14 - lldb_r15_x86_64, // CVRegR15 - lldb_r8l_x86_64, // CVRegR8B - lldb_r9l_x86_64, // CVRegR9B - lldb_r10l_x86_64, // CVRegR10B - lldb_r11l_x86_64, // CVRegR11B - lldb_r12l_x86_64, // CVRegR12B - lldb_r13l_x86_64, // CVRegR13B - lldb_r14l_x86_64, // CVRegR14B - lldb_r15l_x86_64, // CVRegR15B - lldb_r8w_x86_64, // CVRegR8W - lldb_r9w_x86_64, // CVRegR9W - lldb_r10w_x86_64, // CVRegR10W - lldb_r11w_x86_64, // CVRegR11W - lldb_r12w_x86_64, // CVRegR12W - lldb_r13w_x86_64, // CVRegR13W - lldb_r14w_x86_64, // CVRegR14W - lldb_r15w_x86_64, // CVRegR15W - lldb_r8d_x86_64, // CVRegR8D - lldb_r9d_x86_64, // CVRegR9D - lldb_r10d_x86_64, // CVRegR10D - lldb_r11d_x86_64, // CVRegR11D - lldb_r12d_x86_64, // CVRegR12D - lldb_r13d_x86_64, // CVRegR13D - lldb_r14d_x86_64, // CVRegR14D - lldb_r15d_x86_64, // CVRegR15D - lldb_ymm0_x86_64, // CVRegAMD64_YMM0 - lldb_ymm1_x86_64, // CVRegAMD64_YMM1 - lldb_ymm2_x86_64, // CVRegAMD64_YMM2 - lldb_ymm3_x86_64, // CVRegAMD64_YMM3 - lldb_ymm4_x86_64, // CVRegAMD64_YMM4 - lldb_ymm5_x86_64, // CVRegAMD64_YMM5 - lldb_ymm6_x86_64, // CVRegAMD64_YMM6 - lldb_ymm7_x86_64, // CVRegAMD64_YMM7 - lldb_ymm8_x86_64, // CVRegAMD64_YMM8 - lldb_ymm9_x86_64, // CVRegAMD64_YMM9 - lldb_ymm10_x86_64, // CVRegAMD64_YMM10 - lldb_ymm11_x86_64, // CVRegAMD64_YMM11 - lldb_ymm12_x86_64, // CVRegAMD64_YMM12 - lldb_ymm13_x86_64, // CVRegAMD64_YMM13 - lldb_ymm14_x86_64, // CVRegAMD64_YMM14 - lldb_ymm15_x86_64, // CVRegAMD64_YMM15 + lldb_sil_x86_64, // SIL + lldb_dil_x86_64, // DIL + lldb_bpl_x86_64, // BPL + lldb_spl_x86_64, // SPL + lldb_rax_x86_64, // RAX + lldb_rbx_x86_64, // RBX + lldb_rcx_x86_64, // RCX + lldb_rdx_x86_64, // RDX + lldb_rsi_x86_64, // RSI + lldb_rdi_x86_64, // RDI + lldb_rbp_x86_64, // RBP + lldb_rsp_x86_64, // RSP + lldb_r8_x86_64, // R8 + lldb_r9_x86_64, // R9 + lldb_r10_x86_64, // R10 + lldb_r11_x86_64, // R11 + lldb_r12_x86_64, // R12 + lldb_r13_x86_64, // R13 + lldb_r14_x86_64, // R14 + lldb_r15_x86_64, // R15 + lldb_r8l_x86_64, // R8B + lldb_r9l_x86_64, // R9B + lldb_r10l_x86_64, // R10B + lldb_r11l_x86_64, // R11B + lldb_r12l_x86_64, // R12B + lldb_r13l_x86_64, // R13B + lldb_r14l_x86_64, // R14B + lldb_r15l_x86_64, // R15B + lldb_r8w_x86_64, // R8W + lldb_r9w_x86_64, // R9W + lldb_r10w_x86_64, // R10W + lldb_r11w_x86_64, // R11W + lldb_r12w_x86_64, // R12W + lldb_r13w_x86_64, // R13W + lldb_r14w_x86_64, // R14W + lldb_r15w_x86_64, // R15W + lldb_r8d_x86_64, // R8D + lldb_r9d_x86_64, // R9D + lldb_r10d_x86_64, // R10D + lldb_r11d_x86_64, // R11D + lldb_r12d_x86_64, // R12D + lldb_r13d_x86_64, // R13D + lldb_r14d_x86_64, // R14D + lldb_r15d_x86_64, // R15D + lldb_ymm0_x86_64, // AMD64_YMM0 + lldb_ymm1_x86_64, // AMD64_YMM1 + lldb_ymm2_x86_64, // AMD64_YMM2 + lldb_ymm3_x86_64, // AMD64_YMM3 + lldb_ymm4_x86_64, // AMD64_YMM4 + lldb_ymm5_x86_64, // AMD64_YMM5 + lldb_ymm6_x86_64, // AMD64_YMM6 + lldb_ymm7_x86_64, // AMD64_YMM7 + lldb_ymm8_x86_64, // AMD64_YMM8 + lldb_ymm9_x86_64, // AMD64_YMM9 + lldb_ymm10_x86_64, // AMD64_YMM10 + lldb_ymm11_x86_64, // AMD64_YMM11 + lldb_ymm12_x86_64, // AMD64_YMM12 + lldb_ymm13_x86_64, // AMD64_YMM13 + lldb_ymm14_x86_64, // AMD64_YMM14 + lldb_ymm15_x86_64, // AMD64_YMM15 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, - lldb_bnd0_x86_64, // CVRegBND0 - lldb_bnd1_x86_64, // CVRegBND1 - lldb_bnd2_x86_64 // CVRegBND2 + lldb_bnd0_x86_64, // BND0 + lldb_bnd1_x86_64, // BND1 + lldb_bnd2_x86_64 // BND2 }; uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, @@ -443,13 +443,13 @@ uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, register_id)]; switch (register_id) { - case llvm::codeview::RegisterId::CVRegMXCSR: + case llvm::codeview::RegisterId::MXCSR: return lldb_mxcsr_i386; - case llvm::codeview::RegisterId::CVRegBND0: + case llvm::codeview::RegisterId::BND0: return lldb_bnd0_i386; - case llvm::codeview::RegisterId::CVRegBND1: + case llvm::codeview::RegisterId::BND1: return lldb_bnd1_i386; - case llvm::codeview::RegisterId::CVRegBND2: + case llvm::codeview::RegisterId::BND2: return lldb_bnd2_i386; default: return LLDB_INVALID_REGNUM; @@ -468,7 +468,7 @@ uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type, } uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) { - if (register_id == llvm::codeview::RegisterId::CVRegVFRAME) + if (register_id == llvm::codeview::RegisterId::VFRAME) return LLDB_REGNUM_GENERIC_FP; return LLDB_INVALID_REGNUM; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index 05f3017819fa..ad25842f4d05 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -9,6 +9,9 @@ #include "SymbolFilePDB.h" +#include "PDBASTParser.h" +#include "PDBLocationToDWARFExpression.h" + #include "clang/Lex/Lexer.h" #include "lldb/Core/Module.h" @@ -46,8 +49,8 @@ #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" -#include "Plugins/SymbolFile/PDB/PDBASTParser.h" -#include "Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.h" +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" +#include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" #include @@ -74,14 +77,32 @@ bool ShouldAddLine(uint32_t requested_line, uint32_t actual_line, } } // namespace +static bool ShouldUseNativeReader() { +#if defined(_WIN32) + llvm::StringRef use_native = ::getenv("LLDB_USE_NATIVE_PDB_READER"); + return use_native.equals_lower("on") || use_native.equals_lower("yes") || + use_native.equals_lower("1") || use_native.equals_lower("true"); +#else + return true; +#endif +} + void SymbolFilePDB::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - GetPluginDescriptionStatic(), CreateInstance, - DebuggerInitialize); + if (ShouldUseNativeReader()) { + npdb::SymbolFileNativePDB::Initialize(); + } else { + PluginManager::RegisterPlugin(GetPluginNameStatic(), + GetPluginDescriptionStatic(), CreateInstance, + DebuggerInitialize); + } } void SymbolFilePDB::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); + if (ShouldUseNativeReader()) { + npdb::SymbolFileNativePDB::Terminate(); + } else { + PluginManager::UnregisterPlugin(CreateInstance); + } } void SymbolFilePDB::DebuggerInitialize(lldb_private::Debugger &debugger) {} @@ -246,14 +267,8 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitAtIndex(uint32_t index) { return ParseCompileUnitForUID(compiland_up->getSymIndexId(), index); } -lldb::LanguageType -SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) { - // What fields should I expect to be filled out on the SymbolContext? Is it - // safe to assume that `sc.comp_unit` is valid? - if (!sc.comp_unit) - return lldb::eLanguageTypeUnknown; - - auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); +lldb::LanguageType SymbolFilePDB::ParseLanguage(CompileUnit &comp_unit) { + auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID()); if (!compiland_up) return lldb::eLanguageTypeUnknown; auto details = compiland_up->findOneChild(); @@ -262,9 +277,11 @@ SymbolFilePDB::ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) { return TranslateLanguage(details->getLanguage()); } -lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc( - const PDBSymbolFunc &pdb_func, const lldb_private::SymbolContext &sc) { - lldbassert(sc.comp_unit && sc.module_sp.get()); +lldb_private::Function * +SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func, + CompileUnit &comp_unit) { + if (FunctionSP result = comp_unit.FindFunctionByUID(pdb_func.getSymIndexId())) + return result.get(); auto file_vm_addr = pdb_func.getVirtualAddress(); if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) @@ -272,7 +289,8 @@ lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc( auto func_length = pdb_func.getLength(); AddressRange func_range = - AddressRange(file_vm_addr, func_length, sc.module_sp->GetSectionList()); + AddressRange(file_vm_addr, func_length, + GetObjectFile()->GetModule()->GetSectionList()); if (!func_range.GetBaseAddress().IsValid()) return nullptr; @@ -285,59 +303,61 @@ lldb_private::Function *SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc( Mangled mangled = GetMangledForPDBFunc(pdb_func); FunctionSP func_sp = - std::make_shared(sc.comp_unit, pdb_func.getSymIndexId(), + std::make_shared(&comp_unit, pdb_func.getSymIndexId(), func_type_uid, mangled, func_type, func_range); - sc.comp_unit->AddFunction(func_sp); + comp_unit.AddFunction(func_sp); + + TypeSystem *type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); + if (!type_system) + return nullptr; + ClangASTContext *clang_type_system = + llvm::dyn_cast_or_null(type_system); + if (!clang_type_system) + return nullptr; + clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func); + return func_sp.get(); } -size_t SymbolFilePDB::ParseCompileUnitFunctions( - const lldb_private::SymbolContext &sc) { - lldbassert(sc.comp_unit); +size_t SymbolFilePDB::ParseFunctions(CompileUnit &comp_unit) { size_t func_added = 0; - auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); + auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID()); if (!compiland_up) return 0; auto results_up = compiland_up->findAllChildren(); if (!results_up) return 0; while (auto pdb_func_up = results_up->getNext()) { - auto func_sp = - sc.comp_unit->FindFunctionByUID(pdb_func_up->getSymIndexId()); + auto func_sp = comp_unit.FindFunctionByUID(pdb_func_up->getSymIndexId()); if (!func_sp) { - if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, sc)) + if (ParseCompileUnitFunctionForPDBFunc(*pdb_func_up, comp_unit)) ++func_added; } } return func_added; } -bool SymbolFilePDB::ParseCompileUnitLineTable( - const lldb_private::SymbolContext &sc) { - lldbassert(sc.comp_unit); - if (sc.comp_unit->GetLineTable()) +bool SymbolFilePDB::ParseLineTable(CompileUnit &comp_unit) { + if (comp_unit.GetLineTable()) return true; - return ParseCompileUnitLineTable(sc, 0); + return ParseCompileUnitLineTable(comp_unit, 0); } -bool SymbolFilePDB::ParseCompileUnitDebugMacros( - const lldb_private::SymbolContext &sc) { +bool SymbolFilePDB::ParseDebugMacros(CompileUnit &comp_unit) { // PDB doesn't contain information about macros return false; } -bool SymbolFilePDB::ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) { - lldbassert(sc.comp_unit); +bool SymbolFilePDB::ParseSupportFiles( + CompileUnit &comp_unit, lldb_private::FileSpecList &support_files) { // In theory this is unnecessary work for us, because all of this information // is easily (and quickly) accessible from DebugInfoPDB, so caching it a // second time seems like a waste. Unfortunately, there's no good way around // this short of a moderate refactor since SymbolVendor depends on being able // to cache this list. - auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); + auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID()); if (!compiland_up) return false; auto files = m_session_up->getSourceFilesForCompiland(*compiland_up); @@ -345,13 +365,13 @@ bool SymbolFilePDB::ParseCompileUnitSupportFiles( return false; while (auto file = files->getNext()) { - FileSpec spec(file->getFileName(), false, FileSpec::Style::windows); + FileSpec spec(file->getFileName(), FileSpec::Style::windows); support_files.AppendIfUnique(spec); } // LLDB uses the DWARF-like file numeration (one based), // the zeroth file is the compile unit itself - support_files.Insert(0, *sc.comp_unit); + support_files.Insert(0, comp_unit); return true; } @@ -364,9 +384,8 @@ bool SymbolFilePDB::ParseImportedModules( } static size_t ParseFunctionBlocksForPDBSymbol( - const lldb_private::SymbolContext &sc, uint64_t func_file_vm_addr, - const llvm::pdb::PDBSymbol *pdb_symbol, lldb_private::Block *parent_block, - bool is_top_parent) { + uint64_t func_file_vm_addr, const llvm::pdb::PDBSymbol *pdb_symbol, + lldb_private::Block *parent_block, bool is_top_parent) { assert(pdb_symbol && parent_block); size_t num_added = 0; @@ -405,7 +424,7 @@ static size_t ParseFunctionBlocksForPDBSymbol( break; while (auto symbol_up = results_up->getNext()) { num_added += ParseFunctionBlocksForPDBSymbol( - sc, func_file_vm_addr, symbol_up.get(), block, false); + func_file_vm_addr, symbol_up.get(), block, false); } } break; default: @@ -414,28 +433,22 @@ static size_t ParseFunctionBlocksForPDBSymbol( return num_added; } -size_t -SymbolFilePDB::ParseFunctionBlocks(const lldb_private::SymbolContext &sc) { - lldbassert(sc.comp_unit && sc.function); +size_t SymbolFilePDB::ParseBlocksRecursive(Function &func) { size_t num_added = 0; - auto uid = sc.function->GetID(); + auto uid = func.GetID(); auto pdb_func_up = m_session_up->getConcreteSymbolById(uid); if (!pdb_func_up) return 0; - Block &parent_block = sc.function->GetBlock(false); - num_added = - ParseFunctionBlocksForPDBSymbol(sc, pdb_func_up->getVirtualAddress(), - pdb_func_up.get(), &parent_block, true); + Block &parent_block = func.GetBlock(false); + num_added = ParseFunctionBlocksForPDBSymbol( + pdb_func_up->getVirtualAddress(), pdb_func_up.get(), &parent_block, true); return num_added; } -size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) { - lldbassert(sc.module_sp.get()); - if (!sc.comp_unit) - return 0; +size_t SymbolFilePDB::ParseTypes(CompileUnit &comp_unit) { size_t num_added = 0; - auto compiland = GetPDBCompilandByUID(sc.comp_unit->GetID()); + auto compiland = GetPDBCompilandByUID(comp_unit.GetID()); if (!compiland) return 0; @@ -459,31 +472,26 @@ size_t SymbolFilePDB::ParseTypes(const lldb_private::SymbolContext &sc) { // This should cause the type to get cached and stored in the `m_types` // lookup. - if (!ResolveTypeUID(symbol->getSymIndexId())) - continue; - - ++num_added; + if (auto type = ResolveTypeUID(symbol->getSymIndexId())) { + // Resolve the type completely to avoid a completion + // (and so a list change, which causes an iterators invalidation) + // during a TypeList dumping + type->GetFullCompilerType(); + ++num_added; + } } } }; - if (sc.function) { - auto pdb_func = m_session_up->getConcreteSymbolById( - sc.function->GetID()); - if (!pdb_func) - return 0; - ParseTypesByTagFn(*pdb_func); - } else { - ParseTypesByTagFn(*compiland); + ParseTypesByTagFn(*compiland); - // Also parse global types particularly coming from this compiland. - // Unfortunately, PDB has no compiland information for each global type. We - // have to parse them all. But ensure we only do this once. - static bool parse_all_global_types = false; - if (!parse_all_global_types) { - ParseTypesByTagFn(*m_global_scope_up); - parse_all_global_types = true; - } + // Also parse global types particularly coming from this compiland. + // Unfortunately, PDB has no compiland information for each global type. We + // have to parse them all. But ensure we only do this once. + static bool parse_all_global_types = false; + if (!parse_all_global_types) { + ParseTypesByTagFn(*m_global_scope_up); + parse_all_global_types = true; } return num_added; } @@ -513,7 +521,7 @@ SymbolFilePDB::ParseVariablesForContext(const lldb_private::SymbolContext &sc) { auto results = m_global_scope_up->findAllChildren(); if (results && results->getChildCount()) { while (auto result = results->getNext()) { - auto cu_id = result->getCompilandId(); + auto cu_id = GetCompilandId(*result); // FIXME: We are not able to determine variable's compile unit. if (cu_id == 0) continue; @@ -548,8 +556,7 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { llvm::dyn_cast_or_null(type_system); if (!clang_type_system) return nullptr; - PDBASTParser *pdb = - llvm::dyn_cast(clang_type_system->GetPDBParser()); + PDBASTParser *pdb = clang_type_system->GetPDBParser(); if (!pdb) return nullptr; @@ -567,34 +574,109 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { return result.get(); } +llvm::Optional SymbolFilePDB::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + return llvm::None; +} + bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { - // TODO: Implement this - return false; + std::lock_guard guard( + GetObjectFile()->GetModule()->GetMutex()); + + ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null( + GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); + if (!clang_ast_ctx) + return false; + + PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); + if (!pdb) + return false; + + return pdb->CompleteTypeFromPDB(compiler_type); } lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { - return lldb_private::CompilerDecl(); + ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null( + GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); + if (!clang_ast_ctx) + return CompilerDecl(); + + PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); + if (!pdb) + return CompilerDecl(); + + auto symbol = m_session_up->getSymbolById(uid); + if (!symbol) + return CompilerDecl(); + + auto decl = pdb->GetDeclForSymbol(*symbol); + if (!decl) + return CompilerDecl(); + + return CompilerDecl(clang_ast_ctx, decl); } lldb_private::CompilerDeclContext SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { - // PDB always uses the translation unit decl context for everything. We can - // improve this later but it's not easy because PDB doesn't provide a high - // enough level of type fidelity in this area. - return *m_tu_decl_ctx_up; + ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null( + GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); + if (!clang_ast_ctx) + return CompilerDeclContext(); + + PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); + if (!pdb) + return CompilerDeclContext(); + + auto symbol = m_session_up->getSymbolById(uid); + if (!symbol) + return CompilerDeclContext(); + + auto decl_context = pdb->GetDeclContextForSymbol(*symbol); + if (!decl_context) + return GetDeclContextContainingUID(uid); + + return CompilerDeclContext(clang_ast_ctx, decl_context); } lldb_private::CompilerDeclContext SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { - return *m_tu_decl_ctx_up; + ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null( + GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); + if (!clang_ast_ctx) + return CompilerDeclContext(); + + PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); + if (!pdb) + return CompilerDeclContext(); + + auto symbol = m_session_up->getSymbolById(uid); + if (!symbol) + return CompilerDeclContext(); + + auto decl_context = pdb->GetDeclContextContainingSymbol(*symbol); + assert(decl_context); + + return CompilerDeclContext(clang_ast_ctx, decl_context); } void SymbolFilePDB::ParseDeclsForContext( - lldb_private::CompilerDeclContext decl_ctx) {} + lldb_private::CompilerDeclContext decl_ctx) { + ClangASTContext *clang_ast_ctx = llvm::dyn_cast_or_null( + GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus)); + if (!clang_ast_ctx) + return; + + PDBASTParser *pdb = clang_ast_ctx->GetPDBParser(); + if (!pdb) + return; + + pdb->ParseDeclsForDeclContext( + static_cast(decl_ctx.GetOpaqueDeclContext())); +} uint32_t SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, - uint32_t resolve_scope, + SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) { uint32_t resolved_flags = 0; if (resolve_scope & eSymbolContextCompUnit || @@ -614,7 +696,8 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, lldbassert(sc.module_sp == cu_sp->GetModule()); } - if (resolve_scope & eSymbolContextFunction) { + if (resolve_scope & eSymbolContextFunction || + resolve_scope & eSymbolContextBlock) { addr_t file_vm_addr = so_addr.GetFileAddress(); auto symbol_up = m_session_up->findSymbolByAddress(file_vm_addr, PDB_SymType::Function); @@ -624,12 +707,16 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, auto func_uid = pdb_func->getSymIndexId(); sc.function = sc.comp_unit->FindFunctionByUID(func_uid).get(); if (sc.function == nullptr) - sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc); + sc.function = + ParseCompileUnitFunctionForPDBFunc(*pdb_func, *sc.comp_unit); if (sc.function) { resolved_flags |= eSymbolContextFunction; if (resolve_scope & eSymbolContextBlock) { - Block &block = sc.function->GetBlock(true); - sc.block = block.FindBlockByID(sc.function->GetID()); + auto block_symbol = m_session_up->findSymbolByAddress( + file_vm_addr, PDB_SymType::Block); + auto block_id = block_symbol ? block_symbol->getSymIndexId() + : sc.function->GetID(); + sc.block = sc.function->GetBlock(true).FindBlockByID(block_id); if (sc.block) resolved_flags |= eSymbolContextBlock; } @@ -650,7 +737,7 @@ SymbolFilePDB::ResolveSymbolContext(const lldb_private::Address &so_addr, uint32_t SymbolFilePDB::ResolveSymbolContext( const lldb_private::FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, lldb_private::SymbolContextList &sc_list) { + SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) { const size_t old_size = sc_list.GetSize(); if (resolve_scope & lldb::eSymbolContextCompUnit) { // Locate all compilation units with line numbers referencing the specified @@ -674,7 +761,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext( std::string source_file = compiland->getSourceFileFullPath(); if (source_file.empty()) continue; - FileSpec this_spec(source_file, false, FileSpec::Style::windows); + FileSpec this_spec(source_file, FileSpec::Style::windows); bool need_full_match = !file_spec.GetDirectory().IsEmpty(); if (FileSpec::Compare(file_spec, this_spec, need_full_match) != 0) continue; @@ -691,7 +778,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext( // table that match the requested line (or all lines if `line` == 0). if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock | eSymbolContextLineEntry)) { - bool has_line_table = ParseCompileUnitLineTable(sc, line); + bool has_line_table = ParseCompileUnitLineTable(*sc.comp_unit, line); if ((resolve_scope & eSymbolContextLineEntry) && !has_line_table) { // The query asks for line entries, but we can't get them for the @@ -734,7 +821,8 @@ uint32_t SymbolFilePDB::ResolveSymbolContext( if (sc.function == nullptr) { auto pdb_func = llvm::dyn_cast(symbol_up.get()); assert(pdb_func); - sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, sc); + sc.function = ParseCompileUnitFunctionForPDBFunc(*pdb_func, + *sc.comp_unit); } if (sc.function && (resolve_scope & eSymbolContextBlock)) { Block &block = sc.function->GetBlock(true); @@ -759,24 +847,16 @@ uint32_t SymbolFilePDB::ResolveSymbolContext( } std::string SymbolFilePDB::GetMangledForPDBData(const PDBSymbolData &pdb_data) { - std::string decorated_name; - auto vm_addr = pdb_data.getVirtualAddress(); - if (vm_addr != LLDB_INVALID_ADDRESS && vm_addr) { - auto result_up = - m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol); - if (result_up) { - while (auto symbol_up = result_up->getNext()) { - if (symbol_up->getRawSymbol().getVirtualAddress() == vm_addr) { - decorated_name = symbol_up->getRawSymbol().getName(); - break; - } - } - } - } - if (!decorated_name.empty()) - return decorated_name; + // Cache public names at first + if (m_public_names.empty()) + if (auto result_up = + m_global_scope_up->findAllChildren(PDB_SymType::PublicSymbol)) + while (auto symbol_up = result_up->getNext()) + if (auto addr = symbol_up->getRawSymbol().getVirtualAddress()) + m_public_names[addr] = symbol_up->getRawSymbol().getName(); - return std::string(); + // Look up the name in the cache + return m_public_names.lookup(pdb_data.getVirtualAddress()); } VariableSP SymbolFilePDB::ParseVariableForPDBData( @@ -843,7 +923,7 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData( uint32_t src_file_id = first_line->getSourceFileId(); auto src_file = m_session_up->getSourceFileById(src_file_id); if (src_file) { - FileSpec spec(src_file->getFileName(), /*resolve_path*/ false); + FileSpec spec(src_file->getFileName()); decl.SetFile(spec); decl.SetColumn(first_line->getColumnNumber()); decl.SetLine(first_line->getLineNumber()); @@ -857,7 +937,7 @@ VariableSP SymbolFilePDB::ParseVariableForPDBData( if (scope == eValueTypeVariableLocal) { if (sc.function) { context_scope = sc.function->GetBlock(true).FindBlockByID( - pdb_data.getClassParentId()); + pdb_data.getLexicalParentId()); if (context_scope == nullptr) context_scope = sc.function; } @@ -937,6 +1017,9 @@ SymbolFilePDB::ParseVariables(const lldb_private::SymbolContext &sc, if (variable_list) variable_list->AddVariableIfUnique(var_sp); ++num_added; + PDBASTParser *ast = GetPDBAstParser(); + if (ast) + ast->GetDeclForSymbol(*pdb_data); } } } @@ -959,9 +1042,7 @@ uint32_t SymbolFilePDB::FindGlobalVariables( if (name.IsEmpty()) return 0; - auto results = - m_global_scope_up->findChildren(PDB_SymType::Data, name.GetStringRef(), - PDB_NameSearchFlags::NS_CaseSensitive); + auto results = m_global_scope_up->findAllChildren(); if (!results) return 0; @@ -976,11 +1057,19 @@ uint32_t SymbolFilePDB::FindGlobalVariables( sc.module_sp = m_obj_file->GetModule(); lldbassert(sc.module_sp.get()); - sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get(); + if (!name.GetStringRef().equals( + MSVCUndecoratedNameParser::DropScope(pdb_data->getName()))) + continue; + + sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); // FIXME: We are not able to determine the compile unit. if (sc.comp_unit == nullptr) continue; + if (parent_decl_ctx && GetDeclContextContainingUID( + result->getSymIndexId()) != *parent_decl_ctx) + continue; + ParseVariables(sc, *pdb_data, &variables); matches = variables.GetSize() - old_size; } @@ -1013,7 +1102,7 @@ SymbolFilePDB::FindGlobalVariables(const lldb_private::RegularExpression ®ex, sc.module_sp = m_obj_file->GetModule(); lldbassert(sc.module_sp.get()); - sc.comp_unit = ParseCompileUnitForUID(pdb_data->getCompilandId()).get(); + sc.comp_unit = ParseCompileUnitForUID(GetCompilandId(*pdb_data)).get(); // FIXME: We are not able to determine the compile unit. if (sc.comp_unit == nullptr) continue; @@ -1033,7 +1122,7 @@ bool SymbolFilePDB::ResolveFunction(const llvm::pdb::PDBSymbolFunc &pdb_func, if (!sc.comp_unit) return false; sc.module_sp = sc.comp_unit->GetModule(); - sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, sc); + sc.function = ParseCompileUnitFunctionForPDBFunc(pdb_func, *sc.comp_unit); if (!sc.function) return false; @@ -1075,22 +1164,11 @@ void SymbolFilePDB::CacheFunctionNames() { // Class. We won't bother to check if the parent is UDT or Enum here. m_func_method_names.Append(ConstString(name), uid); - ConstString cstr_name(name); - // To search a method name, like NS::Class:MemberFunc, LLDB searches // its base name, i.e. MemberFunc by default. Since PDBSymbolFunc does // not have inforamtion of this, we extract base names and cache them // by our own effort. - llvm::StringRef basename; - CPlusPlusLanguage::MethodName cpp_method(cstr_name); - if (cpp_method.IsValid()) { - llvm::StringRef context; - basename = cpp_method.GetBasename(); - if (basename.empty()) - CPlusPlusLanguage::ExtractContextAndIdentifier(name.c_str(), - context, basename); - } - + llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); if (!basename.empty()) m_func_base_names.Append(ConstString(basename), uid); else { @@ -1103,11 +1181,12 @@ void SymbolFilePDB::CacheFunctionNames() { } else { // Handle not-method symbols. - // The function name might contain namespace, or its lexical scope. It - // is not safe to get its base name by applying same scheme as we deal - // with the method names. - // FIXME: Remove namespace if function is static in a scope. - m_func_base_names.Append(ConstString(name), uid); + // The function name might contain namespace, or its lexical scope. + llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(name); + if (!basename.empty()) + m_func_base_names.Append(ConstString(basename), uid); + else + m_func_base_names.Append(ConstString(name), uid); if (name == "main") { m_func_full_names.Append(ConstString(name), uid); @@ -1157,7 +1236,7 @@ void SymbolFilePDB::CacheFunctionNames() { uint32_t SymbolFilePDB::FindFunctions( const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, + FunctionNameType name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list) { if (!append) sc_list.Clear(); @@ -1177,20 +1256,28 @@ uint32_t SymbolFilePDB::FindFunctions( CacheFunctionNames(); std::set resolved_ids; - auto ResolveFn = [include_inlines, &name, &sc_list, &resolved_ids, - this](UniqueCStringMap &Names) { + auto ResolveFn = [this, &name, parent_decl_ctx, include_inlines, &sc_list, + &resolved_ids](UniqueCStringMap &Names) { std::vector ids; - if (Names.GetValues(name, ids)) { - for (auto id : ids) { - if (resolved_ids.find(id) == resolved_ids.end()) { - if (ResolveFunction(id, include_inlines, sc_list)) - resolved_ids.insert(id); - } - } + if (!Names.GetValues(name, ids)) + return; + + for (uint32_t id : ids) { + if (resolved_ids.find(id) != resolved_ids.end()) + continue; + + if (parent_decl_ctx && + GetDeclContextContainingUID(id) != *parent_decl_ctx) + continue; + + if (ResolveFunction(id, include_inlines, sc_list)) + resolved_ids.insert(id); } }; if (name_type_mask & eFunctionNameTypeFull) { ResolveFn(m_func_full_names); + ResolveFn(m_func_base_names); + ResolveFn(m_func_method_names); } if (name_type_mask & eFunctionNameTypeBase) { ResolveFn(m_func_base_names); @@ -1236,8 +1323,59 @@ void SymbolFilePDB::GetMangledNamesForFunction( const std::string &scope_qualified_name, std::vector &mangled_names) {} +void SymbolFilePDB::AddSymbols(lldb_private::Symtab &symtab) { + std::set sym_addresses; + for (size_t i = 0; i < symtab.GetNumSymbols(); i++) + sym_addresses.insert(symtab.SymbolAtIndex(i)->GetFileAddress()); + + auto results = m_global_scope_up->findAllChildren(); + if (!results) + return; + + auto section_list = m_obj_file->GetSectionList(); + if (!section_list) + return; + + while (auto pub_symbol = results->getNext()) { + auto section_idx = pub_symbol->getAddressSection() - 1; + if (section_idx >= section_list->GetSize()) + continue; + + auto section = section_list->GetSectionAtIndex(section_idx); + if (!section) + continue; + + auto offset = pub_symbol->getAddressOffset(); + + auto file_addr = section->GetFileAddress() + offset; + if (sym_addresses.find(file_addr) != sym_addresses.end()) + continue; + sym_addresses.insert(file_addr); + + auto size = pub_symbol->getLength(); + symtab.AddSymbol( + Symbol(pub_symbol->getSymIndexId(), // symID + pub_symbol->getName().c_str(), // name + true, // name_is_mangled + pub_symbol->isCode() ? eSymbolTypeCode : eSymbolTypeData, // type + true, // external + false, // is_debug + false, // is_trampoline + false, // is_artificial + section, // section_sp + offset, // value + size, // size + size != 0, // size_is_valid + false, // contains_linker_annotations + 0 // flags + )); + } + + symtab.CalculateSymbolSizes(); + symtab.Finalize(); +} + uint32_t SymbolFilePDB::FindTypes( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, @@ -1253,14 +1391,20 @@ uint32_t SymbolFilePDB::FindTypes( searched_symbol_files.clear(); searched_symbol_files.insert(this); - std::string name_str = name.AsCString(); - // There is an assumption 'name' is not a regex - FindTypesByName(name_str, max_matches, types); + FindTypesByName(name.GetStringRef(), parent_decl_ctx, max_matches, types); return types.GetSize(); } +void SymbolFilePDB::DumpClangAST(Stream &s) { + auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); + auto clang = llvm::dyn_cast_or_null(type_system); + if (!clang) + return; + clang->Dump(s); +} + void SymbolFilePDB::FindTypesByRegex( const lldb_private::RegularExpression ®ex, uint32_t max_matches, lldb_private::TypeMap &types) { @@ -1316,14 +1460,14 @@ void SymbolFilePDB::FindTypesByRegex( } } -void SymbolFilePDB::FindTypesByName(const std::string &name, - uint32_t max_matches, - lldb_private::TypeMap &types) { +void SymbolFilePDB::FindTypesByName( + llvm::StringRef name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, + uint32_t max_matches, lldb_private::TypeMap &types) { std::unique_ptr results; if (name.empty()) return; - results = m_global_scope_up->findChildren(PDB_SymType::None, name, - PDB_NameSearchFlags::NS_Default); + results = m_global_scope_up->findAllChildren(PDB_SymType::None); if (!results) return; @@ -1332,6 +1476,11 @@ void SymbolFilePDB::FindTypesByName(const std::string &name, while (auto result = results->getNext()) { if (max_matches > 0 && matches >= max_matches) break; + + if (MSVCUndecoratedNameParser::DropScope( + result->getRawSymbol().getName()) != name) + continue; + switch (result->getSymTag()) { case PDB_SymType::Enum: case PDB_SymType::UDT: @@ -1348,6 +1497,10 @@ void SymbolFilePDB::FindTypesByName(const std::string &name, if (!ResolveTypeUID(result->getSymIndexId())) continue; + if (parent_decl_ctx && GetDeclContextContainingUID( + result->getSymIndexId()) != *parent_decl_ctx) + continue; + auto iter = m_types.find(result->getSymIndexId()); if (iter == m_types.end()) continue; @@ -1417,7 +1570,7 @@ void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol, } size_t SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, + TypeClass type_mask, lldb_private::TypeList &type_list) { TypeCollection type_collection; uint32_t old_size = type_list.GetSize(); @@ -1454,11 +1607,40 @@ SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) { return type_system; } +PDBASTParser *SymbolFilePDB::GetPDBAstParser() { + auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); + auto clang_type_system = llvm::dyn_cast_or_null(type_system); + if (!clang_type_system) + return nullptr; + + return clang_type_system->GetPDBParser(); +} + + lldb_private::CompilerDeclContext SymbolFilePDB::FindNamespace( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx) { - return lldb_private::CompilerDeclContext(); + auto type_system = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); + auto clang_type_system = llvm::dyn_cast_or_null(type_system); + if (!clang_type_system) + return CompilerDeclContext(); + + PDBASTParser *pdb = clang_type_system->GetPDBParser(); + if (!pdb) + return CompilerDeclContext(); + + clang::DeclContext *decl_context = nullptr; + if (parent_decl_ctx) + decl_context = static_cast( + parent_decl_ctx->GetOpaqueDeclContext()); + + auto namespace_decl = + pdb->FindNamespaceDecl(decl_context, name.GetStringRef()); + if (!namespace_decl) + return CompilerDeclContext(); + + return CompilerDeclContext(type_system, + static_cast(namespace_decl)); } lldb_private::ConstString SymbolFilePDB::GetPluginName() { @@ -1516,11 +1698,9 @@ lldb::CompUnitSP SymbolFilePDB::ParseCompileUnitForUID(uint32_t id, return cu_sp; } -bool SymbolFilePDB::ParseCompileUnitLineTable( - const lldb_private::SymbolContext &sc, uint32_t match_line) { - lldbassert(sc.comp_unit); - - auto compiland_up = GetPDBCompilandByUID(sc.comp_unit->GetID()); +bool SymbolFilePDB::ParseCompileUnitLineTable(CompileUnit &comp_unit, + uint32_t match_line) { + auto compiland_up = GetPDBCompilandByUID(comp_unit.GetID()); if (!compiland_up) return false; @@ -1530,10 +1710,10 @@ bool SymbolFilePDB::ParseCompileUnitLineTable( // to do a mapping so that we can hand out indices. llvm::DenseMap index_map; BuildSupportFileIdToSupportFileIndexMap(*compiland_up, index_map); - auto line_table = llvm::make_unique(sc.comp_unit); + auto line_table = llvm::make_unique(&comp_unit); // Find contributions to `compiland` from all source and header files. - std::string path = sc.comp_unit->GetPath(); + std::string path = comp_unit.GetPath(); auto files = m_session_up->getSourceFilesForCompiland(*compiland_up); if (!files) return false; @@ -1617,7 +1797,7 @@ bool SymbolFilePDB::ParseCompileUnitLineTable( } if (line_table->GetSize()) { - sc.comp_unit->SetLineTable(line_table.release()); + comp_unit.SetLineTable(line_table.release()); return true; } return false; @@ -1747,3 +1927,68 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile( return false; } + +uint32_t SymbolFilePDB::GetCompilandId(const llvm::pdb::PDBSymbolData &data) { + static const auto pred_upper = [](uint32_t lhs, SecContribInfo rhs) { + return lhs < rhs.Offset; + }; + + // Cache section contributions + if (m_sec_contribs.empty()) { + if (auto SecContribs = m_session_up->getSectionContribs()) { + while (auto SectionContrib = SecContribs->getNext()) { + auto comp_id = SectionContrib->getCompilandId(); + if (!comp_id) + continue; + + auto sec = SectionContrib->getAddressSection(); + auto &sec_cs = m_sec_contribs[sec]; + + auto offset = SectionContrib->getAddressOffset(); + auto it = + std::upper_bound(sec_cs.begin(), sec_cs.end(), offset, pred_upper); + + auto size = SectionContrib->getLength(); + sec_cs.insert(it, {offset, size, comp_id}); + } + } + } + + // Check by line number + if (auto Lines = data.getLineNumbers()) { + if (auto FirstLine = Lines->getNext()) + return FirstLine->getCompilandId(); + } + + // Retrieve section + offset + uint32_t DataSection = data.getAddressSection(); + uint32_t DataOffset = data.getAddressOffset(); + if (DataSection == 0) { + if (auto RVA = data.getRelativeVirtualAddress()) + m_session_up->addressForRVA(RVA, DataSection, DataOffset); + } + + if (DataSection) { + // Search by section contributions + auto &sec_cs = m_sec_contribs[DataSection]; + auto it = + std::upper_bound(sec_cs.begin(), sec_cs.end(), DataOffset, pred_upper); + if (it != sec_cs.begin()) { + --it; + if (DataOffset < it->Offset + it->Size) + return it->CompilandId; + } + } else { + // Search in lexical tree + auto LexParentId = data.getLexicalParentId(); + while (auto LexParent = m_session_up->getSymbolById(LexParentId)) { + if (LexParent->getSymTag() == PDB_SymType::Exe) + break; + if (LexParent->getSymTag() == PDB_SymType::Compiland) + return LexParentId; + LexParentId = LexParent->getRawSymbol().getLexicalParentId(); + } + } + + return 0; +} diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 96b62d68a6c2..81288093b7d8 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -20,6 +20,8 @@ #include "llvm/DebugInfo/PDB/PDB.h" #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" +class PDBASTParser; + class SymbolFilePDB : public lldb_private::SymbolFile { public: //------------------------------------------------------------------ @@ -58,33 +60,32 @@ public: lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; + ParseLanguage(lldb_private::CompileUnit &comp_unit) override; - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; + bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; - bool - ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; + bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; - bool ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) override; + bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, + lldb_private::FileSpecList &support_files) override; + + size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; bool ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector &imported_modules) override; - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - - size_t ParseTypes(const lldb_private::SymbolContext &sc) override; + size_t ParseBlocksRecursive(lldb_private::Function &func) override; size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; @@ -100,12 +101,13 @@ public: ParseDeclsForContext(lldb_private::CompilerDeclContext decl_ctx) override; uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; uint32_t ResolveSymbolContext(const lldb_private::FileSpec &file_spec, uint32_t line, - bool check_inlines, uint32_t resolve_scope, + bool check_inlines, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContextList &sc_list) override; uint32_t @@ -121,8 +123,8 @@ public: uint32_t FindFunctions(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, bool include_inlines, bool append, - lldb_private::SymbolContextList &sc_list) override; + lldb::FunctionNameType name_type_mask, bool include_inlines, + bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t FindFunctions(const lldb_private::RegularExpression ®ex, bool include_inlines, bool append, @@ -132,9 +134,10 @@ public: const std::string &scope_qualified_name, std::vector &mangled_names) override; + void AddSymbols(lldb_private::Symtab &symtab) override; + uint32_t - FindTypes(const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, + FindTypes(const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, @@ -149,14 +152,13 @@ public: lldb_private::TypeList *GetTypeList() override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; lldb_private::TypeSystem * GetTypeSystemForLanguage(lldb::LanguageType language) override; lldb_private::CompilerDeclContext FindNamespace( - const lldb_private::SymbolContext &sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx) override; @@ -168,19 +170,29 @@ public: const llvm::pdb::IPDBSession &GetPDBSession() const; + void DumpClangAST(lldb_private::Stream &s) override; + private: + struct SecContribInfo { + uint32_t Offset; + uint32_t Size; + uint32_t CompilandId; + }; + using SecContribsMap = std::map>; + lldb::CompUnitSP ParseCompileUnitForUID(uint32_t id, uint32_t index = UINT32_MAX); - bool ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc, + bool ParseCompileUnitLineTable(lldb_private::CompileUnit &comp_unit, uint32_t match_line); void BuildSupportFileIdToSupportFileIndexMap( const llvm::pdb::PDBSymbolCompiland &pdb_compiland, llvm::DenseMap &index_map) const; - void FindTypesByName(const std::string &name, uint32_t max_matches, - lldb_private::TypeMap &types); + void FindTypesByName(llvm::StringRef name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, + uint32_t max_matches, lldb_private::TypeMap &types); std::string GetMangledForPDBData(const llvm::pdb::PDBSymbolData &pdb_data); @@ -203,11 +215,13 @@ private: lldb_private::Function * ParseCompileUnitFunctionForPDBFunc(const llvm::pdb::PDBSymbolFunc &pdb_func, - const lldb_private::SymbolContext &sc); + lldb_private::CompileUnit &comp_unit); void GetCompileUnitIndex(const llvm::pdb::PDBSymbolCompiland &pdb_compiland, uint32_t &index); + PDBASTParser *GetPDBAstParser(); + std::unique_ptr GetPDBCompilandByUID(uint32_t uid); @@ -226,9 +240,14 @@ private: bool DeclContextMatchesThisSymbolFile( const lldb_private::CompilerDeclContext *decl_ctx); + uint32_t GetCompilandId(const llvm::pdb::PDBSymbolData &data); + llvm::DenseMap m_comp_units; llvm::DenseMap m_types; llvm::DenseMap m_variables; + llvm::DenseMap m_public_names; + + SecContribsMap m_sec_contribs; std::vector m_builtin_types; std::unique_ptr m_session_up; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index 64e2daf60ee5..08778bd1ba70 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -46,7 +46,7 @@ SymbolFile *SymbolFileSymtab::CreateInstance(ObjectFile *obj_file) { } size_t SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope, - uint32_t type_mask, + TypeClass type_mask, lldb_private::TypeList &type_list) { return 0; } @@ -131,15 +131,13 @@ CompUnitSP SymbolFileSymtab::ParseCompileUnitAtIndex(uint32_t idx) { return cu_sp; } -lldb::LanguageType -SymbolFileSymtab::ParseCompileUnitLanguage(const SymbolContext &sc) { +lldb::LanguageType SymbolFileSymtab::ParseLanguage(CompileUnit &comp_unit) { return eLanguageTypeUnknown; } -size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) { +size_t SymbolFileSymtab::ParseFunctions(CompileUnit &comp_unit) { size_t num_added = 0; // We must at least have a valid compile unit - assert(sc.comp_unit != NULL); const Symtab *symtab = m_obj_file->GetSymtab(); const Symbol *curr_symbol = NULL; const Symbol *next_symbol = NULL; @@ -185,7 +183,7 @@ size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) { } FunctionSP func_sp( - new Function(sc.comp_unit, + new Function(&comp_unit, symbol_idx, // UserID is the DIE offset LLDB_INVALID_UID, // We don't have any type info // for this function @@ -194,7 +192,7 @@ size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) { func_range)); // first address range if (func_sp.get() != NULL) { - sc.comp_unit->AddFunction(func_sp); + comp_unit.AddFunction(func_sp); ++num_added; } } @@ -207,16 +205,16 @@ size_t SymbolFileSymtab::ParseCompileUnitFunctions(const SymbolContext &sc) { return num_added; } -bool SymbolFileSymtab::ParseCompileUnitLineTable(const SymbolContext &sc) { +size_t SymbolFileSymtab::ParseTypes(CompileUnit &comp_unit) { return 0; } + +bool SymbolFileSymtab::ParseLineTable(CompileUnit &comp_unit) { return false; } + +bool SymbolFileSymtab::ParseDebugMacros(CompileUnit &comp_unit) { return false; } -bool SymbolFileSymtab::ParseCompileUnitDebugMacros(const SymbolContext &sc) { - return false; -} - -bool SymbolFileSymtab::ParseCompileUnitSupportFiles( - const SymbolContext &sc, FileSpecList &support_files) { +bool SymbolFileSymtab::ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) { return false; } @@ -225,11 +223,7 @@ bool SymbolFileSymtab::ParseImportedModules( return false; } -size_t SymbolFileSymtab::ParseFunctionBlocks(const SymbolContext &sc) { - return 0; -} - -size_t SymbolFileSymtab::ParseTypes(const SymbolContext &sc) { return 0; } +size_t SymbolFileSymtab::ParseBlocksRecursive(Function &func) { return 0; } size_t SymbolFileSymtab::ParseVariablesForContext(const SymbolContext &sc) { return 0; @@ -239,12 +233,18 @@ Type *SymbolFileSymtab::ResolveTypeUID(lldb::user_id_t type_uid) { return NULL; } +llvm::Optional +SymbolFileSymtab::GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, const lldb_private::ExecutionContext *exe_ctx) { + return llvm::None; +} + bool SymbolFileSymtab::CompleteType(lldb_private::CompilerType &compiler_type) { return false; } uint32_t SymbolFileSymtab::ResolveSymbolContext(const Address &so_addr, - uint32_t resolve_scope, + SymbolContextItem resolve_scope, SymbolContext &sc) { if (m_obj_file->GetSymtab() == NULL) return 0; diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index d1887a707ea6..e4ec7a181333 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -10,13 +10,9 @@ #ifndef liblldb_SymbolFileSymtab_h_ #define liblldb_SymbolFileSymtab_h_ -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Symtab.h" @@ -53,42 +49,41 @@ public: lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override; lldb::LanguageType - ParseCompileUnitLanguage(const lldb_private::SymbolContext &sc) override; + ParseLanguage(lldb_private::CompileUnit &comp_unit) override; - size_t - ParseCompileUnitFunctions(const lldb_private::SymbolContext &sc) override; + size_t ParseFunctions(lldb_private::CompileUnit &comp_unit) override; - bool - ParseCompileUnitLineTable(const lldb_private::SymbolContext &sc) override; + bool ParseLineTable(lldb_private::CompileUnit &comp_unit) override; - bool - ParseCompileUnitDebugMacros(const lldb_private::SymbolContext &sc) override; + bool ParseDebugMacros(lldb_private::CompileUnit &comp_unit) override; - bool ParseCompileUnitSupportFiles( - const lldb_private::SymbolContext &sc, - lldb_private::FileSpecList &support_files) override; + bool ParseSupportFiles(lldb_private::CompileUnit &comp_unit, + lldb_private::FileSpecList &support_files) override; + + size_t ParseTypes(lldb_private::CompileUnit &comp_unit) override; bool ParseImportedModules( const lldb_private::SymbolContext &sc, std::vector &imported_modules) override; - size_t ParseFunctionBlocks(const lldb_private::SymbolContext &sc) override; - - size_t ParseTypes(const lldb_private::SymbolContext &sc) override; + size_t ParseBlocksRecursive(lldb_private::Function &func) override; size_t ParseVariablesForContext(const lldb_private::SymbolContext &sc) override; lldb_private::Type *ResolveTypeUID(lldb::user_id_t type_uid) override; + llvm::Optional GetDynamicArrayInfoForUID( + lldb::user_id_t type_uid, + const lldb_private::ExecutionContext *exe_ctx) override; bool CompleteType(lldb_private::CompilerType &compiler_type) override; uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, + lldb::TypeClass type_mask, lldb_private::TypeList &type_list) override; //------------------------------------------------------------------ diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp b/contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp index d24510966878..425b612d786f 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.cpp @@ -101,16 +101,17 @@ SymbolVendorELF::CreateInstance(const lldb::ModuleSP &module_sp, const FileSpec fspec = file_spec_list.GetFileSpecAtIndex(idx); module_spec.GetFileSpec() = obj_file->GetFileSpec(); - module_spec.GetFileSpec().ResolvePath(); + FileSystem::Instance().Resolve(module_spec.GetFileSpec()); module_spec.GetSymbolFileSpec() = fspec; module_spec.GetUUID() = uuid; FileSpec dsym_fspec = Symbols::LocateExecutableSymbolFile(module_spec); if (dsym_fspec) { DataBufferSP dsym_file_data_sp; lldb::offset_t dsym_file_data_offset = 0; - ObjectFileSP dsym_objfile_sp = ObjectFile::FindPlugin( - module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), - dsym_file_data_sp, dsym_file_data_offset); + ObjectFileSP dsym_objfile_sp = + ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, + FileSystem::Instance().GetByteSize(dsym_fspec), + dsym_file_data_sp, dsym_file_data_offset); if (dsym_objfile_sp) { // This objfile is for debugging purposes. Sadly, ObjectFileELF won't // be able to figure this out consistently as the symbol file may not diff --git a/contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h b/contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h index e7aeebc96b94..b0d956e31dc9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h +++ b/contrib/llvm/tools/lldb/source/Plugins/SymbolVendor/ELF/SymbolVendorELF.h @@ -10,10 +10,6 @@ #ifndef liblldb_SymbolVendorELF_h_ #define liblldb_SymbolVendorELF_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Symbol/SymbolVendor.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp index 54e182b30b6f..b70c2c44d3e6 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.cpp @@ -606,7 +606,7 @@ bool UnwindAssemblyInstEmulation::WriteRegister( assert( (generic_regnum == LLDB_REGNUM_GENERIC_PC || generic_regnum == LLDB_REGNUM_GENERIC_FLAGS) && - "eInfoTypeISA used for poping a register other the the PC/FLAGS"); + "eInfoTypeISA used for popping a register other the PC/FLAGS"); if (generic_regnum != LLDB_REGNUM_GENERIC_FLAGS) { m_curr_row->SetRegisterLocationToSame(reg_num, false /*must_replace*/); diff --git a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h index e587c93b427c..5539b5217e9e 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h +++ b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/InstEmulation/UnwindAssemblyInstEmulation.h @@ -10,14 +10,10 @@ #ifndef liblldb_UnwindAssemblyInstEmulation_h_ #define liblldb_UnwindAssemblyInstEmulation_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/EmulateInstruction.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/Target/UnwindAssembly.h" +#include "lldb/Utility/RegisterValue.h" #include "lldb/lldb-private.h" class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly { diff --git a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp index 327d0b0e4f71..04f9cbbf03ae 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.cpp @@ -92,7 +92,7 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite( // assembly parsing instead. if (first_row->GetCFAValue().GetValueType() != - UnwindPlan::Row::CFAValue::isRegisterPlusOffset || + UnwindPlan::Row::FAValue::isRegisterPlusOffset || RegisterNumber(thread, unwind_plan.GetRegisterKind(), first_row->GetCFAValue().GetRegisterNumber()) != sp_regnum || @@ -100,10 +100,10 @@ bool UnwindAssembly_x86::AugmentUnwindPlanFromCallSite( return false; } UnwindPlan::Row::RegisterLocation first_row_pc_loc; - if (first_row->GetRegisterInfo( + if (!first_row->GetRegisterInfo( pc_regnum.GetAsKind(unwind_plan.GetRegisterKind()), - first_row_pc_loc) == false || - first_row_pc_loc.IsAtCFAPlusOffset() == false || + first_row_pc_loc) || + !first_row_pc_loc.IsAtCFAPlusOffset() || first_row_pc_loc.GetOffset() != -wordsize) { return false; } diff --git a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h index 2beaa4a6510a..c4052a8489da 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h +++ b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/UnwindAssembly-x86.h @@ -10,12 +10,8 @@ #ifndef liblldb_UnwindAssembly_x86_h_ #define liblldb_UnwindAssembly_x86_h_ -// C Includes -// C++ Includes -// Other libraries and framework includes #include "x86AssemblyInspectionEngine.h" -// Project includes #include "lldb/Target/UnwindAssembly.h" #include "lldb/lldb-private.h" diff --git a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp index 10a56980594f..f8e70204e509 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp +++ b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp @@ -59,6 +59,7 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP ®_ctx) { m_machine_ip_regnum = k_machine_eip; m_machine_sp_regnum = k_machine_esp; m_machine_fp_regnum = k_machine_ebp; + m_machine_alt_fp_regnum = k_machine_ebx; m_wordsize = 4; struct lldb_reg_info reginfo; @@ -84,6 +85,7 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP ®_ctx) { m_machine_ip_regnum = k_machine_rip; m_machine_sp_regnum = k_machine_rsp; m_machine_fp_regnum = k_machine_rbp; + m_machine_alt_fp_regnum = k_machine_rbx; m_wordsize = 8; struct lldb_reg_info reginfo; @@ -135,6 +137,8 @@ void x86AssemblyInspectionEngine::Initialize(RegisterContextSP ®_ctx) { m_lldb_sp_regnum = lldb_regno; if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno)) m_lldb_fp_regnum = lldb_regno; + if (machine_regno_to_lldb_regno(m_machine_alt_fp_regnum, lldb_regno)) + m_lldb_alt_fp_regnum = lldb_regno; if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno)) m_lldb_ip_regnum = lldb_regno; @@ -160,6 +164,7 @@ void x86AssemblyInspectionEngine::Initialize( m_machine_ip_regnum = k_machine_eip; m_machine_sp_regnum = k_machine_esp; m_machine_fp_regnum = k_machine_ebp; + m_machine_alt_fp_regnum = k_machine_ebx; m_wordsize = 4; struct lldb_reg_info reginfo; @@ -185,6 +190,7 @@ void x86AssemblyInspectionEngine::Initialize( m_machine_ip_regnum = k_machine_rip; m_machine_sp_regnum = k_machine_rsp; m_machine_fp_regnum = k_machine_rbp; + m_machine_alt_fp_regnum = k_machine_rbx; m_wordsize = 8; struct lldb_reg_info reginfo; @@ -239,6 +245,8 @@ void x86AssemblyInspectionEngine::Initialize( m_lldb_sp_regnum = lldb_regno; if (machine_regno_to_lldb_regno(m_machine_fp_regnum, lldb_regno)) m_lldb_fp_regnum = lldb_regno; + if (machine_regno_to_lldb_regno(m_machine_alt_fp_regnum, lldb_regno)) + m_lldb_alt_fp_regnum = lldb_regno; if (machine_regno_to_lldb_regno(m_machine_ip_regnum, lldb_regno)) m_lldb_ip_regnum = lldb_regno; @@ -296,26 +304,20 @@ bool x86AssemblyInspectionEngine::nonvolatile_reg_p(int machine_regno) { // pushq %rbp [0x55] bool x86AssemblyInspectionEngine::push_rbp_pattern_p() { uint8_t *p = m_cur_insn; - if (*p == 0x55) - return true; - return false; + return *p == 0x55; } // pushq $0 ; the first instruction in start() [0x6a 0x00] bool x86AssemblyInspectionEngine::push_0_pattern_p() { uint8_t *p = m_cur_insn; - if (*p == 0x6a && *(p + 1) == 0x0) - return true; - return false; + return *p == 0x6a && *(p + 1) == 0x0; } // pushq $0 // pushl $0 bool x86AssemblyInspectionEngine::push_imm_pattern_p() { uint8_t *p = m_cur_insn; - if (*p == 0x68 || *p == 0x6a) - return true; - return false; + return *p == 0x68 || *p == 0x6a; } // pushl imm8(%esp) @@ -387,6 +389,45 @@ bool x86AssemblyInspectionEngine::mov_rsp_rbp_pattern_p() { return false; } +// movq %rsp, %rbx [0x48 0x8b 0xdc] or [0x48 0x89 0xe3] +// movl %esp, %ebx [0x8b 0xdc] or [0x89 0xe3] +bool x86AssemblyInspectionEngine::mov_rsp_rbx_pattern_p() { + uint8_t *p = m_cur_insn; + if (m_wordsize == 8 && *p == 0x48) + p++; + if (*(p) == 0x8b && *(p + 1) == 0xdc) + return true; + if (*(p) == 0x89 && *(p + 1) == 0xe3) + return true; + return false; +} + +// movq %rbp, %rsp [0x48 0x8b 0xe5] or [0x48 0x89 0xec] +// movl %ebp, %esp [0x8b 0xe5] or [0x89 0xec] +bool x86AssemblyInspectionEngine::mov_rbp_rsp_pattern_p() { + uint8_t *p = m_cur_insn; + if (m_wordsize == 8 && *p == 0x48) + p++; + if (*(p) == 0x8b && *(p + 1) == 0xe5) + return true; + if (*(p) == 0x89 && *(p + 1) == 0xec) + return true; + return false; +} + +// movq %rbx, %rsp [0x48 0x8b 0xe3] or [0x48 0x89 0xdc] +// movl %ebx, %esp [0x8b 0xe3] or [0x89 0xdc] +bool x86AssemblyInspectionEngine::mov_rbx_rsp_pattern_p() { + uint8_t *p = m_cur_insn; + if (m_wordsize == 8 && *p == 0x48) + p++; + if (*(p) == 0x8b && *(p + 1) == 0xe3) + return true; + if (*(p) == 0x89 && *(p + 1) == 0xdc) + return true; + return false; +} + // subq $0x20, %rsp bool x86AssemblyInspectionEngine::sub_rsp_pattern_p(int &amount) { uint8_t *p = m_cur_insn; @@ -476,6 +517,46 @@ bool x86AssemblyInspectionEngine::lea_rbp_rsp_pattern_p(int &amount) { return false; } +// lea -0x28(%ebx), %esp +// (32-bit and 64-bit variants, 8-bit and 32-bit displacement) +bool x86AssemblyInspectionEngine::lea_rbx_rsp_pattern_p(int &amount) { + uint8_t *p = m_cur_insn; + if (m_wordsize == 8 && *p == 0x48) + p++; + + // Check opcode + if (*p != 0x8d) + return false; + ++p; + + // 8 bit displacement + if (*p == 0x63) { + amount = (int8_t)p[1]; + return true; + } + + // 32 bit displacement + if (*p == 0xa3) { + amount = (int32_t)extract_4(p + 1); + return true; + } + + return false; +} + +// and -0xfffffff0, %esp +// (32-bit and 64-bit variants, 8-bit and 32-bit displacement) +bool x86AssemblyInspectionEngine::and_rsp_pattern_p() { + uint8_t *p = m_cur_insn; + if (m_wordsize == 8 && *p == 0x48) + p++; + + if (*p != 0x81 && *p != 0x83) + return false; + + return *++p == 0xe4; +} + // popq %rbx // popl %ebx bool x86AssemblyInspectionEngine::pop_reg_p(int ®no) { @@ -588,9 +669,7 @@ bool x86AssemblyInspectionEngine::mov_reg_to_local_stack_frame_p( // ret [0xc9] or [0xc2 imm8] or [0xca imm8] bool x86AssemblyInspectionEngine::ret_pattern_p() { uint8_t *p = m_cur_insn; - if (*p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3) - return true; - return false; + return *p == 0xc9 || *p == 0xc2 || *p == 0xca || *p == 0xc3; } uint32_t x86AssemblyInspectionEngine::extract_4(uint8_t *b) { @@ -636,11 +715,12 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( if (data == nullptr || size == 0) return false; - if (m_register_map_initialized == false) + if (!m_register_map_initialized) return false; addr_t current_func_text_offset = 0; - int current_sp_bytes_offset_from_cfa = 0; + int current_sp_bytes_offset_from_fa = 0; + bool is_aligned = false; UnwindPlan::Row::RegisterLocation initial_regloc; UnwindPlan::RowSP row(new UnwindPlan::Row); @@ -657,8 +737,8 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( row->SetRegisterInfo(m_lldb_sp_regnum, initial_regloc); // saved instruction pointer can be found at CFA - wordsize. - current_sp_bytes_offset_from_cfa = m_wordsize; - initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa); + current_sp_bytes_offset_from_fa = m_wordsize; + initial_regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_fa); row->SetRegisterInfo(m_lldb_ip_regnum, initial_regloc); unwind_plan.AppendRow(row); @@ -682,6 +762,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( UnwindPlan::RowSP prologue_completed_row; // copy of prologue row of CFI int prologue_completed_sp_bytes_offset_from_cfa; // The sp value before the // epilogue started executed + bool prologue_completed_is_aligned; std::vector prologue_completed_saved_registers; while (current_func_text_offset < size) { @@ -701,20 +782,57 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( break; } - if (push_rbp_pattern_p()) { - current_sp_bytes_offset_from_cfa += m_wordsize; - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); - UnwindPlan::Row::RegisterLocation regloc; - regloc.SetAtCFAPlusOffset(-row->GetCFAValue().GetOffset()); - row->SetRegisterInfo(m_lldb_fp_regnum, regloc); - saved_registers[m_machine_fp_regnum] = true; + auto &cfa_value = row->GetCFAValue(); + auto &afa_value = row->GetAFAValue(); + auto fa_value_ptr = is_aligned ? &afa_value : &cfa_value; + + if (mov_rsp_rbp_pattern_p()) { + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetIsRegisterPlusOffset( + m_lldb_fp_regnum, fa_value_ptr->GetOffset()); + row_updated = true; + } + } + + else if (mov_rsp_rbx_pattern_p()) { + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetIsRegisterPlusOffset( + m_lldb_alt_fp_regnum, fa_value_ptr->GetOffset()); + row_updated = true; + } + } + + else if (and_rsp_pattern_p()) { + current_sp_bytes_offset_from_fa = 0; + afa_value.SetIsRegisterPlusOffset( + m_lldb_sp_regnum, current_sp_bytes_offset_from_fa); + fa_value_ptr = &afa_value; + is_aligned = true; row_updated = true; } - else if (mov_rsp_rbp_pattern_p()) { - row->GetCFAValue().SetIsRegisterPlusOffset( - m_lldb_fp_regnum, row->GetCFAValue().GetOffset()); - row_updated = true; + else if (mov_rbp_rsp_pattern_p()) { + if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_fp_regnum) + { + is_aligned = false; + fa_value_ptr = &cfa_value; + afa_value.SetUnspecified(); + row_updated = true; + } + if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum) + current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset(); + } + + else if (mov_rbx_rsp_pattern_p()) { + if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_alt_fp_regnum) + { + is_aligned = false; + fa_value_ptr = &cfa_value; + afa_value.SetUnspecified(); + row_updated = true; + } + if (fa_value_ptr->GetRegisterNumber() == m_lldb_alt_fp_regnum) + current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset(); } // This is the start() function (or a pthread equivalent), it starts with a @@ -726,21 +844,24 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( } else if (push_reg_p(machine_regno)) { - current_sp_bytes_offset_from_cfa += m_wordsize; - // the PUSH instruction has moved the stack pointer - if the CFA is set + current_sp_bytes_offset_from_fa += m_wordsize; + // the PUSH instruction has moved the stack pointer - if the FA is set // in terms of the stack pointer, we need to add a new row of // instructions. - if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa); row_updated = true; } // record where non-volatile (callee-saved, spilled) registers are saved // on the stack if (nonvolatile_reg_p(machine_regno) && machine_regno_to_lldb_regno(machine_regno, lldb_regno) && - saved_registers[machine_regno] == false) { + !saved_registers[machine_regno]) { UnwindPlan::Row::RegisterLocation regloc; - regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_cfa); + if (is_aligned) + regloc.SetAtAFAPlusOffset(-current_sp_bytes_offset_from_fa); + else + regloc.SetAtCFAPlusOffset(-current_sp_bytes_offset_from_fa); row->SetRegisterInfo(lldb_regno, regloc); saved_registers[machine_regno] = true; row_updated = true; @@ -748,37 +869,37 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( } else if (pop_reg_p(machine_regno)) { - current_sp_bytes_offset_from_cfa -= m_wordsize; + current_sp_bytes_offset_from_fa -= m_wordsize; if (nonvolatile_reg_p(machine_regno) && machine_regno_to_lldb_regno(machine_regno, lldb_regno) && - saved_registers[machine_regno] == true) { + saved_registers[machine_regno]) { saved_registers[machine_regno] = false; row->RemoveRegisterInfo(lldb_regno); - if (machine_regno == (int)m_machine_fp_regnum) { - row->GetCFAValue().SetIsRegisterPlusOffset( - m_lldb_sp_regnum, row->GetCFAValue().GetOffset()); + if (lldb_regno == fa_value_ptr->GetRegisterNumber()) { + fa_value_ptr->SetIsRegisterPlusOffset( + m_lldb_sp_regnum, fa_value_ptr->GetOffset()); } in_epilogue = true; row_updated = true; } - // the POP instruction has moved the stack pointer - if the CFA is set in + // the POP instruction has moved the stack pointer - if the FA is set in // terms of the stack pointer, we need to add a new row of instructions. - if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { - row->GetCFAValue().SetIsRegisterPlusOffset( - m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa); + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetIsRegisterPlusOffset( + m_lldb_sp_regnum, current_sp_bytes_offset_from_fa); row_updated = true; } } else if (pop_misc_reg_p()) { - current_sp_bytes_offset_from_cfa -= m_wordsize; - if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { - row->GetCFAValue().SetIsRegisterPlusOffset( - m_lldb_sp_regnum, current_sp_bytes_offset_from_cfa); + current_sp_bytes_offset_from_fa -= m_wordsize; + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetIsRegisterPlusOffset( + m_lldb_sp_regnum, current_sp_bytes_offset_from_fa); row_updated = true; } } @@ -787,41 +908,57 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( // off the stack into rbp (restoring the caller's rbp value). It is the // opposite of ENTER, or 'push rbp, mov rsp rbp'. else if (leave_pattern_p()) { - // We're going to copy the value in rbp into rsp, so re-set the sp offset - // based on the CFAValue. Also, adjust it to recognize that we're - // popping the saved rbp value off the stack. - current_sp_bytes_offset_from_cfa = row->GetCFAValue().GetOffset(); - current_sp_bytes_offset_from_cfa -= m_wordsize; - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); + if (saved_registers[m_machine_fp_regnum]) { + saved_registers[m_machine_fp_regnum] = false; + row->RemoveRegisterInfo(m_lldb_fp_regnum); - // rbp is restored to the caller's value - saved_registers[m_machine_fp_regnum] = false; - row->RemoveRegisterInfo(m_lldb_fp_regnum); + row_updated = true; + } - // cfa is now in terms of rsp again. - row->GetCFAValue().SetIsRegisterPlusOffset( - m_lldb_sp_regnum, row->GetCFAValue().GetOffset()); - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); + if (is_aligned && cfa_value.GetRegisterNumber() == m_lldb_fp_regnum) + { + is_aligned = false; + fa_value_ptr = &cfa_value; + afa_value.SetUnspecified(); + row_updated = true; + } + + if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum) + { + fa_value_ptr->SetIsRegisterPlusOffset( + m_lldb_sp_regnum, fa_value_ptr->GetOffset()); + + current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset(); + } + + current_sp_bytes_offset_from_fa -= m_wordsize; + + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetIsRegisterPlusOffset( + m_lldb_sp_regnum, current_sp_bytes_offset_from_fa); + row_updated = true; + } in_epilogue = true; - row_updated = true; } else if (mov_reg_to_local_stack_frame_p(machine_regno, stack_offset) && nonvolatile_reg_p(machine_regno) && machine_regno_to_lldb_regno(machine_regno, lldb_regno) && - saved_registers[machine_regno] == false) { + !saved_registers[machine_regno]) { saved_registers[machine_regno] = true; UnwindPlan::Row::RegisterLocation regloc; // stack_offset for 'movq %r15, -80(%rbp)' will be 80. In the Row, we - // want to express this as the offset from the CFA. If the frame base is - // rbp (like the above instruction), the CFA offset for rbp is probably - // 16. So we want to say that the value is stored at the CFA address - + // want to express this as the offset from the FA. If the frame base is + // rbp (like the above instruction), the FA offset for rbp is probably + // 16. So we want to say that the value is stored at the FA address - // 96. - regloc.SetAtCFAPlusOffset( - -(stack_offset + row->GetCFAValue().GetOffset())); + if (is_aligned) + regloc.SetAtAFAPlusOffset(-(stack_offset + fa_value_ptr->GetOffset())); + else + regloc.SetAtCFAPlusOffset(-(stack_offset + fa_value_ptr->GetOffset())); row->SetRegisterInfo(lldb_regno, regloc); @@ -829,17 +966,17 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( } else if (sub_rsp_pattern_p(stack_offset)) { - current_sp_bytes_offset_from_cfa += stack_offset; - if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); + current_sp_bytes_offset_from_fa += stack_offset; + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa); row_updated = true; } } else if (add_rsp_pattern_p(stack_offset)) { - current_sp_bytes_offset_from_cfa -= stack_offset; - if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); + current_sp_bytes_offset_from_fa -= stack_offset; + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa); row_updated = true; } in_epilogue = true; @@ -847,27 +984,48 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( else if (push_extended_pattern_p() || push_imm_pattern_p() || push_misc_reg_p()) { - current_sp_bytes_offset_from_cfa += m_wordsize; - if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); + current_sp_bytes_offset_from_fa += m_wordsize; + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa); row_updated = true; } } else if (lea_rsp_pattern_p(stack_offset)) { - current_sp_bytes_offset_from_cfa -= stack_offset; - if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); + current_sp_bytes_offset_from_fa -= stack_offset; + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa); row_updated = true; } if (stack_offset > 0) in_epilogue = true; } - else if (lea_rbp_rsp_pattern_p(stack_offset) && - row->GetCFAValue().GetRegisterNumber() == m_lldb_fp_regnum) { - current_sp_bytes_offset_from_cfa = - row->GetCFAValue().GetOffset() - stack_offset; + else if (lea_rbp_rsp_pattern_p(stack_offset)) { + if (is_aligned && + cfa_value.GetRegisterNumber() == m_lldb_fp_regnum) { + is_aligned = false; + fa_value_ptr = &cfa_value; + afa_value.SetUnspecified(); + row_updated = true; + } + if (fa_value_ptr->GetRegisterNumber() == m_lldb_fp_regnum) { + current_sp_bytes_offset_from_fa = + fa_value_ptr->GetOffset() - stack_offset; + } + } + + else if (lea_rbx_rsp_pattern_p(stack_offset)) { + if (is_aligned && + cfa_value.GetRegisterNumber() == m_lldb_alt_fp_regnum) { + is_aligned = false; + fa_value_ptr = &cfa_value; + afa_value.SetUnspecified(); + row_updated = true; + } + if (fa_value_ptr->GetRegisterNumber() == m_lldb_alt_fp_regnum) { + current_sp_bytes_offset_from_fa = fa_value_ptr->GetOffset() - stack_offset; + } } else if (ret_pattern_p() && prologue_completed_row.get()) { @@ -877,8 +1035,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( UnwindPlan::Row *newrow = new UnwindPlan::Row; *newrow = *prologue_completed_row.get(); row.reset(newrow); - current_sp_bytes_offset_from_cfa = + current_sp_bytes_offset_from_fa = prologue_completed_sp_bytes_offset_from_cfa; + is_aligned = prologue_completed_is_aligned; saved_registers.clear(); saved_registers.resize(prologue_completed_saved_registers.size(), false); @@ -896,9 +1055,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( // This is used in i386 programs to get the PIC base address for finding // global data else if (call_next_insn_pattern_p()) { - current_sp_bytes_offset_from_cfa += m_wordsize; - if (row->GetCFAValue().GetRegisterNumber() == m_lldb_sp_regnum) { - row->GetCFAValue().SetOffset(current_sp_bytes_offset_from_cfa); + current_sp_bytes_offset_from_fa += m_wordsize; + if (fa_value_ptr->GetRegisterNumber() == m_lldb_sp_regnum) { + fa_value_ptr->SetOffset(current_sp_bytes_offset_from_fa); row_updated = true; } } @@ -914,7 +1073,7 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( } } - if (in_epilogue == false && row_updated) { + if (!in_epilogue && row_updated) { // If we're not in an epilogue sequence, save the updated Row UnwindPlan::Row *newrow = new UnwindPlan::Row; *newrow = *row.get(); @@ -929,9 +1088,10 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly( // We may change the sp value without adding a new Row necessarily -- keep // track of it either way. - if (in_epilogue == false) { + if (!in_epilogue) { prologue_completed_sp_bytes_offset_from_cfa = - current_sp_bytes_offset_from_cfa; + current_sp_bytes_offset_from_fa; + prologue_completed_is_aligned = is_aligned; } m_cur_insn = m_cur_insn + insn_len; @@ -1194,7 +1354,7 @@ bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction( uint8_t *data, size_t size, size_t &offset) { offset = 0; - if (m_register_map_initialized == false) + if (!m_register_map_initialized) return false; while (offset < size) { diff --git a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h index cec9803c8a49..e02b510ba1f9 100644 --- a/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h +++ b/contrib/llvm/tools/lldb/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h @@ -98,10 +98,15 @@ private: bool push_extended_pattern_p(); bool push_misc_reg_p(); bool mov_rsp_rbp_pattern_p(); + bool mov_rsp_rbx_pattern_p(); + bool mov_rbp_rsp_pattern_p(); + bool mov_rbx_rsp_pattern_p(); bool sub_rsp_pattern_p(int &amount); bool add_rsp_pattern_p(int &amount); bool lea_rsp_pattern_p(int &amount); bool lea_rbp_rsp_pattern_p(int &amount); + bool lea_rbx_rsp_pattern_p(int &amount); + bool and_rsp_pattern_p(); bool push_reg_p(int ®no); bool pop_reg_p(int ®no); bool pop_rbp_pattern_p(); @@ -157,9 +162,11 @@ private: uint32_t m_machine_ip_regnum; uint32_t m_machine_sp_regnum; uint32_t m_machine_fp_regnum; + uint32_t m_machine_alt_fp_regnum; uint32_t m_lldb_ip_regnum; uint32_t m_lldb_sp_regnum; uint32_t m_lldb_fp_regnum; + uint32_t m_lldb_alt_fp_regnum; typedef std::map MachineRegnumToNameAndLLDBRegnum; diff --git a/contrib/llvm/tools/lldb/source/Symbol/ArmUnwindInfo.cpp b/contrib/llvm/tools/lldb/source/Symbol/ArmUnwindInfo.cpp index 6dcad62f2f9d..08f28073be21 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/ArmUnwindInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/ArmUnwindInfo.cpp @@ -66,7 +66,7 @@ ArmUnwindInfo::ArmUnwindInfo(ObjectFile &objfile, SectionSP &arm_exidx, // Sort the entries in the exidx section. The entries should be sorted inside // the section but some old compiler isn't sorted them. - std::sort(m_exidx_entries.begin(), m_exidx_entries.end()); + llvm::sort(m_exidx_entries.begin(), m_exidx_entries.end()); } ArmUnwindInfo::~ArmUnwindInfo() {} diff --git a/contrib/llvm/tools/lldb/source/Symbol/Block.cpp b/contrib/llvm/tools/lldb/source/Symbol/Block.cpp index 46f875fca776..d0342355911c 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/Block.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/Block.cpp @@ -83,7 +83,7 @@ void Block::Dump(Stream *s, addr_t base_addr, int32_t depth, size_t num_ranges = m_ranges.GetSize(); for (size_t i = 0; i < num_ranges; ++i) { const Range &range = m_ranges.GetEntryRef(i); - if (parent_block != nullptr && parent_block->Contains(range) == false) + if (parent_block != nullptr && !parent_block->Contains(range)) *s << '!'; else *s << ' '; @@ -369,7 +369,7 @@ void Block::SetInlinedFunctionInfo(const char *name, const char *mangled, } VariableListSP Block::GetBlockVariableList(bool can_create) { - if (m_parsed_block_variables == false) { + if (!m_parsed_block_variables) { if (m_variable_list_sp.get() == nullptr && can_create) { m_parsed_block_variables = true; SymbolContext sc; @@ -402,7 +402,7 @@ Block::AppendBlockVariables(bool can_create, bool get_child_block_variables, collection::const_iterator pos, end = m_children.end(); for (pos = m_children.begin(); pos != end; ++pos) { Block *child_block = pos->get(); - if (stop_if_child_block_is_inlined_function == false || + if (!stop_if_child_block_is_inlined_function || child_block->GetInlinedFunctionInfo() == nullptr) { num_variables_added += child_block->AppendBlockVariables( can_create, get_child_block_variables, @@ -444,19 +444,16 @@ uint32_t Block::AppendVariables(bool can_create, bool get_parent_variables, return num_variables_added; } +SymbolFile *Block::GetSymbolFile() { + if (ModuleSP module_sp = CalculateSymbolContextModule()) + if (SymbolVendor *sym_vendor = module_sp->GetSymbolVendor()) + return sym_vendor->GetSymbolFile(); + return nullptr; +} + CompilerDeclContext Block::GetDeclContext() { - ModuleSP module_sp = CalculateSymbolContextModule(); - - if (module_sp) { - SymbolVendor *sym_vendor = module_sp->GetSymbolVendor(); - - if (sym_vendor) { - SymbolFile *sym_file = sym_vendor->GetSymbolFile(); - - if (sym_file) - return sym_file->GetDeclContextForUID(GetID()); - } - } + if (SymbolFile *sym_file = GetSymbolFile()) + return sym_file->GetDeclContextForUID(GetID()); return CompilerDeclContext(); } diff --git a/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp b/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp index a7578de0dcac..15596cbebd14 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/ClangASTContext.cpp @@ -12,13 +12,10 @@ #include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" -// C Includes -// C++ Includes #include #include #include -// Other libraries and framework includes // Clang headers like to use NDEBUG inside of them to enable/disable debug // related features using "#ifndef NDEBUG" preprocessor blocks to do one thing @@ -76,7 +73,6 @@ #include "lldb/Core/DumpDataExtractor.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/ThreadSafeDenseMap.h" #include "lldb/Core/UniqueCStringMap.h" @@ -97,6 +93,7 @@ #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/Scalar.h" #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h" #ifdef LLDB_ENABLE_ALL @@ -124,8 +121,204 @@ ClangASTContextSupportsLanguage(lldb::LanguageType language) { language == eLanguageTypeRust || language == eLanguageTypeExtRenderScript || // Use Clang for D until there is a proper language plugin for it - language == eLanguageTypeD; + language == eLanguageTypeD || + // Open Dylan compiler debug info is designed to be Clang-compatible + language == eLanguageTypeDylan; } + +// Checks whether m1 is an overload of m2 (as opposed to an override). This is +// called by addOverridesForMethod to distinguish overrides (which share a +// vtable entry) from overloads (which require distinct entries). +bool isOverload(clang::CXXMethodDecl *m1, clang::CXXMethodDecl *m2) { + // FIXME: This should detect covariant return types, but currently doesn't. + lldbassert(&m1->getASTContext() == &m2->getASTContext() && + "Methods should have the same AST context"); + clang::ASTContext &context = m1->getASTContext(); + + const auto *m1Type = llvm::cast( + context.getCanonicalType(m1->getType())); + + const auto *m2Type = llvm::cast( + context.getCanonicalType(m2->getType())); + + auto compareArgTypes = [&context](const clang::QualType &m1p, + const clang::QualType &m2p) { + return context.hasSameType(m1p.getUnqualifiedType(), + m2p.getUnqualifiedType()); + }; + + // FIXME: In C++14 and later, we can just pass m2Type->param_type_end() + // as a fourth parameter to std::equal(). + return (m1->getNumParams() != m2->getNumParams()) || + !std::equal(m1Type->param_type_begin(), m1Type->param_type_end(), + m2Type->param_type_begin(), compareArgTypes); +} + +// If decl is a virtual method, walk the base classes looking for methods that +// decl overrides. This table of overridden methods is used by IRGen to +// determine the vtable layout for decl's parent class. +void addOverridesForMethod(clang::CXXMethodDecl *decl) { + if (!decl->isVirtual()) + return; + + clang::CXXBasePaths paths; + + auto find_overridden_methods = + [decl](const clang::CXXBaseSpecifier *specifier, + clang::CXXBasePath &path) { + if (auto *base_record = llvm::dyn_cast( + specifier->getType()->getAs()->getDecl())) { + + clang::DeclarationName name = decl->getDeclName(); + + // If this is a destructor, check whether the base class destructor is + // virtual. + if (name.getNameKind() == clang::DeclarationName::CXXDestructorName) + if (auto *baseDtorDecl = base_record->getDestructor()) { + if (baseDtorDecl->isVirtual()) { + path.Decls = baseDtorDecl; + return true; + } else + return false; + } + + // Otherwise, search for name in the base class. + for (path.Decls = base_record->lookup(name); !path.Decls.empty(); + path.Decls = path.Decls.slice(1)) { + if (auto *method_decl = + llvm::dyn_cast(path.Decls.front())) + if (method_decl->isVirtual() && !isOverload(decl, method_decl)) { + path.Decls = method_decl; + return true; + } + } + } + + return false; + }; + + if (decl->getParent()->lookupInBases(find_overridden_methods, paths)) { + for (auto *overridden_decl : paths.found_decls()) + decl->addOverriddenMethod( + llvm::cast(overridden_decl)); + } +} +} + +static lldb::addr_t GetVTableAddress(Process &process, + VTableContextBase &vtable_ctx, + ValueObject &valobj, + const ASTRecordLayout &record_layout) { + // Retrieve type info + CompilerType pointee_type; + CompilerType this_type(valobj.GetCompilerType()); + uint32_t type_info = this_type.GetTypeInfo(&pointee_type); + if (!type_info) + return LLDB_INVALID_ADDRESS; + + // Check if it's a pointer or reference + bool ptr_or_ref = false; + if (type_info & (eTypeIsPointer | eTypeIsReference)) { + ptr_or_ref = true; + type_info = pointee_type.GetTypeInfo(); + } + + // We process only C++ classes + const uint32_t cpp_class = eTypeIsClass | eTypeIsCPlusPlus; + if ((type_info & cpp_class) != cpp_class) + return LLDB_INVALID_ADDRESS; + + // Calculate offset to VTable pointer + lldb::offset_t vbtable_ptr_offset = + vtable_ctx.isMicrosoft() ? record_layout.getVBPtrOffset().getQuantity() + : 0; + + if (ptr_or_ref) { + // We have a pointer / ref to object, so read + // VTable pointer from process memory + + if (valobj.GetAddressTypeOfChildren() != eAddressTypeLoad) + return LLDB_INVALID_ADDRESS; + + auto vbtable_ptr_addr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + if (vbtable_ptr_addr == LLDB_INVALID_ADDRESS) + return LLDB_INVALID_ADDRESS; + + vbtable_ptr_addr += vbtable_ptr_offset; + + Status err; + return process.ReadPointerFromMemory(vbtable_ptr_addr, err); + } + + // We have an object already read from process memory, + // so just extract VTable pointer from it + + DataExtractor data; + Status err; + auto size = valobj.GetData(data, err); + if (err.Fail() || vbtable_ptr_offset + data.GetAddressByteSize() > size) + return LLDB_INVALID_ADDRESS; + + return data.GetPointer(&vbtable_ptr_offset); +} + +static int64_t ReadVBaseOffsetFromVTable(Process &process, + VTableContextBase &vtable_ctx, + lldb::addr_t vtable_ptr, + const CXXRecordDecl *cxx_record_decl, + const CXXRecordDecl *base_class_decl) { + if (vtable_ctx.isMicrosoft()) { + clang::MicrosoftVTableContext &msoft_vtable_ctx = + static_cast(vtable_ctx); + + // Get the index into the virtual base table. The + // index is the index in uint32_t from vbtable_ptr + const unsigned vbtable_index = + msoft_vtable_ctx.getVBTableIndex(cxx_record_decl, base_class_decl); + const lldb::addr_t base_offset_addr = vtable_ptr + vbtable_index * 4; + Status err; + return process.ReadSignedIntegerFromMemory(base_offset_addr, 4, INT64_MAX, + err); + } + + clang::ItaniumVTableContext &itanium_vtable_ctx = + static_cast(vtable_ctx); + + clang::CharUnits base_offset_offset = + itanium_vtable_ctx.getVirtualBaseOffsetOffset(cxx_record_decl, + base_class_decl); + const lldb::addr_t base_offset_addr = + vtable_ptr + base_offset_offset.getQuantity(); + const uint32_t base_offset_size = process.GetAddressByteSize(); + Status err; + return process.ReadSignedIntegerFromMemory(base_offset_addr, base_offset_size, + INT64_MAX, err); +} + +static bool GetVBaseBitOffset(VTableContextBase &vtable_ctx, + ValueObject &valobj, + const ASTRecordLayout &record_layout, + const CXXRecordDecl *cxx_record_decl, + const CXXRecordDecl *base_class_decl, + int32_t &bit_offset) { + ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); + Process *process = exe_ctx.GetProcessPtr(); + if (!process) + return false; + + lldb::addr_t vtable_ptr = + GetVTableAddress(*process, vtable_ctx, valobj, record_layout); + if (vtable_ptr == LLDB_INVALID_ADDRESS) + return false; + + auto base_offset = ReadVBaseOffsetFromVTable( + *process, vtable_ctx, vtable_ptr, cxx_record_decl, base_class_decl); + if (base_offset == INT64_MAX) + return false; + + bit_offset = base_offset * 8; + + return true; } typedef lldb_private::ThreadSafeDenseMap @@ -383,7 +576,7 @@ static void ParseLangArgs(LangOptions &Opts, InputKind IK, const char *triple) { if (IK.getLanguage() == InputKind::Asm) { Opts.AsmPreprocessor = 1; } else if (IK.isObjectiveC()) { - Opts.ObjC1 = Opts.ObjC2 = 1; + Opts.ObjC = 1; } LangStandard::Kind LangStd = LangStandard::lang_unspecified; @@ -630,7 +823,6 @@ void ClangASTContext::SetExternalSource( if (ast) { ast->setExternalSource(ast_source_ap); ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(true); - // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(true); } } @@ -641,7 +833,6 @@ void ClangASTContext::RemoveExternalSource() { llvm::IntrusiveRefCntPtr empty_ast_source_ap; ast->setExternalSource(empty_ast_source_ap); ast->getTranslationUnitDecl()->setHasExternalLexicalStorage(false); - // ast->getTranslationUnitDecl()->setHasExternalVisibleStorage(false); } } @@ -803,9 +994,7 @@ TargetInfo *ClangASTContext::getTargetInfo() { static inline bool QualTypeMatchesBitSize(const uint64_t bit_size, ASTContext *ast, QualType qual_type) { uint64_t qual_type_bit_size = ast->getTypeSize(qual_type); - if (qual_type_bit_size == bit_size) - return true; - return false; + return qual_type_bit_size == bit_size; } CompilerType @@ -954,9 +1143,10 @@ CompilerType ClangASTContext::GetBasicType(ASTContext *ast, uint32_t ClangASTContext::GetPointerByteSize() { if (m_pointer_byte_size == 0) - m_pointer_byte_size = GetBasicType(lldb::eBasicTypeVoid) - .GetPointerType() - .GetByteSize(nullptr); + if (auto size = GetBasicType(lldb::eBasicTypeVoid) + .GetPointerType() + .GetByteSize(nullptr)) + m_pointer_byte_size = *size; return m_pointer_byte_size; } @@ -1677,8 +1867,7 @@ CompilerType ClangASTContext::CreateObjCClass(const char *name, } static inline bool BaseSpecifierIsEmpty(const CXXBaseSpecifier *b) { - return ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()) == - false; + return !ClangASTContext::RecordHasFields(b->getType()->getAsCXXRecordDecl()); } uint32_t @@ -1984,7 +2173,8 @@ FunctionDecl *ClangASTContext::CreateFunctionDeclaration( CompilerType ClangASTContext::CreateFunctionType( ASTContext *ast, const CompilerType &result_type, const CompilerType *args, - unsigned num_args, bool is_variadic, unsigned type_quals) { + unsigned num_args, bool is_variadic, unsigned type_quals, + clang::CallingConv cc) { if (ast == nullptr) return CompilerType(); // invalid AST @@ -2012,9 +2202,10 @@ CompilerType ClangASTContext::CreateFunctionType( // TODO: Detect calling convention in DWARF? FunctionProtoType::ExtProtoInfo proto_info; + proto_info.ExtInfo = cc; proto_info.Variadic = is_variadic; proto_info.ExceptionSpec = EST_None; - proto_info.TypeQuals = type_quals; + proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals); proto_info.RefQualifier = RQ_None; return CompilerType(ast, @@ -2023,14 +2214,17 @@ CompilerType ClangASTContext::CreateFunctionType( } ParmVarDecl *ClangASTContext::CreateParameterDeclaration( - const char *name, const CompilerType ¶m_type, int storage) { + clang::DeclContext *decl_ctx, const char *name, + const CompilerType ¶m_type, int storage) { ASTContext *ast = getASTContext(); assert(ast != nullptr); - return ParmVarDecl::Create(*ast, ast->getTranslationUnitDecl(), - SourceLocation(), SourceLocation(), - name && name[0] ? &ast->Idents.get(name) : nullptr, - ClangUtil::GetQualType(param_type), nullptr, - (clang::StorageClass)storage, nullptr); + auto *decl = + ParmVarDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(), + name && name[0] ? &ast->Idents.get(name) : nullptr, + ClangUtil::GetQualType(param_type), nullptr, + (clang::StorageClass)storage, nullptr); + decl_ctx->addDecl(decl); + return decl; } void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl, @@ -2138,6 +2332,9 @@ ClangASTContext::CreateEnumerationType(const char *name, DeclContext *decl_ctx, false); // IsFixed if (enum_decl) { + if (decl_ctx) + decl_ctx->addDecl(enum_decl); + // TODO: check if we should be setting the promotion type too? enum_decl->setIntegerType(ClangUtil::GetQualType(integer_clang_type)); @@ -3739,9 +3936,7 @@ bool ClangASTContext::IsCXXClassType(const CompilerType &type) { return false; clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type)); - if (!qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr) - return true; - return false; + return !qual_type.isNull() && qual_type->getAsCXXRecordDecl() != nullptr; } bool ClangASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) { @@ -4313,7 +4508,8 @@ ClangASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, // TODO: the real stride will be >= this value.. find the real one! if (stride) - *stride = element_type.GetByteSize(nullptr); + if (Optional size = element_type.GetByteSize(nullptr)) + *stride = *size; return element_type; } @@ -4665,6 +4861,8 @@ CompilerType ClangASTContext::CreateTypedefType( decl->setAccess(clang::AS_public); // TODO respect proper access specifier + decl_ctx->addDecl(decl); + // Get a uniqued clang::QualType for the typedef decl type return CompilerType(clang_ast, clang_ast->getTypedefType(decl)); } @@ -5032,6 +5230,20 @@ lldb::Encoding ClangASTContext::GetEncoding(lldb::opaque_compiler_type_t type, case clang::BuiltinType::Kind::PseudoObject: case clang::BuiltinType::Kind::UnknownAny: break; + + case clang::BuiltinType::OCLIntelSubgroupAVCMcePayload: + case clang::BuiltinType::OCLIntelSubgroupAVCImePayload: + case clang::BuiltinType::OCLIntelSubgroupAVCRefPayload: + case clang::BuiltinType::OCLIntelSubgroupAVCSicPayload: + case clang::BuiltinType::OCLIntelSubgroupAVCMceResult: + case clang::BuiltinType::OCLIntelSubgroupAVCImeResult: + case clang::BuiltinType::OCLIntelSubgroupAVCRefResult: + case clang::BuiltinType::OCLIntelSubgroupAVCSicResult: + case clang::BuiltinType::OCLIntelSubgroupAVCImeResultSingleRefStreamout: + case clang::BuiltinType::OCLIntelSubgroupAVCImeResultDualRefStreamout: + case clang::BuiltinType::OCLIntelSubgroupAVCImeSingleRefStreamin: + case clang::BuiltinType::OCLIntelSubgroupAVCImeDualRefStreamin: + break; } break; // All pointer types are represented as unsigned integer encodings. We may @@ -5319,8 +5531,20 @@ static bool ObjCDeclHasIVars(clang::ObjCInterfaceDecl *class_interface_decl, return false; } +static Optional +GetDynamicArrayInfo(ClangASTContext &ast, SymbolFile *sym_file, + clang::QualType qual_type, + const ExecutionContext *exe_ctx) { + if (qual_type->isIncompleteArrayType()) + if (auto *metadata = ast.GetMetadata(qual_type.getAsOpaquePtr())) + return sym_file->GetDynamicArrayInfoForUID(metadata->GetUserID(), + exe_ctx); + return llvm::None; +} + uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) { + bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) { if (!type) return 0; @@ -5342,7 +5566,6 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, case clang::Type::Complex: return 0; - case clang::Type::Record: if (GetCompleteQualType(getASTContext(), qual_type)) { const clang::RecordType *record_type = @@ -5368,7 +5591,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, ->getDecl()); // Skip empty base classes - if (ClangASTContext::RecordHasFields(base_class_decl) == false) + if (!ClangASTContext::RecordHasFields(base_class_decl)) continue; num_children++; @@ -5420,7 +5643,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, clang::QualType pointee_type = pointer_type->getPointeeType(); uint32_t num_pointee_children = CompilerType(getASTContext(), pointee_type) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); // If this type points to a simple type, then it has 1 child if (num_pointee_children == 0) num_children = 1; @@ -5439,6 +5662,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, ->getSize() .getLimitedValue(); break; + case clang::Type::IncompleteArray: + if (auto array_info = + GetDynamicArrayInfo(*this, GetSymbolFile(), qual_type, exe_ctx)) + // Only 1-dimensional arrays are supported. + num_children = array_info->element_orders.size() + ? array_info->element_orders.back() + : 0; + break; case clang::Type::Pointer: { const clang::PointerType *pointer_type = @@ -5446,7 +5677,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, clang::QualType pointee_type(pointer_type->getPointeeType()); uint32_t num_pointee_children = CompilerType(getASTContext(), pointee_type) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); if (num_pointee_children == 0) { // We have a pointer to a pointee type that claims it has no children. We // will want to look at @@ -5462,7 +5693,7 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, clang::QualType pointee_type = reference_type->getPointeeType(); uint32_t num_pointee_children = CompilerType(getASTContext(), pointee_type) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); // If this type points to a simple type, then it has 1 child if (num_pointee_children == 0) num_children = 1; @@ -5475,14 +5706,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, CompilerType(getASTContext(), llvm::cast(qual_type) ->getDecl() ->getUnderlyingType()) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); break; case clang::Type::Auto: num_children = CompilerType(getASTContext(), llvm::cast(qual_type)->getDeducedType()) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); break; case clang::Type::Elaborated: @@ -5490,14 +5721,14 @@ uint32_t ClangASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, CompilerType( getASTContext(), llvm::cast(qual_type)->getNamedType()) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); break; case clang::Type::Paren: num_children = CompilerType(getASTContext(), llvm::cast(qual_type)->desugar()) - .GetNumChildren(omit_empty_base_classes); + .GetNumChildren(omit_empty_base_classes, exe_ctx); break; default: break; @@ -5735,10 +5966,10 @@ GetObjCFieldAtIndex(clang::ASTContext *ast, if (is_bitfield && ast) { clang::Expr *bitfield_bit_size_expr = ivar_pos->getBitWidth(); - llvm::APSInt bitfield_apsint; + clang::Expr::EvalResult result; if (bitfield_bit_size_expr && - bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, - *ast)) { + bitfield_bit_size_expr->EvaluateAsInt(result, *ast)) { + llvm::APSInt bitfield_apsint = result.Val.getInt(); *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); } } @@ -5795,10 +6026,11 @@ CompilerType ClangASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, if (is_bitfield) { clang::Expr *bitfield_bit_size_expr = field->getBitWidth(); - llvm::APSInt bitfield_apsint; + clang::Expr::EvalResult result; if (bitfield_bit_size_expr && - bitfield_bit_size_expr->EvaluateAsInt(bitfield_apsint, + bitfield_bit_size_expr->EvaluateAsInt(result, *getASTContext())) { + llvm::APSInt bitfield_apsint = result.Val.getInt(); *bitfield_bit_size_ptr = bitfield_apsint.getLimitedValue(); } } @@ -6366,6 +6598,10 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( if (!type) return CompilerType(); + auto get_exe_scope = [&exe_ctx]() { + return exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; + }; + clang::QualType parent_qual_type(GetCanonicalQualType(type)); const clang::Type::TypeClass parent_type_class = parent_qual_type->getTypeClass(); @@ -6374,8 +6610,9 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( child_is_base_class = false; language_flags = 0; - const bool idx_is_valid = idx < GetNumChildren(type, omit_empty_base_classes); - uint32_t bit_offset; + const bool idx_is_valid = + idx < GetNumChildren(type, omit_empty_base_classes, exe_ctx); + int32_t bit_offset; switch (parent_type_class) { case clang::Type::Builtin: if (idx_is_valid) { @@ -6420,7 +6657,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( if (omit_empty_base_classes) { base_class_decl = llvm::cast( base_class->getType()->getAs()->getDecl()); - if (ClangASTContext::RecordHasFields(base_class_decl) == false) + if (!ClangASTContext::RecordHasFields(base_class_decl)) continue; } @@ -6432,80 +6669,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( if (base_class->isVirtual()) { bool handled = false; if (valobj) { - Status err; - AddressType addr_type = eAddressTypeInvalid; - lldb::addr_t vtable_ptr_addr = - valobj->GetCPPVTableAddress(addr_type); - - if (vtable_ptr_addr != LLDB_INVALID_ADDRESS && - addr_type == eAddressTypeLoad) { - - ExecutionContext exe_ctx(valobj->GetExecutionContextRef()); - Process *process = exe_ctx.GetProcessPtr(); - if (process) { - clang::VTableContextBase *vtable_ctx = - getASTContext()->getVTableContext(); - if (vtable_ctx) { - if (vtable_ctx->isMicrosoft()) { - clang::MicrosoftVTableContext *msoft_vtable_ctx = - static_cast( - vtable_ctx); - - if (vtable_ptr_addr) { - const lldb::addr_t vbtable_ptr_addr = - vtable_ptr_addr + - record_layout.getVBPtrOffset().getQuantity(); - - const lldb::addr_t vbtable_ptr = - process->ReadPointerFromMemory(vbtable_ptr_addr, - err); - if (vbtable_ptr != LLDB_INVALID_ADDRESS) { - // Get the index into the virtual base table. The - // index is the index in uint32_t from vbtable_ptr - const unsigned vbtable_index = - msoft_vtable_ctx->getVBTableIndex( - cxx_record_decl, base_class_decl); - const lldb::addr_t base_offset_addr = - vbtable_ptr + vbtable_index * 4; - const uint32_t base_offset = - process->ReadUnsignedIntegerFromMemory( - base_offset_addr, 4, UINT32_MAX, err); - if (base_offset != UINT32_MAX) { - handled = true; - bit_offset = base_offset * 8; - } - } - } - } else { - clang::ItaniumVTableContext *itanium_vtable_ctx = - static_cast( - vtable_ctx); - if (vtable_ptr_addr) { - const lldb::addr_t vtable_ptr = - process->ReadPointerFromMemory(vtable_ptr_addr, - err); - if (vtable_ptr != LLDB_INVALID_ADDRESS) { - clang::CharUnits base_offset_offset = - itanium_vtable_ctx->getVirtualBaseOffsetOffset( - cxx_record_decl, base_class_decl); - const lldb::addr_t base_offset_addr = - vtable_ptr + base_offset_offset.getQuantity(); - const uint32_t base_offset_size = - process->GetAddressByteSize(); - const uint64_t base_offset = - process->ReadUnsignedIntegerFromMemory( - base_offset_addr, base_offset_size, - UINT32_MAX, err); - if (base_offset < UINT32_MAX) { - handled = true; - bit_offset = base_offset * 8; - } - } - } - } - } - } - } + clang::VTableContextBase *vtable_ctx = + getASTContext()->getVTableContext(); + if (vtable_ctx) + handled = GetVBaseBitOffset(*vtable_ctx, *valobj, + record_layout, cxx_record_decl, + base_class_decl, bit_offset); } if (!handled) bit_offset = record_layout.getVBaseClassOffset(base_class_decl) @@ -6521,9 +6690,11 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( CompilerType base_class_clang_type(getASTContext(), base_class->getType()); child_name = base_class_clang_type.GetTypeName().AsCString(""); - uint64_t base_class_clang_type_bit_size = - base_class_clang_type.GetBitSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); + Optional size = + base_class_clang_type.GetBitSize(get_exe_scope()); + if (!size) + return {}; + uint64_t base_class_clang_type_bit_size = *size; // Base classes bit sizes should be a multiple of 8 bits in size assert(base_class_clang_type_bit_size % 8 == 0); @@ -6551,8 +6722,11 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( // alignment (field_type_info.second) from the AST context. CompilerType field_clang_type(getASTContext(), field->getType()); assert(field_idx < record_layout.getFieldCount()); - child_byte_size = field_clang_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); + Optional size = + field_clang_type.GetByteSize(get_exe_scope()); + if (!size) + return {}; + child_byte_size = *size; const uint32_t child_bit_size = child_byte_size * 8; // Figure out the field offset within the current struct/union/class @@ -6596,8 +6770,8 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( CompilerType base_class_clang_type( getASTContext(), getASTContext()->getObjCInterfaceType( superclass_interface_decl)); - if (base_class_clang_type.GetNumChildren( - omit_empty_base_classes) > 0) { + if (base_class_clang_type.GetNumChildren(omit_empty_base_classes, + exe_ctx) > 0) { if (idx == 0) { clang::QualType ivar_qual_type( getASTContext()->getObjCInterfaceType( @@ -6664,9 +6838,9 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( } } - // Setting this to UINT32_MAX to make sure we don't compute it + // Setting this to INT32_MAX to make sure we don't compute it // twice... - bit_offset = UINT32_MAX; + bit_offset = INT32_MAX; if (child_byte_offset == static_cast(LLDB_INVALID_IVAR_OFFSET)) { @@ -6683,7 +6857,7 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( if (ClangASTContext::FieldIsBitfield(getASTContext(), ivar_decl, child_bitfield_bit_size)) { - if (bit_offset == UINT32_MAX) + if (bit_offset == INT32_MAX) bit_offset = interface_layout.getFieldOffset( child_idx - superclass_idx); @@ -6723,10 +6897,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( // We have a pointer to an simple type if (idx == 0 && pointee_clang_type.GetCompleteType()) { - child_byte_size = pointee_clang_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = 0; - return pointee_clang_type; + if (Optional size = + pointee_clang_type.GetByteSize(get_exe_scope())) { + child_byte_size = *size; + child_byte_offset = 0; + return pointee_clang_type; + } } } } @@ -6744,10 +6920,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( ::snprintf(element_name, sizeof(element_name), "[%" PRIu64 "]", static_cast(idx)); child_name.assign(element_name); - child_byte_size = element_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - return element_type; + if (Optional size = + element_type.GetByteSize(get_exe_scope())) { + child_byte_size = *size; + child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; + return element_type; + } } } } @@ -6761,10 +6939,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( CompilerType element_type(getASTContext(), array->getElementType()); if (element_type.GetCompleteType()) { child_name = llvm::formatv("[{0}]", idx); - child_byte_size = element_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - return element_type; + if (Optional size = + element_type.GetByteSize(get_exe_scope())) { + child_byte_size = *size; + child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; + return element_type; + } } } } @@ -6798,10 +6978,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( // We have a pointer to an simple type if (idx == 0) { - child_byte_size = pointee_clang_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = 0; - return pointee_clang_type; + if (Optional size = + pointee_clang_type.GetByteSize(get_exe_scope())) { + child_byte_size = *size; + child_byte_offset = 0; + return pointee_clang_type; + } } } break; @@ -6833,10 +7015,12 @@ CompilerType ClangASTContext::GetChildCompilerTypeAtIndex( // We have a pointer to an simple type if (idx == 0) { - child_byte_size = pointee_clang_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = 0; - return pointee_clang_type; + if (Optional size = + pointee_clang_type.GetByteSize(get_exe_scope())) { + child_byte_size = *size; + child_byte_offset = 0; + return pointee_clang_type; + } } } } @@ -7283,14 +7467,14 @@ ClangASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, ->getAs() ->getDecl()); if (omit_empty_base_classes && - ClangASTContext::RecordHasFields(base_class_decl) == false) + !ClangASTContext::RecordHasFields(base_class_decl)) continue; CompilerType base_class_clang_type(getASTContext(), base_class->getType()); std::string base_class_type_name( base_class_clang_type.GetTypeName().AsCString("")); - if (base_class_type_name.compare(name) == 0) + if (base_class_type_name == name) return child_idx; ++child_idx; } @@ -7625,7 +7809,7 @@ ClangASTContext::GetTypeTemplateArgument(lldb::opaque_compiler_type_t type, return CompilerType(getASTContext(), template_arg.getAsType()); } -llvm::Optional +Optional ClangASTContext::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx) { const clang::ClassTemplateSpecializationDecl *template_decl = @@ -7665,11 +7849,16 @@ clang::RecordDecl *ClangASTContext::GetAsRecordDecl(const CompilerType &type) { } clang::TagDecl *ClangASTContext::GetAsTagDecl(const CompilerType &type) { - clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type); - if (qual_type.isNull()) - return nullptr; - else - return qual_type->getAsTagDecl(); + return ClangUtil::GetAsTagDecl(type); +} + +clang::TypedefNameDecl * +ClangASTContext::GetAsTypedefDecl(const CompilerType &type) { + const clang::TypedefType *typedef_type = + llvm::dyn_cast(ClangUtil::GetQualType(type)); + if (typedef_type) + return typedef_type->getDecl(); + return nullptr; } clang::CXXRecordDecl * @@ -7688,7 +7877,7 @@ ClangASTContext::GetAsObjCInterfaceDecl(const CompilerType &type) { } clang::FieldDecl *ClangASTContext::AddFieldToRecordType( - const CompilerType &type, const char *name, + const CompilerType &type, llvm::StringRef name, const CompilerType &field_clang_type, AccessType access, uint32_t bitfield_bit_size) { if (!type.IsValid() || !field_clang_type.IsValid()) @@ -7698,6 +7887,9 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType( if (!ast) return nullptr; clang::ASTContext *clang_ast = ast->getASTContext(); + clang::IdentifierInfo *ident = nullptr; + if (!name.empty()) + ident = &clang_ast->Idents.get(name); clang::FieldDecl *field = nullptr; @@ -7715,14 +7907,14 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType( field = clang::FieldDecl::Create( *clang_ast, record_decl, clang::SourceLocation(), clang::SourceLocation(), - name ? &clang_ast->Idents.get(name) : nullptr, // Identifier - ClangUtil::GetQualType(field_clang_type), // Field type - nullptr, // TInfo * - bit_width, // BitWidth - false, // Mutable - clang::ICIS_NoInit); // HasInit + ident, // Identifier + ClangUtil::GetQualType(field_clang_type), // Field type + nullptr, // TInfo * + bit_width, // BitWidth + false, // Mutable + clang::ICIS_NoInit); // HasInit - if (!name) { + if (name.empty()) { // Determine whether this field corresponds to an anonymous struct or // union. if (const clang::TagType *TagT = @@ -7758,9 +7950,9 @@ clang::FieldDecl *ClangASTContext::AddFieldToRecordType( field = clang::ObjCIvarDecl::Create( *clang_ast, class_interface_decl, clang::SourceLocation(), clang::SourceLocation(), - name ? &clang_ast->Idents.get(name) : nullptr, // Identifier - ClangUtil::GetQualType(field_clang_type), // Field type - nullptr, // TypeSourceInfo * + ident, // Identifier + ClangUtil::GetQualType(field_clang_type), // Field type + nullptr, // TypeSourceInfo * ConvertAccessTypeToObjCIvarAccessControl(access), bit_width, is_synthesized); @@ -7899,38 +8091,44 @@ void ClangASTContext::SetIsPacked(const CompilerType &type) { } clang::VarDecl *ClangASTContext::AddVariableToRecordType( - const CompilerType &type, const char *name, const CompilerType &var_type, - AccessType access) { - clang::VarDecl *var_decl = nullptr; - + const CompilerType &type, llvm::StringRef name, + const CompilerType &var_type, AccessType access) { if (!type.IsValid() || !var_type.IsValid()) return nullptr; + ClangASTContext *ast = llvm::dyn_cast(type.GetTypeSystem()); if (!ast) return nullptr; clang::RecordDecl *record_decl = ast->GetAsRecordDecl(type); - if (record_decl) { - var_decl = clang::VarDecl::Create( - *ast->getASTContext(), // ASTContext & - record_decl, // DeclContext * - clang::SourceLocation(), // clang::SourceLocation StartLoc - clang::SourceLocation(), // clang::SourceLocation IdLoc - name ? &ast->getASTContext()->Idents.get(name) - : nullptr, // clang::IdentifierInfo * - ClangUtil::GetQualType(var_type), // Variable clang::QualType - nullptr, // TypeSourceInfo * - clang::SC_Static); // StorageClass - if (var_decl) { - var_decl->setAccess( - ClangASTContext::ConvertAccessTypeToAccessSpecifier(access)); - record_decl->addDecl(var_decl); + if (!record_decl) + return nullptr; + + clang::VarDecl *var_decl = nullptr; + clang::IdentifierInfo *ident = nullptr; + if (!name.empty()) + ident = &ast->getASTContext()->Idents.get(name); + + var_decl = clang::VarDecl::Create( + *ast->getASTContext(), // ASTContext & + record_decl, // DeclContext * + clang::SourceLocation(), // clang::SourceLocation StartLoc + clang::SourceLocation(), // clang::SourceLocation IdLoc + ident, // clang::IdentifierInfo * + ClangUtil::GetQualType(var_type), // Variable clang::QualType + nullptr, // TypeSourceInfo * + clang::SC_Static); // StorageClass + if (!var_decl) + return nullptr; + + var_decl->setAccess( + ClangASTContext::ConvertAccessTypeToAccessSpecifier(access)); + record_decl->addDecl(var_decl); #ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(var_decl); + VerifyDecl(var_decl); #endif - } - } + return var_decl; } @@ -8131,41 +8329,46 @@ clang::CXXMethodDecl *ClangASTContext::AddMethodToCXXRecordType( return cxx_method_decl; } +void ClangASTContext::AddMethodOverridesForCXXRecordType( + lldb::opaque_compiler_type_t type) { + if (auto *record = GetAsCXXRecordDecl(type)) + for (auto *method : record->methods()) + addOverridesForMethod(method); +} + #pragma mark C++ Base Classes -clang::CXXBaseSpecifier * +std::unique_ptr ClangASTContext::CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type, AccessType access, bool is_virtual, bool base_of_class) { - if (type) - return new clang::CXXBaseSpecifier( - clang::SourceRange(), is_virtual, base_of_class, - ClangASTContext::ConvertAccessTypeToAccessSpecifier(access), - getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)), - clang::SourceLocation()); - return nullptr; + if (!type) + return nullptr; + + return llvm::make_unique( + clang::SourceRange(), is_virtual, base_of_class, + ClangASTContext::ConvertAccessTypeToAccessSpecifier(access), + getASTContext()->getTrivialTypeSourceInfo(GetQualType(type)), + clang::SourceLocation()); } -void ClangASTContext::DeleteBaseClassSpecifiers( - clang::CXXBaseSpecifier **base_classes, unsigned num_base_classes) { - for (unsigned i = 0; i < num_base_classes; ++i) { - delete base_classes[i]; - base_classes[i] = nullptr; - } -} - -bool ClangASTContext::SetBaseClassesForClassType( +bool ClangASTContext::TransferBaseClasses( lldb::opaque_compiler_type_t type, - clang::CXXBaseSpecifier const *const *base_classes, - unsigned num_base_classes) { - if (type) { - clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type); - if (cxx_record_decl) { - cxx_record_decl->setBases(base_classes, num_base_classes); - return true; - } - } - return false; + std::vector> bases) { + if (!type) + return false; + clang::CXXRecordDecl *cxx_record_decl = GetAsCXXRecordDecl(type); + if (!cxx_record_decl) + return false; + std::vector raw_bases; + raw_bases.reserve(bases.size()); + + // Clang will make a copy of them, so it's ok that we pass pointers that we're + // about to destroy. + for (auto &b : bases) + raw_bases.push_back(b.get()); + cxx_record_decl->setBases(raw_bases.data(), raw_bases.size()); + return true; } bool ClangASTContext::SetObjCSuperClass( @@ -8750,44 +8953,63 @@ bool ClangASTContext::CompleteTagDeclarationDefinition( return false; } -bool ClangASTContext::AddEnumerationValueToEnumerationType( - lldb::opaque_compiler_type_t type, - const CompilerType &enumerator_clang_type, const Declaration &decl, - const char *name, int64_t enum_value, uint32_t enum_value_bit_size) { - if (type && enumerator_clang_type.IsValid() && name && name[0]) { - clang::QualType enum_qual_type(GetCanonicalQualType(type)); +clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType( + const CompilerType &enum_type, const Declaration &decl, const char *name, + const llvm::APSInt &value) { - bool is_signed = false; - enumerator_clang_type.IsIntegerType(is_signed); - const clang::Type *clang_type = enum_qual_type.getTypePtr(); - if (clang_type) { - const clang::EnumType *enutype = - llvm::dyn_cast(clang_type); + if (!enum_type || ConstString(name).IsEmpty()) + return nullptr; - if (enutype) { - llvm::APSInt enum_llvm_apsint(enum_value_bit_size, is_signed); - enum_llvm_apsint = enum_value; - clang::EnumConstantDecl *enumerator_decl = - clang::EnumConstantDecl::Create( - *getASTContext(), enutype->getDecl(), clang::SourceLocation(), - name ? &getASTContext()->Idents.get(name) - : nullptr, // Identifier - ClangUtil::GetQualType(enumerator_clang_type), - nullptr, enum_llvm_apsint); + lldbassert(enum_type.GetTypeSystem() == static_cast(this)); - if (enumerator_decl) { - enutype->getDecl()->addDecl(enumerator_decl); + lldb::opaque_compiler_type_t enum_opaque_compiler_type = + enum_type.GetOpaqueQualType(); + + if (!enum_opaque_compiler_type) + return nullptr; + + clang::QualType enum_qual_type( + GetCanonicalQualType(enum_opaque_compiler_type)); + + const clang::Type *clang_type = enum_qual_type.getTypePtr(); + + if (!clang_type) + return nullptr; + + const clang::EnumType *enutype = llvm::dyn_cast(clang_type); + + if (!enutype) + return nullptr; + + clang::EnumConstantDecl *enumerator_decl = clang::EnumConstantDecl::Create( + *getASTContext(), enutype->getDecl(), clang::SourceLocation(), + name ? &getASTContext()->Idents.get(name) : nullptr, // Identifier + clang::QualType(enutype, 0), nullptr, value); + + if (!enumerator_decl) + return nullptr; + + enutype->getDecl()->addDecl(enumerator_decl); #ifdef LLDB_CONFIGURATION_DEBUG - VerifyDecl(enumerator_decl); + VerifyDecl(enumerator_decl); #endif - return true; - } - } - } - } - return false; + return enumerator_decl; +} + +clang::EnumConstantDecl *ClangASTContext::AddEnumerationValueToEnumerationType( + const CompilerType &enum_type, const Declaration &decl, const char *name, + int64_t enum_value, uint32_t enum_value_bit_size) { + CompilerType underlying_type = + GetEnumerationIntegerType(enum_type.GetOpaqueQualType()); + bool is_signed = false; + underlying_type.IsIntegerType(is_signed); + + llvm::APSInt value(enum_value_bit_size, is_signed); + value = enum_value; + + return AddEnumerationValueToEnumerationType(enum_type, decl, name, value); } CompilerType @@ -8861,6 +9083,11 @@ ClangASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, //---------------------------------------------------------------------- #define DEPTH_INCREMENT 2 +void ClangASTContext::Dump(Stream &s) { + Decl *tu = Decl::castFromDeclContext(GetTranslationUnitDecl()); + tu->dump(s.AsRawOstream()); +} + void ClangASTContext::DumpValue( lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, const DataExtractor &data, @@ -8898,8 +9125,7 @@ void ClangASTContext::DumpValue( base_class->getType()->getAs()->getDecl()); // Skip empty base classes - if (verbose == false && - ClangASTContext::RecordHasFields(base_class_decl) == false) + if (!verbose && !ClangASTContext::RecordHasFields(base_class_decl)) continue; if (base_class->isVirtual()) @@ -9672,11 +9898,16 @@ bool ClangASTContext::LayoutRecordType( llvm::DenseMap &vbase_offsets) { ClangASTContext *ast = (ClangASTContext *)baton; - DWARFASTParserClang *dwarf_ast_parser = - (DWARFASTParserClang *)ast->GetDWARFParser(); - return dwarf_ast_parser->GetClangASTImporter().LayoutRecordType( - record_decl, bit_size, alignment, field_offsets, base_offsets, - vbase_offsets); + lldb_private::ClangASTImporter *importer = nullptr; + if (ast->m_dwarf_ast_parser_ap) + importer = &ast->m_dwarf_ast_parser_ap->GetClangASTImporter(); + if (!importer && ast->m_pdb_ast_parser_ap) + importer = &ast->m_pdb_ast_parser_ap->GetClangASTImporter(); + if (!importer) + return false; + + return importer->LayoutRecordType(record_decl, bit_size, alignment, + field_offsets, base_offsets, vbase_offsets); } //---------------------------------------------------------------------- diff --git a/contrib/llvm/tools/lldb/source/Symbol/ClangASTImporter.cpp b/contrib/llvm/tools/lldb/source/Symbol/ClangASTImporter.cpp index ea3b141c9e74..621441449c20 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/ClangASTImporter.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/ClangASTImporter.cpp @@ -1002,7 +1002,7 @@ clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, if (isa(to) || isa(to)) { RecordDecl *from_record_decl = dyn_cast(from); if (from_record_decl == nullptr || - from_record_decl->isInjectedClassName() == false) { + !from_record_decl->isInjectedClassName()) { NamedDecl *to_named_decl = dyn_cast(to); if (!m_decls_already_deported->count(to_named_decl)) @@ -1050,7 +1050,7 @@ clang::Decl *ClangASTImporter::Minion::Imported(clang::Decl *from, TagDecl *to_tag_decl = dyn_cast(to); to_tag_decl->setHasExternalLexicalStorage(); - to_tag_decl->setMustBuildLookupTable(); + to_tag_decl->getPrimaryContext()->setMustBuildLookupTable(); if (log) log->Printf( diff --git a/contrib/llvm/tools/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp b/contrib/llvm/tools/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp index c88119bc9a4c..a96ef19b02f5 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/ClangExternalASTSourceCallbacks.cpp @@ -9,9 +9,6 @@ #include "lldb/Symbol/ClangExternalASTSourceCallbacks.h" -// C Includes -// C++ Includes -// Other libraries and framework includes // Clang headers like to use NDEBUG inside of them to enable/disable debug // related features using "#ifndef NDEBUG" preprocessor blocks to do one thing diff --git a/contrib/llvm/tools/lldb/source/Symbol/ClangUtil.cpp b/contrib/llvm/tools/lldb/source/Symbol/ClangUtil.cpp index 7a67df48ee6a..687fba7c7c33 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/ClangUtil.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/ClangUtil.cpp @@ -48,3 +48,11 @@ CompilerType ClangUtil::RemoveFastQualifiers(const CompilerType &ct) { qual_type.removeLocalFastQualifiers(); return CompilerType(ct.GetTypeSystem(), qual_type.getAsOpaquePtr()); } + +clang::TagDecl *ClangUtil::GetAsTagDecl(const CompilerType &type) { + clang::QualType qual_type = ClangUtil::GetCanonicalQualType(type); + if (qual_type.isNull()) + return nullptr; + + return qual_type->getAsTagDecl(); +} diff --git a/contrib/llvm/tools/lldb/source/Symbol/CompactUnwindInfo.cpp b/contrib/llvm/tools/lldb/source/Symbol/CompactUnwindInfo.cpp index 7dda877582cc..6f0f35f278c4 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/CompactUnwindInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/CompactUnwindInfo.cpp @@ -183,8 +183,7 @@ bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr, if (function_info.encoding == 0) return false; - ArchSpec arch; - if (m_objfile.GetArchitecture(arch)) { + if (ArchSpec arch = m_objfile.GetArchitecture()) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); if (log && log->GetVerbose()) { @@ -204,7 +203,7 @@ bool CompactUnwindInfo::GetUnwindPlan(Target &target, Address addr, if (sl) { addr_t func_range_start_file_addr = function_info.valid_range_offset_start + - m_objfile.GetHeaderAddress().GetFileAddress(); + m_objfile.GetBaseAddress().GetFileAddress(); AddressRange func_range(func_range_start_file_addr, function_info.valid_range_offset_end - function_info.valid_range_offset_start, @@ -259,7 +258,7 @@ void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) { m_objfile.GetModule()->LogMessage( log, "Reading compact unwind first-level indexes"); - if (m_unwindinfo_data_computed == false) { + if (!m_unwindinfo_data_computed) { if (m_section_sp->IsEncrypted()) { // Can't get section contents of a protected/encrypted section until we // have a live process and can read them out of memory. @@ -338,8 +337,7 @@ void CompactUnwindInfo::ScanIndex(const ProcessSP &process_sp) { // }; bool clear_address_zeroth_bit = false; - ArchSpec arch; - if (m_objfile.GetArchitecture(arch)) { + if (ArchSpec arch = m_objfile.GetArchitecture()) { if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb) clear_address_zeroth_bit = true; @@ -513,7 +511,7 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction( return false; addr_t function_offset = - address.GetFileAddress() - m_objfile.GetHeaderAddress().GetFileAddress(); + address.GetFileAddress() - m_objfile.GetBaseAddress().GetFileAddress(); UnwindIndex key; key.function_offset = function_offset; @@ -529,7 +527,7 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction( --it; } - if (it->sentinal_entry == true) { + if (it->sentinal_entry) { return false; } @@ -578,10 +576,10 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction( if (sl) { uint32_t lsda_offset = GetLSDAForFunctionOffset( lsda_array_start, lsda_array_count, function_offset); - addr_t objfile_header_file_address = - m_objfile.GetHeaderAddress().GetFileAddress(); + addr_t objfile_base_address = + m_objfile.GetBaseAddress().GetFileAddress(); unwind_info.lsda_address.ResolveAddressUsingFileSections( - objfile_header_file_address + lsda_offset, sl); + objfile_base_address + lsda_offset, sl); } } if (unwind_info.encoding & UNWIND_PERSONALITY_MASK) { @@ -596,10 +594,10 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction( SectionList *sl = m_objfile.GetSectionList(); if (sl) { uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset); - addr_t objfile_header_file_address = - m_objfile.GetHeaderAddress().GetFileAddress(); + addr_t objfile_base_address = + m_objfile.GetBaseAddress().GetFileAddress(); unwind_info.personality_ptr_address.ResolveAddressUsingFileSections( - objfile_header_file_address + personality_offset, sl); + objfile_base_address + personality_offset, sl); } } } @@ -662,10 +660,10 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction( if (sl) { uint32_t lsda_offset = GetLSDAForFunctionOffset( lsda_array_start, lsda_array_count, function_offset); - addr_t objfile_header_file_address = - m_objfile.GetHeaderAddress().GetFileAddress(); + addr_t objfile_base_address = + m_objfile.GetBaseAddress().GetFileAddress(); unwind_info.lsda_address.ResolveAddressUsingFileSections( - objfile_header_file_address + lsda_offset, sl); + objfile_base_address + lsda_offset, sl); } } if (unwind_info.encoding & UNWIND_PERSONALITY_MASK) { @@ -680,10 +678,10 @@ bool CompactUnwindInfo::GetCompactUnwindInfoForFunction( SectionList *sl = m_objfile.GetSectionList(); if (sl) { uint32_t personality_offset = m_unwindinfo_data.GetU32(&offset); - addr_t objfile_header_file_address = - m_objfile.GetHeaderAddress().GetFileAddress(); + addr_t objfile_base_address = + m_objfile.GetBaseAddress().GetFileAddress(); unwind_info.personality_ptr_address.ResolveAddressUsingFileSections( - objfile_header_file_address + personality_offset, sl); + objfile_base_address + personality_offset, sl); } } } @@ -925,7 +923,7 @@ bool CompactUnwindInfo::CreateUnwindPlan_x86_64(Target &target, for (uint32_t i = 0; i < register_count; i++) { int renum = 0; for (int j = 1; j < 7; j++) { - if (used[j] == false) { + if (!used[j]) { if (renum == permunreg[i]) { registers[i] = j; used[j] = true; @@ -1187,7 +1185,7 @@ bool CompactUnwindInfo::CreateUnwindPlan_i386(Target &target, for (uint32_t i = 0; i < register_count; i++) { int renum = 0; for (int j = 1; j < 7; j++) { - if (used[j] == false) { + if (!used[j]) { if (renum == permunreg[i]) { registers[i] = j; used[j] = true; diff --git a/contrib/llvm/tools/lldb/source/Symbol/CompileUnit.cpp b/contrib/llvm/tools/lldb/source/Symbol/CompileUnit.cpp index a4f0d4231e2f..74512c891440 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/CompileUnit.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/CompileUnit.cpp @@ -21,8 +21,8 @@ CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, const lldb::user_id_t cu_sym_id, lldb::LanguageType language, lldb_private::LazyBool is_optimized) - : ModuleChild(module_sp), FileSpec(pathname, false), UserID(cu_sym_id), - m_user_data(user_data), m_language(language), m_flags(0), m_functions(), + : ModuleChild(module_sp), FileSpec(pathname), UserID(cu_sym_id), + m_user_data(user_data), m_language(language), m_flags(0), m_support_files(), m_line_table_ap(), m_variables(), m_is_optimized(is_optimized) { if (language != eLanguageTypeUnknown) @@ -35,7 +35,7 @@ CompileUnit::CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, lldb::LanguageType language, lldb_private::LazyBool is_optimized) : ModuleChild(module_sp), FileSpec(fspec), UserID(cu_sym_id), - m_user_data(user_data), m_language(language), m_flags(0), m_functions(), + m_user_data(user_data), m_language(language), m_flags(0), m_support_files(), m_line_table_ap(), m_variables(), m_is_optimized(is_optimized) { if (language != eLanguageTypeUnknown) @@ -66,6 +66,22 @@ void CompileUnit::GetDescription(Stream *s, << (const FileSpec &)*this << "\", language = \"" << language << '"'; } +void CompileUnit::ForeachFunction( + llvm::function_ref lambda) const { + std::vector sorted_functions; + sorted_functions.reserve(m_functions_by_uid.size()); + for (auto &p : m_functions_by_uid) + sorted_functions.push_back(p.second); + llvm::sort(sorted_functions.begin(), sorted_functions.end(), + [](const lldb::FunctionSP &a, const lldb::FunctionSP &b) { + return a->GetID() < b->GetID(); + }); + + for (auto &f : sorted_functions) + if (lambda(f)) + return; +} + //---------------------------------------------------------------------- // Dump the current contents of this object. No functions that cause on demand // parsing of functions, globals, statics are called, so this is a good @@ -89,13 +105,12 @@ void CompileUnit::Dump(Stream *s, bool show_context) const { s->IndentLess(); } - if (!m_functions.empty()) { + if (!m_functions_by_uid.empty()) { s->IndentMore(); - std::vector::const_iterator pos; - std::vector::const_iterator end = m_functions.end(); - for (pos = m_functions.begin(); pos != end; ++pos) { - (*pos)->Dump(s, show_context); - } + ForeachFunction([&s, show_context](const FunctionSP &f) { + f->Dump(s, show_context); + return false; + }); s->IndentLess(); s->EOL(); @@ -106,15 +121,7 @@ void CompileUnit::Dump(Stream *s, bool show_context) const { // Add a function to this compile unit //---------------------------------------------------------------------- void CompileUnit::AddFunction(FunctionSP &funcSP) { - // TODO: order these by address - m_functions.push_back(funcSP); -} - -FunctionSP CompileUnit::GetFunctionAtIndex(size_t idx) { - FunctionSP funcSP; - if (idx < m_functions.size()) - funcSP = m_functions[idx]; - return funcSP; + m_functions_by_uid[funcSP->GetID()] = funcSP; } //---------------------------------------------------------------------- @@ -163,18 +170,10 @@ FunctionSP CompileUnit::GetFunctionAtIndex(size_t idx) { //} FunctionSP CompileUnit::FindFunctionByUID(lldb::user_id_t func_uid) { - FunctionSP funcSP; - if (!m_functions.empty()) { - std::vector::const_iterator pos; - std::vector::const_iterator end = m_functions.end(); - for (pos = m_functions.begin(); pos != end; ++pos) { - if ((*pos)->GetID() == func_uid) { - funcSP = *pos; - break; - } - } - } - return funcSP; + auto it = m_functions_by_uid.find(func_uid); + if (it == m_functions_by_uid.end()) + return FunctionSP(); + return it->second; } lldb::LanguageType CompileUnit::GetLanguage() { @@ -183,9 +182,7 @@ lldb::LanguageType CompileUnit::GetLanguage() { m_flags.Set(flagsParsedLanguage); SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); if (symbol_vendor) { - SymbolContext sc; - CalculateSymbolContext(&sc); - m_language = symbol_vendor->ParseCompileUnitLanguage(sc); + m_language = symbol_vendor->ParseLanguage(*this); } } } @@ -197,11 +194,8 @@ LineTable *CompileUnit::GetLineTable() { if (m_flags.IsClear(flagsParsedLineTable)) { m_flags.Set(flagsParsedLineTable); SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); - if (symbol_vendor) { - SymbolContext sc; - CalculateSymbolContext(&sc); - symbol_vendor->ParseCompileUnitLineTable(sc); - } + if (symbol_vendor) + symbol_vendor->ParseLineTable(*this); } } return m_line_table_ap.get(); @@ -221,9 +215,7 @@ DebugMacros *CompileUnit::GetDebugMacros() { m_flags.Set(flagsParsedDebugMacros); SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); if (symbol_vendor) { - SymbolContext sc; - CalculateSymbolContext(&sc); - symbol_vendor->ParseCompileUnitDebugMacros(sc); + symbol_vendor->ParseDebugMacros(*this); } } } @@ -279,7 +271,8 @@ uint32_t CompileUnit::FindLineEntry(uint32_t start_idx, uint32_t line, uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, bool check_inlines, - bool exact, uint32_t resolve_scope, + bool exact, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { // First find all of the file indexes that match our "file_spec". If // "file_spec" has an empty directory, then only compare the basenames when @@ -291,7 +284,7 @@ uint32_t CompileUnit::ResolveSymbolContext(const FileSpec &file_spec, // If we are not looking for inlined functions and our file spec doesn't // match then we are done... - if (file_spec_matches_cu_file_spec == false && check_inlines == false) + if (!file_spec_matches_cu_file_spec && !check_inlines) return 0; uint32_t file_idx = @@ -387,9 +380,7 @@ bool CompileUnit::GetIsOptimized() { if (m_is_optimized == eLazyBoolCalculate) { m_is_optimized = eLazyBoolNo; if (SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor()) { - SymbolContext sc; - CalculateSymbolContext(&sc); - if (symbol_vendor->ParseCompileUnitIsOptimized(sc)) + if (symbol_vendor->ParseIsOptimized(*this)) m_is_optimized = eLazyBoolYes; } } @@ -419,9 +410,7 @@ FileSpecList &CompileUnit::GetSupportFiles() { m_flags.Set(flagsParsedSupportFiles); SymbolVendor *symbol_vendor = GetModule()->GetSymbolVendor(); if (symbol_vendor) { - SymbolContext sc; - CalculateSymbolContext(&sc); - symbol_vendor->ParseCompileUnitSupportFiles(sc, m_support_files); + symbol_vendor->ParseSupportFiles(*this, m_support_files); } } } diff --git a/contrib/llvm/tools/lldb/source/Symbol/CompilerType.cpp b/contrib/llvm/tools/lldb/source/Symbol/CompilerType.cpp index 2dd1d3ebd04b..7e381abd7d11 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/CompilerType.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/CompilerType.cpp @@ -10,7 +10,6 @@ #include "lldb/Symbol/CompilerType.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/StreamFile.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/ClangExternalASTSourceCommon.h" @@ -20,6 +19,7 @@ #include "lldb/Utility/ConstString.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" @@ -504,15 +504,18 @@ CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const { // Exploring the type //---------------------------------------------------------------------- -uint64_t CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const { - if (IsValid()) { +llvm::Optional +CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const { + if (IsValid()) return m_type_system->GetBitSize(m_type, exe_scope); - } - return 0; + return {}; } -uint64_t CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const { - return (GetBitSize(exe_scope) + 7) / 8; +llvm::Optional +CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const { + if (llvm::Optional bit_size = GetBitSize(exe_scope)) + return (*bit_size + 7) / 8; + return {}; } size_t CompilerType::GetTypeBitAlign() const { @@ -535,10 +538,12 @@ lldb::Format CompilerType::GetFormat() const { return m_type_system->GetFormat(m_type); } -uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes) const { +uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes, + const ExecutionContext *exe_ctx) const { if (!IsValid()) return 0; - return m_type_system->GetNumChildren(m_type, omit_empty_base_classes); + return m_type_system->GetNumChildren(m_type, omit_empty_base_classes, + exe_ctx); } lldb::BasicType CompilerType::GetBasicTypeEnumeration() const { @@ -814,7 +819,9 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, if (encoding == lldb::eEncodingInvalid || count != 1) return false; - const uint64_t byte_size = GetByteSize(nullptr); + llvm::Optional byte_size = GetByteSize(nullptr); + if (!byte_size) + return false; lldb::offset_t offset = data_byte_offset; switch (encoding) { case lldb::eEncodingInvalid: @@ -822,15 +829,15 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, case lldb::eEncodingVector: break; case lldb::eEncodingUint: - if (byte_size <= sizeof(unsigned long long)) { - uint64_t uval64 = data.GetMaxU64(&offset, byte_size); - if (byte_size <= sizeof(unsigned int)) { + if (*byte_size <= sizeof(unsigned long long)) { + uint64_t uval64 = data.GetMaxU64(&offset, *byte_size); + if (*byte_size <= sizeof(unsigned int)) { value = (unsigned int)uval64; return true; - } else if (byte_size <= sizeof(unsigned long)) { + } else if (*byte_size <= sizeof(unsigned long)) { value = (unsigned long)uval64; return true; - } else if (byte_size <= sizeof(unsigned long long)) { + } else if (*byte_size <= sizeof(unsigned long long)) { value = (unsigned long long)uval64; return true; } else @@ -839,15 +846,15 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, break; case lldb::eEncodingSint: - if (byte_size <= sizeof(long long)) { - int64_t sval64 = data.GetMaxS64(&offset, byte_size); - if (byte_size <= sizeof(int)) { + if (*byte_size <= sizeof(long long)) { + int64_t sval64 = data.GetMaxS64(&offset, *byte_size); + if (*byte_size <= sizeof(int)) { value = (int)sval64; return true; - } else if (byte_size <= sizeof(long)) { + } else if (*byte_size <= sizeof(long)) { value = (long)sval64; return true; - } else if (byte_size <= sizeof(long long)) { + } else if (*byte_size <= sizeof(long long)) { value = (long long)sval64; return true; } else @@ -856,10 +863,10 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, break; case lldb::eEncodingIEEE754: - if (byte_size <= sizeof(long double)) { + if (*byte_size <= sizeof(long double)) { uint32_t u32; uint64_t u64; - if (byte_size == sizeof(float)) { + if (*byte_size == sizeof(float)) { if (sizeof(float) == sizeof(uint32_t)) { u32 = data.GetU32(&offset); value = *((float *)&u32); @@ -869,7 +876,7 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, value = *((float *)&u64); return true; } - } else if (byte_size == sizeof(double)) { + } else if (*byte_size == sizeof(double)) { if (sizeof(double) == sizeof(uint32_t)) { u32 = data.GetU32(&offset); value = *((double *)&u32); @@ -879,7 +886,7 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data, value = *((double *)&u64); return true; } - } else if (byte_size == sizeof(long double)) { + } else if (*byte_size == sizeof(long double)) { if (sizeof(long double) == sizeof(uint32_t)) { u32 = data.GetU32(&offset); value = *((long double *)&u32); @@ -910,12 +917,15 @@ bool CompilerType::SetValueFromScalar(const Scalar &value, Stream &strm) { if (encoding == lldb::eEncodingInvalid || count != 1) return false; - const uint64_t bit_width = GetBitSize(nullptr); - // This function doesn't currently handle non-byte aligned assignments - if ((bit_width % 8) != 0) + llvm::Optional bit_width = GetBitSize(nullptr); + if (!bit_width) return false; - const uint64_t byte_size = (bit_width + 7) / 8; + // This function doesn't currently handle non-byte aligned assignments + if ((*bit_width % 8) != 0) + return false; + + const uint64_t byte_size = (*bit_width + 7) / 8; switch (encoding) { case lldb::eEncodingInvalid: break; @@ -992,20 +1002,23 @@ bool CompilerType::ReadFromMemory(lldb_private::ExecutionContext *exe_ctx, if (!GetCompleteType()) return false; - const uint64_t byte_size = + auto byte_size = GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - if (data.GetByteSize() < byte_size) { - lldb::DataBufferSP data_sp(new DataBufferHeap(byte_size, '\0')); + if (!byte_size) + return false; + + if (data.GetByteSize() < *byte_size) { + lldb::DataBufferSP data_sp(new DataBufferHeap(*byte_size, '\0')); data.SetData(data_sp); } - uint8_t *dst = const_cast(data.PeekData(0, byte_size)); + uint8_t *dst = const_cast(data.PeekData(0, *byte_size)); if (dst != nullptr) { if (address_type == eAddressTypeHost) { if (addr == 0) return false; // The address is an address in this process, so just copy it - memcpy(dst, reinterpret_cast(addr), byte_size); + memcpy(dst, reinterpret_cast(addr), *byte_size); return true; } else { Process *process = nullptr; @@ -1013,7 +1026,7 @@ bool CompilerType::ReadFromMemory(lldb_private::ExecutionContext *exe_ctx, process = exe_ctx->GetProcessPtr(); if (process) { Status error; - return process->ReadMemory(addr, dst, byte_size, error) == byte_size; + return process->ReadMemory(addr, dst, *byte_size, error) == *byte_size; } } } @@ -1034,13 +1047,15 @@ bool CompilerType::WriteToMemory(lldb_private::ExecutionContext *exe_ctx, if (!GetCompleteType()) return false; - const uint64_t byte_size = + auto byte_size = GetByteSize(exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); + if (!byte_size) + return false; - if (byte_size > 0) { + if (*byte_size > 0) { if (address_type == eAddressTypeHost) { // The address is an address in this process, so just copy it - memcpy((void *)addr, new_value.GetData(), byte_size); + memcpy((void *)addr, new_value.GetData(), *byte_size); return true; } else { Process *process = nullptr; @@ -1048,24 +1063,14 @@ bool CompilerType::WriteToMemory(lldb_private::ExecutionContext *exe_ctx, process = exe_ctx->GetProcessPtr(); if (process) { Status error; - return process->WriteMemory(addr, new_value.GetData(), byte_size, - error) == byte_size; + return process->WriteMemory(addr, new_value.GetData(), *byte_size, + error) == *byte_size; } } } return false; } -// clang::CXXRecordDecl * -// CompilerType::GetAsCXXRecordDecl (lldb::opaque_compiler_type_t -// opaque_compiler_qual_type) -//{ -// if (opaque_compiler_qual_type) -// return -// clang::QualType::getFromOpaquePtr(opaque_compiler_qual_type)->getAsCXXRecordDecl(); -// return NULL; -//} - bool lldb_private::operator==(const lldb_private::CompilerType &lhs, const lldb_private::CompilerType &rhs) { return lhs.GetTypeSystem() == rhs.GetTypeSystem() && @@ -1074,6 +1079,5 @@ bool lldb_private::operator==(const lldb_private::CompilerType &lhs, bool lldb_private::operator!=(const lldb_private::CompilerType &lhs, const lldb_private::CompilerType &rhs) { - return lhs.GetTypeSystem() != rhs.GetTypeSystem() || - lhs.GetOpaqueQualType() != rhs.GetOpaqueQualType(); + return !(lhs == rhs); } diff --git a/contrib/llvm/tools/lldb/source/Symbol/DWARFCallFrameInfo.cpp b/contrib/llvm/tools/lldb/source/Symbol/DWARFCallFrameInfo.cpp index 1bf9ff99e015..c8c3a10026a2 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/DWARFCallFrameInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/DWARFCallFrameInfo.cpp @@ -161,7 +161,7 @@ bool DWARFCallFrameInfo::GetUnwindPlan(Address addr, UnwindPlan &unwind_plan) { module_sp->GetObjectFile() != &m_objfile) return false; - if (GetFDEEntryByFileAddress(addr.GetFileAddress(), fde_entry) == false) + if (!GetFDEEntryByFileAddress(addr.GetFileAddress(), fde_entry)) return false; return FDEToUnwindPlan(fde_entry.data, addr, unwind_plan); } @@ -243,7 +243,7 @@ DWARFCallFrameInfo::CIESP DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) { CIESP cie_sp(new CIE(cie_offset)); lldb::offset_t offset = cie_offset; - if (m_cfi_data_initialized == false) + if (!m_cfi_data_initialized) GetCFIData(); uint32_t length = m_cfi_data.GetU32(&offset); dw_offset_t cie_id, end_offset; @@ -394,7 +394,7 @@ DWARFCallFrameInfo::ParseCIE(const dw_offset_t cie_offset) { } void DWARFCallFrameInfo::GetCFIData() { - if (m_cfi_data_initialized == false) { + if (!m_cfi_data_initialized) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); if (log) m_objfile.GetModule()->LogMessage(log, "Reading EH frame info"); @@ -423,15 +423,14 @@ void DWARFCallFrameInfo::GetFDEIndex() { m_objfile.GetFileSpec().GetFilename().AsCString("")); bool clear_address_zeroth_bit = false; - ArchSpec arch; - if (m_objfile.GetArchitecture(arch)) { + if (ArchSpec arch = m_objfile.GetArchitecture()) { if (arch.GetTriple().getArch() == llvm::Triple::arm || arch.GetTriple().getArch() == llvm::Triple::thumb) clear_address_zeroth_bit = true; } lldb::offset_t offset = 0; - if (m_cfi_data_initialized == false) + if (!m_cfi_data_initialized) GetCFIData(); while (m_cfi_data.ValidOffsetForDataOfSize(offset, 8)) { const dw_offset_t current_entry = offset; @@ -533,7 +532,7 @@ bool DWARFCallFrameInfo::FDEToUnwindPlan(dw_offset_t dwarf_offset, if (m_section_sp.get() == nullptr || m_section_sp->IsEncrypted()) return false; - if (m_cfi_data_initialized == false) + if (!m_cfi_data_initialized) GetCFIData(); uint32_t length = m_cfi_data.GetU32(&offset); diff --git a/contrib/llvm/tools/lldb/source/Symbol/FuncUnwinders.cpp b/contrib/llvm/tools/lldb/source/Symbol/FuncUnwinders.cpp index 2384d35e3d36..35ce72f32b61 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/FuncUnwinders.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/FuncUnwinders.cpp @@ -255,7 +255,7 @@ UnwindPlanSP FuncUnwinders::GetAssemblyUnwindPlan(Target &target, int current_offset) { std::lock_guard guard(m_mutex); if (m_unwind_plan_assembly_sp.get() || m_tried_unwind_plan_assembly || - m_unwind_table.GetAllowAssemblyEmulationUnwindPlans() == false) { + !m_unwind_table.GetAllowAssemblyEmulationUnwindPlans()) { return m_unwind_plan_assembly_sp; } @@ -443,8 +443,7 @@ const Address &FuncUnwinders::GetFunctionStartAddress() const { lldb::UnwindAssemblySP FuncUnwinders::GetUnwindAssemblyProfiler(Target &target) { UnwindAssemblySP assembly_profiler_sp; - ArchSpec arch; - if (m_unwind_table.GetArchitecture(arch)) { + if (ArchSpec arch = m_unwind_table.GetArchitecture()) { arch.MergeFrom(target.GetArchitecture()); assembly_profiler_sp = UnwindAssembly::FindPlugin(arch); } diff --git a/contrib/llvm/tools/lldb/source/Symbol/Function.cpp b/contrib/llvm/tools/lldb/source/Symbol/Function.cpp index f642c186a19f..f792a5c5213e 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/Function.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/Function.cpp @@ -10,6 +10,7 @@ #include "lldb/Symbol/Function.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" #include "lldb/Core/Section.h" #include "lldb/Host/Host.h" #include "lldb/Symbol/CompileUnit.h" @@ -18,6 +19,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Target/Language.h" +#include "lldb/Utility/Log.h" #include "llvm/Support/Casting.h" using namespace lldb; @@ -128,6 +130,59 @@ size_t InlineFunctionInfo::MemorySize() const { return FunctionInfo::MemorySize() + m_mangled.MemorySize(); } +//---------------------------------------------------------------------- +// +//---------------------------------------------------------------------- +CallEdge::CallEdge(const char *symbol_name, lldb::addr_t return_pc) + : return_pc(return_pc), resolved(false) { + lazy_callee.symbol_name = symbol_name; +} + +void CallEdge::ParseSymbolFileAndResolve(ModuleList &images) { + if (resolved) + return; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + LLDB_LOG(log, "CallEdge: Lazily parsing the call graph for {0}", + lazy_callee.symbol_name); + + auto resolve_lazy_callee = [&]() -> Function * { + ConstString callee_name{lazy_callee.symbol_name}; + SymbolContextList sc_list; + size_t num_matches = + images.FindFunctionSymbols(callee_name, eFunctionNameTypeAuto, sc_list); + if (num_matches == 0 || !sc_list[0].symbol) { + LLDB_LOG(log, "CallEdge: Found no symbols for {0}, cannot resolve it", + callee_name); + return nullptr; + } + Address callee_addr = sc_list[0].symbol->GetAddress(); + if (!callee_addr.IsValid()) { + LLDB_LOG(log, "CallEdge: Invalid symbol address"); + return nullptr; + } + Function *f = callee_addr.CalculateSymbolContextFunction(); + if (!f) { + LLDB_LOG(log, "CallEdge: Could not find complete function"); + return nullptr; + } + return f; + }; + lazy_callee.def = resolve_lazy_callee(); + resolved = true; +} + +Function *CallEdge::GetCallee(ModuleList &images) { + ParseSymbolFileAndResolve(images); + return lazy_callee.def; +} + +lldb::addr_t CallEdge::GetReturnPCAddress(Function &caller, + Target &target) const { + const Address &base = caller.GetAddressRange().GetBaseAddress(); + return base.GetLoadAddress(&target) + return_pc; +} + //---------------------------------------------------------------------- // //---------------------------------------------------------------------- @@ -141,17 +196,6 @@ Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, assert(comp_unit != nullptr); } -Function::Function(CompileUnit *comp_unit, lldb::user_id_t func_uid, - lldb::user_id_t type_uid, const char *mangled, Type *type, - const AddressRange &range) - : UserID(func_uid), m_comp_unit(comp_unit), m_type_uid(type_uid), - m_type(type), m_mangled(ConstString(mangled), true), m_block(func_uid), - m_range(range), m_frame_base(nullptr), m_flags(), - m_prologue_byte_size(0) { - m_block.SetParentScope(this); - assert(comp_unit != nullptr); -} - Function::~Function() {} void Function::GetStartLineSourceInfo(FileSpec &source_file, @@ -203,16 +247,53 @@ void Function::GetEndLineSourceInfo(FileSpec &source_file, uint32_t &line_no) { } } +llvm::MutableArrayRef Function::GetCallEdges() { + if (m_call_edges_resolved) + return m_call_edges; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + LLDB_LOG(log, "GetCallEdges: Attempting to parse call site info for {0}", + GetDisplayName()); + + m_call_edges_resolved = true; + + // Find the SymbolFile which provided this function's definition. + Block &block = GetBlock(/*can_create*/true); + SymbolFile *sym_file = block.GetSymbolFile(); + if (!sym_file) + return llvm::None; + + // Lazily read call site information from the SymbolFile. + m_call_edges = sym_file->ParseCallEdgesInFunction(GetID()); + + // Sort the call edges to speed up return_pc lookups. + llvm::sort(m_call_edges.begin(), m_call_edges.end(), + [](const CallEdge &LHS, const CallEdge &RHS) { + return LHS.GetUnresolvedReturnPCAddress() < + RHS.GetUnresolvedReturnPCAddress(); + }); + + return m_call_edges; +} + +llvm::MutableArrayRef Function::GetTailCallingEdges() { + // Call edges are sorted by return PC, and tail calling edges have invalid + // return PCs. Find them at the end of the list. + return GetCallEdges().drop_until([](const CallEdge &edge) { + return edge.GetUnresolvedReturnPCAddress() == LLDB_INVALID_ADDRESS; + }); +} + Block &Function::GetBlock(bool can_create) { if (!m_block.BlockInfoHasBeenParsed() && can_create) { - SymbolContext sc; - CalculateSymbolContext(&sc); - if (sc.module_sp) { - sc.module_sp->GetSymbolVendor()->ParseFunctionBlocks(sc); + ModuleSP module_sp = CalculateSymbolContextModule(); + if (module_sp) { + module_sp->GetSymbolVendor()->ParseBlocksRecursive(*this); } else { - Host::SystemLog(Host::eSystemLogError, "error: unable to find module " - "shared pointer for function '%s' " - "in %s\n", + Host::SystemLog(Host::eSystemLogError, + "error: unable to find module " + "shared pointer for function '%s' " + "in %s\n", GetName().GetCString(), m_comp_unit->GetPath().c_str()); } m_block.SetBlockInfoHasBeenParsed(true, true); diff --git a/contrib/llvm/tools/lldb/source/Symbol/GoASTContext.cpp b/contrib/llvm/tools/lldb/source/Symbol/GoASTContext.cpp deleted file mode 100644 index da5c82b2cb55..000000000000 --- a/contrib/llvm/tools/lldb/source/Symbol/GoASTContext.cpp +++ /dev/null @@ -1,1444 +0,0 @@ -//===-- GoASTContext.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include -#include -#include - -#include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/UniqueCStringMap.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/GoASTContext.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Target.h" - -#include "llvm/Support/Threading.h" - -#include "Plugins/ExpressionParser/Go/GoUserExpression.h" -#include "Plugins/SymbolFile/DWARF/DWARFASTParserGo.h" - -using namespace lldb; - -namespace lldb_private { -class GoArray; -class GoFunction; -class GoStruct; - -class GoType { -public: - enum { - KIND_BOOL = 1, - KIND_INT = 2, - KIND_INT8 = 3, - KIND_INT16 = 4, - KIND_INT32 = 5, - KIND_INT64 = 6, - KIND_UINT = 7, - KIND_UINT8 = 8, - KIND_UINT16 = 9, - KIND_UINT32 = 10, - KIND_UINT64 = 11, - KIND_UINTPTR = 12, - KIND_FLOAT32 = 13, - KIND_FLOAT64 = 14, - KIND_COMPLEX64 = 15, - KIND_COMPLEX128 = 16, - KIND_ARRAY = 17, - KIND_CHAN = 18, - KIND_FUNC = 19, - KIND_INTERFACE = 20, - KIND_MAP = 21, - KIND_PTR = 22, - KIND_SLICE = 23, - KIND_STRING = 24, - KIND_STRUCT = 25, - KIND_UNSAFEPOINTER = 26, - KIND_LLDB_VOID, // Extension for LLDB, not used by go runtime. - KIND_MASK = (1 << 5) - 1, - KIND_DIRECT_IFACE = 1 << 5 - }; - GoType(int kind, const ConstString &name) - : m_kind(kind & KIND_MASK), m_name(name) { - if (m_kind == KIND_FUNC) - m_kind = KIND_FUNC; - } - virtual ~GoType() {} - - int GetGoKind() const { return m_kind; } - const ConstString &GetName() const { return m_name; } - virtual CompilerType GetElementType() const { return CompilerType(); } - - bool IsTypedef() const { - switch (m_kind) { - case KIND_CHAN: - case KIND_MAP: - case KIND_INTERFACE: - return true; - default: - return false; - } - } - - GoArray *GetArray(); - GoFunction *GetFunction(); - GoStruct *GetStruct(); - -private: - int m_kind; - ConstString m_name; - GoType(const GoType &) = delete; - const GoType &operator=(const GoType &) = delete; -}; - -class GoElem : public GoType { -public: - GoElem(int kind, const ConstString &name, const CompilerType &elem) - : GoType(kind, name), m_elem(elem) {} - virtual CompilerType GetElementType() const { return m_elem; } - -private: - // TODO: should we store this differently? - CompilerType m_elem; - - GoElem(const GoElem &) = delete; - const GoElem &operator=(const GoElem &) = delete; -}; - -class GoArray : public GoElem { -public: - GoArray(const ConstString &name, uint64_t length, const CompilerType &elem) - : GoElem(KIND_ARRAY, name, elem), m_length(length) {} - - uint64_t GetLength() const { return m_length; } - -private: - uint64_t m_length; - GoArray(const GoArray &) = delete; - const GoArray &operator=(const GoArray &) = delete; -}; - -class GoFunction : public GoType { -public: - GoFunction(const ConstString &name, bool is_variadic) - : GoType(KIND_FUNC, name), m_is_variadic(is_variadic) {} - - bool IsVariadic() const { return m_is_variadic; } - -private: - bool m_is_variadic; - GoFunction(const GoFunction &) = delete; - const GoFunction &operator=(const GoFunction &) = delete; -}; - -class GoStruct : public GoType { -public: - struct Field { - Field(const ConstString &name, const CompilerType &type, uint64_t offset) - : m_name(name), m_type(type), m_byte_offset(offset) {} - ConstString m_name; - CompilerType m_type; - uint64_t m_byte_offset; - }; - - GoStruct(int kind, const ConstString &name, int64_t byte_size) - : GoType(kind == 0 ? KIND_STRUCT : kind, name), m_is_complete(false), - m_byte_size(byte_size) {} - - uint32_t GetNumFields() const { return m_fields.size(); } - - const Field *GetField(uint32_t i) const { - if (i < m_fields.size()) - return &m_fields[i]; - return nullptr; - } - - void AddField(const ConstString &name, const CompilerType &type, - uint64_t offset) { - m_fields.push_back(Field(name, type, offset)); - } - - bool IsComplete() const { return m_is_complete; } - - void SetComplete() { m_is_complete = true; } - - int64_t GetByteSize() const { return m_byte_size; } - -private: - bool m_is_complete; - int64_t m_byte_size; - std::vector m_fields; - - GoStruct(const GoStruct &) = delete; - const GoStruct &operator=(const GoStruct &) = delete; -}; - -GoArray *GoType::GetArray() { - if (m_kind == KIND_ARRAY) { - return static_cast(this); - } - return nullptr; -} - -GoFunction *GoType::GetFunction() { - if (m_kind == KIND_FUNC) { - return static_cast(this); - } - return nullptr; -} - -GoStruct *GoType::GetStruct() { - switch (m_kind) { - case KIND_STRING: - case KIND_STRUCT: - case KIND_SLICE: - return static_cast(this); - } - return nullptr; -} -} // namespace lldb_private -using namespace lldb_private; - -GoASTContext::GoASTContext() - : TypeSystem(eKindGo), m_pointer_byte_size(0), m_int_byte_size(0), - m_types(new TypeMap) {} -GoASTContext::~GoASTContext() {} - -//------------------------------------------------------------------ -// PluginInterface functions -//------------------------------------------------------------------ - -ConstString GoASTContext::GetPluginNameStatic() { return ConstString("go"); } - -ConstString GoASTContext::GetPluginName() { - return GoASTContext::GetPluginNameStatic(); -} - -uint32_t GoASTContext::GetPluginVersion() { return 1; } - -lldb::TypeSystemSP GoASTContext::CreateInstance(lldb::LanguageType language, - Module *module, - Target *target) { - if (language == eLanguageTypeGo) { - ArchSpec arch; - std::shared_ptr go_ast_sp; - if (module) { - arch = module->GetArchitecture(); - go_ast_sp = std::shared_ptr(new GoASTContext); - } else if (target) { - arch = target->GetArchitecture(); - go_ast_sp = std::shared_ptr( - new GoASTContextForExpr(target->shared_from_this())); - } - - if (arch.IsValid()) { - go_ast_sp->SetAddressByteSize(arch.GetAddressByteSize()); - return go_ast_sp; - } - } - return lldb::TypeSystemSP(); -} - -void GoASTContext::EnumerateSupportedLanguages( - std::set &languages_for_types, - std::set &languages_for_expressions) { - static std::vector s_supported_languages_for_types( - {lldb::eLanguageTypeGo}); - - static std::vector s_supported_languages_for_expressions( - {}); - - languages_for_types.insert(s_supported_languages_for_types.begin(), - s_supported_languages_for_types.end()); - languages_for_expressions.insert( - s_supported_languages_for_expressions.begin(), - s_supported_languages_for_expressions.end()); -} - -void GoASTContext::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in", - CreateInstance, EnumerateSupportedLanguages); -} - -void GoASTContext::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -//---------------------------------------------------------------------- -// Tests -//---------------------------------------------------------------------- - -bool GoASTContext::IsArrayType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size, - bool *is_incomplete) { - if (element_type) - element_type->Clear(); - if (size) - *size = 0; - if (is_incomplete) - *is_incomplete = false; - GoArray *array = static_cast(type)->GetArray(); - if (array) { - if (size) - *size = array->GetLength(); - if (element_type) - *element_type = array->GetElementType(); - return true; - } - return false; -} - -bool GoASTContext::IsVectorType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size) { - if (element_type) - element_type->Clear(); - if (size) - *size = 0; - return false; -} - -bool GoASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) { - int kind = static_cast(type)->GetGoKind(); - if (kind < GoType::KIND_ARRAY) - return false; - if (kind == GoType::KIND_PTR) - return false; - if (kind == GoType::KIND_CHAN) - return false; - if (kind == GoType::KIND_MAP) - return false; - if (kind == GoType::KIND_STRING) - return false; - if (kind == GoType::KIND_UNSAFEPOINTER) - return false; - return true; -} - -bool GoASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) { - return false; -} - -bool GoASTContext::IsCharType(lldb::opaque_compiler_type_t type) { - // Go's DWARF doesn't distinguish between rune and int32. - return false; -} - -bool GoASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) { - if (!type) - return false; - GoType *t = static_cast(type); - if (GoStruct *s = t->GetStruct()) - return s->IsComplete(); - if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR) - return t->GetElementType().IsCompleteType(); - return true; -} - -bool GoASTContext::IsConst(lldb::opaque_compiler_type_t type) { return false; } - -bool GoASTContext::IsCStringType(lldb::opaque_compiler_type_t type, - uint32_t &length) { - return false; -} - -bool GoASTContext::IsDefined(lldb::opaque_compiler_type_t type) { - return type != nullptr; -} - -bool GoASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, - uint32_t &count, bool &is_complex) { - int kind = static_cast(type)->GetGoKind(); - if (kind >= GoType::KIND_FLOAT32 && kind <= GoType::KIND_COMPLEX128) { - if (kind >= GoType::KIND_COMPLEX64) { - is_complex = true; - count = 2; - } else { - is_complex = false; - count = 1; - } - return true; - } - count = 0; - is_complex = false; - return false; -} - -bool GoASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, - bool *is_variadic_ptr) { - GoFunction *func = static_cast(type)->GetFunction(); - if (func) { - if (is_variadic_ptr) - *is_variadic_ptr = func->IsVariadic(); - return true; - } - if (is_variadic_ptr) - *is_variadic_ptr = false; - return false; -} - -uint32_t GoASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, - CompilerType *base_type_ptr) { - return false; -} - -size_t -GoASTContext::GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) { - return 0; -} - -CompilerType -GoASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, - const size_t index) { - return CompilerType(); -} - -bool GoASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { - return IsFunctionType(type); -} - -bool GoASTContext::IsBlockPointerType(lldb::opaque_compiler_type_t type, - CompilerType *function_pointer_type_ptr) { - return false; -} - -bool GoASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, - bool &is_signed) { - is_signed = false; - // TODO: Is bool an integer? - if (type) { - int kind = static_cast(type)->GetGoKind(); - if (kind <= GoType::KIND_UINTPTR) { - is_signed = (kind != GoType::KIND_BOOL) & (kind <= GoType::KIND_INT64); - return true; - } - } - return false; -} - -bool GoASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) { - return false; -} - -bool GoASTContext::IsPossibleDynamicType( - lldb::opaque_compiler_type_t type, - CompilerType *target_type, // Can pass NULL - bool check_cplusplus, bool check_objc) { - if (target_type) - target_type->Clear(); - if (type) - return static_cast(type)->GetGoKind() == GoType::KIND_INTERFACE; - return false; -} - -bool GoASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) { - return false; -} - -bool GoASTContext::IsPointerType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type) { - if (!type) - return false; - GoType *t = static_cast(type); - if (pointee_type) { - *pointee_type = t->GetElementType(); - } - switch (t->GetGoKind()) { - case GoType::KIND_PTR: - case GoType::KIND_UNSAFEPOINTER: - case GoType::KIND_CHAN: - case GoType::KIND_MAP: - // TODO: is function a pointer? - return true; - default: - return false; - } -} - -bool GoASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type) { - return IsPointerType(type, pointee_type); -} - -bool GoASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type, - bool *is_rvalue) { - return false; -} - -bool GoASTContext::IsScalarType(lldb::opaque_compiler_type_t type) { - return !IsAggregateType(type); -} - -bool GoASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) { - if (type) - return static_cast(type)->IsTypedef(); - return false; -} - -bool GoASTContext::IsVoidType(lldb::opaque_compiler_type_t type) { - if (!type) - return false; - return static_cast(type)->GetGoKind() == GoType::KIND_LLDB_VOID; -} - -bool GoASTContext::SupportsLanguage(lldb::LanguageType language) { - return language == eLanguageTypeGo; -} - -//---------------------------------------------------------------------- -// Type Completion -//---------------------------------------------------------------------- - -bool GoASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) { - if (!type) - return false; - GoType *t = static_cast(type); - if (t->IsTypedef() || t->GetGoKind() == GoType::KIND_PTR || t->GetArray()) - return t->GetElementType().GetCompleteType(); - if (GoStruct *s = t->GetStruct()) { - if (s->IsComplete()) - return true; - CompilerType compiler_type(this, s); - SymbolFile *symbols = GetSymbolFile(); - return symbols && symbols->CompleteType(compiler_type); - } - return true; -} - -//---------------------------------------------------------------------- -// AST related queries -//---------------------------------------------------------------------- - -uint32_t GoASTContext::GetPointerByteSize() { return m_pointer_byte_size; } - -//---------------------------------------------------------------------- -// Accessors -//---------------------------------------------------------------------- - -ConstString GoASTContext::GetTypeName(lldb::opaque_compiler_type_t type) { - if (type) - return static_cast(type)->GetName(); - return ConstString(); -} - -uint32_t -GoASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type) { - if (pointee_or_element_compiler_type) - pointee_or_element_compiler_type->Clear(); - if (!type) - return 0; - GoType *t = static_cast(type); - if (pointee_or_element_compiler_type) - *pointee_or_element_compiler_type = t->GetElementType(); - int kind = t->GetGoKind(); - if (kind == GoType::KIND_ARRAY) - return eTypeHasChildren | eTypeIsArray; - if (kind < GoType::KIND_ARRAY) { - uint32_t builtin_type_flags = eTypeIsBuiltIn | eTypeHasValue; - if (kind < GoType::KIND_FLOAT32) { - builtin_type_flags |= eTypeIsInteger | eTypeIsScalar; - if (kind >= GoType::KIND_INT && kind <= GoType::KIND_INT64) - builtin_type_flags |= eTypeIsSigned; - } else { - builtin_type_flags |= eTypeIsFloat; - if (kind < GoType::KIND_COMPLEX64) - builtin_type_flags |= eTypeIsComplex; - else - builtin_type_flags |= eTypeIsScalar; - } - return builtin_type_flags; - } - if (kind == GoType::KIND_STRING) - return eTypeHasValue | eTypeIsBuiltIn; - if (kind == GoType::KIND_FUNC) - return eTypeIsFuncPrototype | eTypeHasValue; - if (IsPointerType(type)) - return eTypeIsPointer | eTypeHasValue | eTypeHasChildren; - if (kind == GoType::KIND_LLDB_VOID) - return 0; - return eTypeHasChildren | eTypeIsStructUnion; -} - -lldb::TypeClass GoASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) { - if (!type) - return eTypeClassInvalid; - int kind = static_cast(type)->GetGoKind(); - if (kind == GoType::KIND_FUNC) - return eTypeClassFunction; - if (IsPointerType(type)) - return eTypeClassPointer; - if (kind < GoType::KIND_COMPLEX64) - return eTypeClassBuiltin; - if (kind <= GoType::KIND_COMPLEX128) - return eTypeClassComplexFloat; - if (kind == GoType::KIND_LLDB_VOID) - return eTypeClassInvalid; - return eTypeClassStruct; -} - -lldb::BasicType -GoASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) { - ConstString name = GetTypeName(type); - if (name) { - typedef UniqueCStringMap TypeNameToBasicTypeMap; - static TypeNameToBasicTypeMap g_type_map; - static llvm::once_flag g_once_flag; - llvm::call_once(g_once_flag, []() { - // "void" - g_type_map.Append(ConstString("void"), eBasicTypeVoid); - // "int" - g_type_map.Append(ConstString("int"), eBasicTypeInt); - g_type_map.Append(ConstString("uint"), eBasicTypeUnsignedInt); - - // Miscellaneous - g_type_map.Append(ConstString("bool"), eBasicTypeBool); - - // Others. Should these map to C types? - g_type_map.Append(ConstString("byte"), eBasicTypeOther); - g_type_map.Append(ConstString("uint8"), eBasicTypeOther); - g_type_map.Append(ConstString("uint16"), eBasicTypeOther); - g_type_map.Append(ConstString("uint32"), eBasicTypeOther); - g_type_map.Append(ConstString("uint64"), eBasicTypeOther); - g_type_map.Append(ConstString("int8"), eBasicTypeOther); - g_type_map.Append(ConstString("int16"), eBasicTypeOther); - g_type_map.Append(ConstString("int32"), eBasicTypeOther); - g_type_map.Append(ConstString("int64"), eBasicTypeOther); - g_type_map.Append(ConstString("float32"), eBasicTypeOther); - g_type_map.Append(ConstString("float64"), eBasicTypeOther); - g_type_map.Append(ConstString("uintptr"), eBasicTypeOther); - - g_type_map.Sort(); - }); - - return g_type_map.Find(name, eBasicTypeInvalid); - } - return eBasicTypeInvalid; -} - -lldb::LanguageType -GoASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { - return lldb::eLanguageTypeGo; -} - -unsigned GoASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) { - return 0; -} - -//---------------------------------------------------------------------- -// Creating related types -//---------------------------------------------------------------------- - -CompilerType -GoASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, - uint64_t *stride) { - GoArray *array = static_cast(type)->GetArray(); - if (array) { - if (stride) { - *stride = array->GetElementType().GetByteSize(nullptr); - } - return array->GetElementType(); - } - return CompilerType(); -} - -CompilerType GoASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) { - GoType *t = static_cast(type); - if (t->IsTypedef()) - return t->GetElementType(); - return CompilerType(this, type); -} - -CompilerType -GoASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -// Returns -1 if this isn't a function of if the function doesn't have a -// prototype Returns a value >= 0 if there is a prototype. -int GoASTContext::GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) { - return GetNumberOfFunctionArguments(type); -} - -CompilerType -GoASTContext::GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) { - return GetFunctionArgumentAtIndex(type, idx); -} - -CompilerType -GoASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) { - CompilerType result; - if (type) { - GoType *t = static_cast(type); - if (t->GetGoKind() == GoType::KIND_FUNC) - result = t->GetElementType(); - } - return result; -} - -size_t GoASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) { - return 0; -} - -TypeMemberFunctionImpl -GoASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) { - return TypeMemberFunctionImpl(); -} - -CompilerType -GoASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -CompilerType GoASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) { - if (!type) - return CompilerType(); - return static_cast(type)->GetElementType(); -} - -CompilerType GoASTContext::GetPointerType(lldb::opaque_compiler_type_t type) { - if (!type) - return CompilerType(); - ConstString type_name = GetTypeName(type); - ConstString pointer_name(std::string("*") + type_name.GetCString()); - GoType *pointer = (*m_types)[pointer_name].get(); - if (pointer == nullptr) { - pointer = - new GoElem(GoType::KIND_PTR, pointer_name, CompilerType(this, type)); - (*m_types)[pointer_name].reset(pointer); - } - return CompilerType(this, pointer); -} - -// If the current object represents a typedef type, get the underlying type -CompilerType GoASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) { - if (IsTypedefType(type)) - return static_cast(type)->GetElementType(); - return CompilerType(); -} - -//---------------------------------------------------------------------- -// Create related types using the current type's AST -//---------------------------------------------------------------------- -CompilerType GoASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) { - return CompilerType(); -} - -CompilerType -GoASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, - size_t bit_size) { - return CompilerType(); -} - -//---------------------------------------------------------------------- -// Exploring the type -//---------------------------------------------------------------------- - -uint64_t GoASTContext::GetBitSize(lldb::opaque_compiler_type_t type, - ExecutionContextScope *exe_scope) { - if (!type) - return 0; - if (!GetCompleteType(type)) - return 0; - GoType *t = static_cast(type); - GoArray *array = nullptr; - switch (t->GetGoKind()) { - case GoType::KIND_BOOL: - case GoType::KIND_INT8: - case GoType::KIND_UINT8: - return 8; - case GoType::KIND_INT16: - case GoType::KIND_UINT16: - return 16; - case GoType::KIND_INT32: - case GoType::KIND_UINT32: - case GoType::KIND_FLOAT32: - return 32; - case GoType::KIND_INT64: - case GoType::KIND_UINT64: - case GoType::KIND_FLOAT64: - case GoType::KIND_COMPLEX64: - return 64; - case GoType::KIND_COMPLEX128: - return 128; - case GoType::KIND_INT: - case GoType::KIND_UINT: - return m_int_byte_size * 8; - case GoType::KIND_UINTPTR: - case GoType::KIND_FUNC: // I assume this is a pointer? - case GoType::KIND_CHAN: - case GoType::KIND_PTR: - case GoType::KIND_UNSAFEPOINTER: - case GoType::KIND_MAP: - return m_pointer_byte_size * 8; - case GoType::KIND_ARRAY: - array = t->GetArray(); - return array->GetLength() * array->GetElementType().GetBitSize(exe_scope); - case GoType::KIND_INTERFACE: - return t->GetElementType().GetBitSize(exe_scope); - case GoType::KIND_SLICE: - case GoType::KIND_STRING: - case GoType::KIND_STRUCT: - return t->GetStruct()->GetByteSize() * 8; - default: - assert(false); - } - return 0; -} - -lldb::Encoding GoASTContext::GetEncoding(lldb::opaque_compiler_type_t type, - uint64_t &count) { - count = 1; - bool is_signed; - if (IsIntegerType(type, is_signed)) - return is_signed ? lldb::eEncodingSint : eEncodingUint; - bool is_complex; - uint32_t complex_count; - if (IsFloatingPointType(type, complex_count, is_complex)) { - count = complex_count; - return eEncodingIEEE754; - } - if (IsPointerType(type)) - return eEncodingUint; - return eEncodingInvalid; -} - -lldb::Format GoASTContext::GetFormat(lldb::opaque_compiler_type_t type) { - if (!type) - return eFormatDefault; - switch (static_cast(type)->GetGoKind()) { - case GoType::KIND_BOOL: - return eFormatBoolean; - case GoType::KIND_INT: - case GoType::KIND_INT8: - case GoType::KIND_INT16: - case GoType::KIND_INT32: - case GoType::KIND_INT64: - return eFormatDecimal; - case GoType::KIND_UINT: - case GoType::KIND_UINT8: - case GoType::KIND_UINT16: - case GoType::KIND_UINT32: - case GoType::KIND_UINT64: - return eFormatUnsigned; - case GoType::KIND_FLOAT32: - case GoType::KIND_FLOAT64: - return eFormatFloat; - case GoType::KIND_COMPLEX64: - case GoType::KIND_COMPLEX128: - return eFormatComplexFloat; - case GoType::KIND_UINTPTR: - case GoType::KIND_CHAN: - case GoType::KIND_PTR: - case GoType::KIND_MAP: - case GoType::KIND_UNSAFEPOINTER: - return eFormatHex; - case GoType::KIND_STRING: - return eFormatCString; - case GoType::KIND_ARRAY: - case GoType::KIND_INTERFACE: - case GoType::KIND_SLICE: - case GoType::KIND_STRUCT: - default: - // Don't know how to display this. - return eFormatBytes; - } -} - -size_t GoASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) { - return 0; -} - -uint32_t GoASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) { - if (!type || !GetCompleteType(type)) - return 0; - GoType *t = static_cast(type); - if (t->GetGoKind() == GoType::KIND_PTR) { - CompilerType elem = t->GetElementType(); - if (elem.IsAggregateType()) - return elem.GetNumChildren(omit_empty_base_classes); - return 1; - } else if (GoArray *array = t->GetArray()) { - return array->GetLength(); - } else if (t->IsTypedef()) { - return t->GetElementType().GetNumChildren(omit_empty_base_classes); - } - - return GetNumFields(type); -} - -uint32_t GoASTContext::GetNumFields(lldb::opaque_compiler_type_t type) { - if (!type || !GetCompleteType(type)) - return 0; - GoType *t = static_cast(type); - if (t->IsTypedef()) - return t->GetElementType().GetNumFields(); - GoStruct *s = t->GetStruct(); - if (s) - return s->GetNumFields(); - return 0; -} - -CompilerType GoASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, std::string &name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) { - if (bit_offset_ptr) - *bit_offset_ptr = 0; - if (bitfield_bit_size_ptr) - *bitfield_bit_size_ptr = 0; - if (is_bitfield_ptr) - *is_bitfield_ptr = false; - - if (!type || !GetCompleteType(type)) - return CompilerType(); - - GoType *t = static_cast(type); - if (t->IsTypedef()) - return t->GetElementType().GetFieldAtIndex( - idx, name, bit_offset_ptr, bitfield_bit_size_ptr, is_bitfield_ptr); - - GoStruct *s = t->GetStruct(); - if (s) { - const auto *field = s->GetField(idx); - if (field) { - name = field->m_name.GetStringRef(); - if (bit_offset_ptr) - *bit_offset_ptr = field->m_byte_offset * 8; - return field->m_type; - } - } - return CompilerType(); -} - -CompilerType GoASTContext::GetChildCompilerTypeAtIndex( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, - ValueObject *valobj, uint64_t &language_flags) { - child_name.clear(); - child_byte_size = 0; - child_byte_offset = 0; - child_bitfield_bit_size = 0; - child_bitfield_bit_offset = 0; - child_is_base_class = false; - child_is_deref_of_parent = false; - language_flags = 0; - - if (!type || !GetCompleteType(type)) - return CompilerType(); - - GoType *t = static_cast(type); - if (t->GetStruct()) { - uint64_t bit_offset; - CompilerType ret = - GetFieldAtIndex(type, idx, child_name, &bit_offset, nullptr, nullptr); - child_byte_size = ret.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); - child_byte_offset = bit_offset / 8; - return ret; - } else if (t->GetGoKind() == GoType::KIND_PTR) { - CompilerType pointee = t->GetElementType(); - if (!pointee.IsValid() || pointee.IsVoidType()) - return CompilerType(); - if (transparent_pointers && pointee.IsAggregateType()) { - bool tmp_child_is_deref_of_parent = false; - return pointee.GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, - child_is_base_class, tmp_child_is_deref_of_parent, valobj, - language_flags); - } else { - child_is_deref_of_parent = true; - const char *parent_name = valobj ? valobj->GetName().GetCString() : NULL; - if (parent_name) { - child_name.assign(1, '*'); - child_name += parent_name; - } - - // We have a pointer to an simple type - if (idx == 0 && pointee.GetCompleteType()) { - child_byte_size = pointee.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = 0; - return pointee; - } - } - } else if (GoArray *a = t->GetArray()) { - if (ignore_array_bounds || idx < a->GetLength()) { - CompilerType element_type = a->GetElementType(); - if (element_type.GetCompleteType()) { - char element_name[64]; - ::snprintf(element_name, sizeof(element_name), "[%zu]", idx); - child_name.assign(element_name); - child_byte_size = element_type.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : NULL); - child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; - return element_type; - } - } - } else if (t->IsTypedef()) { - return t->GetElementType().GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class, - child_is_deref_of_parent, valobj, language_flags); - } - return CompilerType(); -} - -// Lookup a child given a name. This function will match base class names and -// member member names in "clang_type" only, not descendants. -uint32_t -GoASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes) { - if (!type || !GetCompleteType(type)) - return UINT_MAX; - - GoType *t = static_cast(type); - GoStruct *s = t->GetStruct(); - if (s) { - for (uint32_t i = 0; i < s->GetNumFields(); ++i) { - const GoStruct::Field *f = s->GetField(i); - if (f->m_name.GetStringRef() == name) - return i; - } - } else if (t->GetGoKind() == GoType::KIND_PTR || t->IsTypedef()) { - return t->GetElementType().GetIndexOfChildWithName(name, - omit_empty_base_classes); - } - return UINT_MAX; -} - -// Lookup a child member given a name. This function will match member names -// only and will descend into "clang_type" children in search for the first -// member in this class, or any base class that matches "name". -// TODO: Return all matches for a given name by returning a -// vector> -// so we catch all names that match a given child name, not just the first. -size_t GoASTContext::GetIndexOfChildMemberWithName( - lldb::opaque_compiler_type_t type, const char *name, - bool omit_empty_base_classes, std::vector &child_indexes) { - uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes); - if (index == UINT_MAX) - return 0; - child_indexes.push_back(index); - return 1; -} - -// Converts "s" to a floating point value and place resulting floating point -// bytes in the "dst" buffer. -size_t -GoASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) { - assert(false); - return 0; -} -//---------------------------------------------------------------------- -// Dumping types -//---------------------------------------------------------------------- -#define DEPTH_INCREMENT 2 - -void GoASTContext::DumpValue(lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, - lldb::Format format, const DataExtractor &data, - lldb::offset_t data_byte_offset, - size_t data_byte_size, uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, bool show_types, - bool show_summary, bool verbose, uint32_t depth) { - if (IsTypedefType(type)) - type = GetTypedefedType(type).GetOpaqueQualType(); - if (!type) - return; - GoType *t = static_cast(type); - - if (GoStruct *st = t->GetStruct()) { - if (GetCompleteType(type)) { - uint32_t field_idx = 0; - for (auto *field = st->GetField(field_idx); field != nullptr; - field_idx++) { - // Print the starting squiggly bracket (if this is the first member) or - // comma (for member 2 and beyond) for the struct/union/class member. - if (field_idx == 0) - s->PutChar('{'); - else - s->PutChar(','); - - // Indent - s->Printf("\n%*s", depth + DEPTH_INCREMENT, ""); - - // Print the member type if requested - if (show_types) { - ConstString field_type_name = field->m_type.GetTypeName(); - s->Printf("(%s) ", field_type_name.AsCString()); - } - // Print the member name and equal sign - s->Printf("%s = ", field->m_name.AsCString()); - - // Dump the value of the member - CompilerType field_type = field->m_type; - field_type.DumpValue( - exe_ctx, - s, // Stream to dump to - field_type - .GetFormat(), // The format with which to display the member - data, // Data buffer containing all bytes for this type - data_byte_offset + field->m_byte_offset, // Offset into "data" where - // to grab value from - field->m_type.GetByteSize( - exe_ctx->GetBestExecutionContextScope()), // Size of this type - // in bytes - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Boolean indicating if we should show the variable - // types - show_summary, // Boolean indicating if we should show a summary for - // the current type - verbose, // Verbose output? - depth + DEPTH_INCREMENT); // Scope depth for any types that have - // children - } - - // Indent the trailing squiggly bracket - if (field_idx > 0) - s->Printf("\n%*s}", depth, ""); - } - } - - if (GoArray *a = t->GetArray()) { - CompilerType element_clang_type = a->GetElementType(); - lldb::Format element_format = element_clang_type.GetFormat(); - uint32_t element_byte_size = - element_clang_type.GetByteSize(exe_ctx->GetBestExecutionContextScope()); - - uint64_t element_idx; - for (element_idx = 0; element_idx < a->GetLength(); ++element_idx) { - // Print the starting squiggly bracket (if this is the first member) or - // comman (for member 2 and beyong) for the struct/union/class member. - if (element_idx == 0) - s->PutChar('{'); - else - s->PutChar(','); - - // Indent and print the index - s->Printf("\n%*s[%" PRIu64 "] ", depth + DEPTH_INCREMENT, "", - element_idx); - - // Figure out the field offset within the current struct/union/class type - uint64_t element_offset = element_idx * element_byte_size; - - // Dump the value of the member - element_clang_type.DumpValue( - exe_ctx, - s, // Stream to dump to - element_format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - data_byte_offset + - element_offset, // Offset into "data" where to grab value from - element_byte_size, // Size of this type in bytes - 0, // Bitfield bit size - 0, // Bitfield bit offset - show_types, // Boolean indicating if we should show the variable types - show_summary, // Boolean indicating if we should show a summary for - // the current type - verbose, // Verbose output? - depth + - DEPTH_INCREMENT); // Scope depth for any types that have children - } - - // Indent the trailing squiggly bracket - if (element_idx > 0) - s->Printf("\n%*s}", depth, ""); - } - - if (show_summary) - DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size); -} - -bool GoASTContext::DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, - lldb::Format format, const DataExtractor &data, - lldb::offset_t byte_offset, size_t byte_size, - uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) { - if (!type) - return false; - if (IsAggregateType(type)) { - return false; - } else { - GoType *t = static_cast(type); - if (t->IsTypedef()) { - CompilerType typedef_compiler_type = t->GetElementType(); - if (format == eFormatDefault) - format = typedef_compiler_type.GetFormat(); - uint64_t typedef_byte_size = typedef_compiler_type.GetByteSize(exe_scope); - - return typedef_compiler_type.DumpTypeValue( - s, - format, // The format with which to display the element - data, // Data buffer containing all bytes for this type - byte_offset, // Offset into "data" where to grab value from - typedef_byte_size, // Size of this type in bytes - bitfield_bit_size, // Size in bits of a bitfield value, if zero don't - // treat as a bitfield - bitfield_bit_offset, // Offset in bits of a bitfield value if - // bitfield_bit_size != 0 - exe_scope); - } - - uint32_t item_count = 1; - // A few formats, we might need to modify our size and count for depending - // on how we are trying to display the value... - switch (format) { - default: - case eFormatBoolean: - case eFormatBinary: - case eFormatComplex: - case eFormatCString: // NULL terminated C strings - case eFormatDecimal: - case eFormatEnum: - case eFormatHex: - case eFormatHexUppercase: - case eFormatFloat: - case eFormatOctal: - case eFormatOSType: - case eFormatUnsigned: - case eFormatPointer: - case eFormatVectorOfChar: - case eFormatVectorOfSInt8: - case eFormatVectorOfUInt8: - case eFormatVectorOfSInt16: - case eFormatVectorOfUInt16: - case eFormatVectorOfSInt32: - case eFormatVectorOfUInt32: - case eFormatVectorOfSInt64: - case eFormatVectorOfUInt64: - case eFormatVectorOfFloat32: - case eFormatVectorOfFloat64: - case eFormatVectorOfUInt128: - break; - - case eFormatChar: - case eFormatCharPrintable: - case eFormatCharArray: - case eFormatBytes: - case eFormatBytesWithASCII: - item_count = byte_size; - byte_size = 1; - break; - - case eFormatUnicode16: - item_count = byte_size / 2; - byte_size = 2; - break; - - case eFormatUnicode32: - item_count = byte_size / 4; - byte_size = 4; - break; - } - return DumpDataExtractor(data, s, byte_offset, format, byte_size, - item_count, UINT32_MAX, LLDB_INVALID_ADDRESS, - bitfield_bit_size, bitfield_bit_offset, exe_scope); - } - return 0; -} - -void GoASTContext::DumpSummary(lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size) { - if (type && GoType::KIND_STRING == static_cast(type)->GetGoKind()) { - // TODO(ribrdb): read length and data - } -} - -void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) { - // Dump to stdout - StreamFile s(stdout, false); - DumpTypeDescription(type, &s); -} - -void GoASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s) { - if (!type) - return; - ConstString name = GetTypeName(type); - GoType *t = static_cast(type); - - if (GoStruct *st = t->GetStruct()) { - if (GetCompleteType(type)) { - if (NULL == strchr(name.AsCString(), '{')) - s->Printf("type %s ", name.AsCString()); - s->PutCString("struct {"); - if (st->GetNumFields() == 0) { - s->PutChar('}'); - return; - } - s->IndentMore(); - uint32_t field_idx = 0; - for (auto *field = st->GetField(field_idx); field != nullptr; - field_idx++) { - s->PutChar('\n'); - s->Indent(); - s->Printf("%s %s", field->m_name.AsCString(), - field->m_type.GetTypeName().AsCString()); - } - s->IndentLess(); - s->PutChar('\n'); - s->Indent("}"); - return; - } - } - - s->PutCString(name.AsCString()); -} - -CompilerType GoASTContext::CreateArrayType(const ConstString &name, - const CompilerType &element_type, - uint64_t length) { - GoType *type = new GoArray(name, length, element_type); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -CompilerType GoASTContext::CreateBaseType(int go_kind, - const lldb_private::ConstString &name, - uint64_t byte_size) { - if (go_kind == GoType::KIND_UINT || go_kind == GoType::KIND_INT) - m_int_byte_size = byte_size; - GoType *type = new GoType(go_kind, name); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -CompilerType GoASTContext::CreateTypedefType(int kind, const ConstString &name, - CompilerType impl) { - GoType *type = new GoElem(kind, name, impl); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -CompilerType -GoASTContext::CreateVoidType(const lldb_private::ConstString &name) { - GoType *type = new GoType(GoType::KIND_LLDB_VOID, name); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -CompilerType -GoASTContext::CreateStructType(int kind, const lldb_private::ConstString &name, - uint32_t byte_size) { - GoType *type = new GoStruct(kind, name, byte_size); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -void GoASTContext::AddFieldToStruct( - const lldb_private::CompilerType &struct_type, - const lldb_private::ConstString &name, - const lldb_private::CompilerType &field_type, uint32_t byte_offset) { - if (!struct_type) - return; - GoASTContext *ast = - llvm::dyn_cast_or_null(struct_type.GetTypeSystem()); - if (!ast) - return; - GoType *type = static_cast(struct_type.GetOpaqueQualType()); - if (GoStruct *s = type->GetStruct()) - s->AddField(name, field_type, byte_offset); -} - -void GoASTContext::CompleteStructType( - const lldb_private::CompilerType &struct_type) { - if (!struct_type) - return; - GoASTContext *ast = - llvm::dyn_cast_or_null(struct_type.GetTypeSystem()); - if (!ast) - return; - GoType *type = static_cast(struct_type.GetOpaqueQualType()); - if (GoStruct *s = type->GetStruct()) - s->SetComplete(); -} - -CompilerType -GoASTContext::CreateFunctionType(const lldb_private::ConstString &name, - CompilerType *params, size_t params_count, - bool is_variadic) { - GoType *type = new GoFunction(name, is_variadic); - (*m_types)[name].reset(type); - return CompilerType(this, type); -} - -bool GoASTContext::IsGoString(const lldb_private::CompilerType &type) { - if (!type.IsValid() || - !llvm::dyn_cast_or_null(type.GetTypeSystem())) - return false; - return GoType::KIND_STRING == - static_cast(type.GetOpaqueQualType())->GetGoKind(); -} - -bool GoASTContext::IsGoSlice(const lldb_private::CompilerType &type) { - if (!type.IsValid() || - !llvm::dyn_cast_or_null(type.GetTypeSystem())) - return false; - return GoType::KIND_SLICE == - static_cast(type.GetOpaqueQualType())->GetGoKind(); -} - -bool GoASTContext::IsGoInterface(const lldb_private::CompilerType &type) { - if (!type.IsValid() || - !llvm::dyn_cast_or_null(type.GetTypeSystem())) - return false; - return GoType::KIND_INTERFACE == - static_cast(type.GetOpaqueQualType())->GetGoKind(); -} - -bool GoASTContext::IsPointerKind(uint8_t kind) { - return (kind & GoType::KIND_MASK) == GoType::KIND_PTR; -} - -bool GoASTContext::IsDirectIface(uint8_t kind) { - return (kind & GoType::KIND_DIRECT_IFACE) == GoType::KIND_DIRECT_IFACE; -} - -DWARFASTParser *GoASTContext::GetDWARFParser() { - if (!m_dwarf_ast_parser_ap) - m_dwarf_ast_parser_ap.reset(new DWARFASTParserGo(*this)); - return m_dwarf_ast_parser_ap.get(); -} - -UserExpression *GoASTContextForExpr::GetUserExpression( - llvm::StringRef expr, llvm::StringRef prefix, lldb::LanguageType language, - Expression::ResultType desired_type, - const EvaluateExpressionOptions &options) { - TargetSP target = m_target_wp.lock(); - if (target) - return new GoUserExpression(*target, expr, prefix, language, desired_type, - options); - return nullptr; -} diff --git a/contrib/llvm/tools/lldb/source/Symbol/JavaASTContext.cpp b/contrib/llvm/tools/lldb/source/Symbol/JavaASTContext.cpp deleted file mode 100644 index ff317eb19e97..000000000000 --- a/contrib/llvm/tools/lldb/source/Symbol/JavaASTContext.cpp +++ /dev/null @@ -1,1324 +0,0 @@ -//===-- JavaASTContext.cpp --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Symbol/JavaASTContext.h" -#include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Expression/DWARFExpression.h" -#include "lldb/Symbol/CompilerType.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Target/Target.h" -#include "lldb/Utility/ArchSpec.h" -#include "lldb/Utility/Stream.h" -#include - -#include "Plugins/SymbolFile/DWARF/DWARFASTParserJava.h" - -using namespace lldb; -using namespace lldb_private; - -namespace lldb_private { - -class JavaASTContext::JavaType { -public: - enum LLVMCastKind { - eKindPrimitive, - eKindObject, - eKindReference, - eKindArray, - kNumKinds - }; - - JavaType(LLVMCastKind kind) : m_kind(kind) {} - - virtual ~JavaType() = default; - - virtual ConstString GetName() = 0; - - virtual void Dump(Stream *s) = 0; - - virtual bool IsCompleteType() = 0; - - LLVMCastKind getKind() const { return m_kind; } - -private: - LLVMCastKind m_kind; -}; - -} // end of namespace lldb_private - -namespace { - -class JavaPrimitiveType : public JavaASTContext::JavaType { -public: - enum TypeKind { - eTypeByte, - eTypeShort, - eTypeInt, - eTypeLong, - eTypeFloat, - eTypeDouble, - eTypeBoolean, - eTypeChar, - }; - - JavaPrimitiveType(TypeKind type_kind) - : JavaType(JavaType::eKindPrimitive), m_type_kind(type_kind) {} - - ConstString GetName() override { - switch (m_type_kind) { - case eTypeByte: - return ConstString("byte"); - case eTypeShort: - return ConstString("short"); - case eTypeInt: - return ConstString("int"); - case eTypeLong: - return ConstString("long"); - case eTypeFloat: - return ConstString("float"); - case eTypeDouble: - return ConstString("double"); - case eTypeBoolean: - return ConstString("boolean"); - case eTypeChar: - return ConstString("char"); - } - return ConstString(); - } - - TypeKind GetTypeKind() { return m_type_kind; } - - void Dump(Stream *s) override { s->Printf("%s\n", GetName().GetCString()); } - - bool IsCompleteType() override { return true; } - - static bool classof(const JavaType *jt) { - return jt->getKind() == JavaType::eKindPrimitive; - } - -private: - const TypeKind m_type_kind; -}; - -class JavaDynamicType : public JavaASTContext::JavaType { -public: - JavaDynamicType(LLVMCastKind kind, const ConstString &linkage_name) - : JavaType(kind), m_linkage_name(linkage_name), - m_dynamic_type_id(nullptr) {} - - ConstString GetLinkageName() const { return m_linkage_name; } - - void SetDynamicTypeId(const DWARFExpression &type_id) { - m_dynamic_type_id = type_id; - } - - uint64_t CalculateDynamicTypeId(ExecutionContext *exe_ctx, - ValueObject &value_obj) { - if (!m_dynamic_type_id.IsValid()) - return UINT64_MAX; - - Value obj_load_address = value_obj.GetValue(); - obj_load_address.ResolveValue(exe_ctx); - obj_load_address.SetValueType(Value::eValueTypeLoadAddress); - - Value result; - if (m_dynamic_type_id.Evaluate(exe_ctx->GetBestExecutionContextScope(), 0, - &obj_load_address, nullptr, result, - nullptr)) { - Status error; - - lldb::addr_t type_id_addr = result.GetScalar().UInt(); - lldb::ProcessSP process_sp = exe_ctx->GetProcessSP(); - if (process_sp) - return process_sp->ReadUnsignedIntegerFromMemory( - type_id_addr, process_sp->GetAddressByteSize(), UINT64_MAX, error); - } - - return UINT64_MAX; - } - -public: - ConstString m_linkage_name; - DWARFExpression m_dynamic_type_id; -}; - -class JavaObjectType : public JavaDynamicType { -public: - struct Field { - ConstString m_name; - CompilerType m_type; - uint32_t m_offset; - }; - - JavaObjectType(const ConstString &name, const ConstString &linkage_name, - uint32_t byte_size) - : JavaDynamicType(JavaType::eKindObject, linkage_name), m_name(name), - m_byte_size(byte_size), m_base_class_offset(0), m_is_complete(false) {} - - ConstString GetName() override { return m_name; } - - uint32_t GetByteSize() const { return m_byte_size; } - - uint32_t GetNumFields() { return m_fields.size(); } - - void Dump(Stream *s) override { - if (m_base_class.IsValid()) - s->Printf("%s : %s\n", GetName().GetCString(), - m_base_class.GetTypeName().GetCString()); - else - s->Printf("%s\n", GetName().GetCString()); - - s->IndentMore(); - for (const Field &f : m_fields) - s->Printf("%s %s\n", f.m_type.GetTypeName().GetCString(), - f.m_name.GetCString()); - s->IndentLess(); - } - - Field *GetFieldAtIndex(size_t idx) { - if (idx < m_fields.size()) - return &m_fields[idx]; - return nullptr; - } - - CompilerType GetBaseClass() { return m_base_class; } - - uint32_t GetBaseClassOffset() { return m_base_class_offset; } - - uint32_t GetNumInterfaces() { return m_interfaces.size(); } - - CompilerType GetInterfaceAtIndex(uint32_t idx) { - if (m_interfaces.size() < idx) - return m_interfaces[idx]; - return CompilerType(); - } - - bool IsCompleteType() override { return m_is_complete; } - - void SetCompleteType(bool is_complete) { - m_is_complete = is_complete; - if (m_byte_size == 0) { - // Try to calcualte the size of the object based on it's values - for (const Field &field : m_fields) { - uint32_t field_end = field.m_offset + field.m_type.GetByteSize(nullptr); - if (field_end > m_byte_size) - m_byte_size = field_end; - } - } - } - - void AddBaseClass(const CompilerType &type, uint32_t offset) { - // TODO: Check if type is an interface and add it to the interface list in - // that case - m_base_class = type; - m_base_class_offset = offset; - } - - void AddField(const ConstString &name, const CompilerType &type, - uint32_t offset) { - m_fields.push_back({name, type, offset}); - } - - static bool classof(const JavaType *jt) { - return jt->getKind() == JavaType::eKindObject; - } - -private: - ConstString m_name; - uint32_t m_byte_size; - CompilerType m_base_class; - uint32_t m_base_class_offset; - std::vector m_interfaces; - std::vector m_fields; - bool m_is_complete; -}; - -class JavaReferenceType : public JavaASTContext::JavaType { -public: - JavaReferenceType(CompilerType pointee_type) - : JavaType(JavaType::eKindReference), m_pointee_type(pointee_type) {} - - static bool classof(const JavaType *jt) { - return jt->getKind() == JavaType::eKindReference; - } - - CompilerType GetPointeeType() { return m_pointee_type; } - - ConstString GetName() override { - ConstString pointee_type_name = - static_cast(GetPointeeType().GetOpaqueQualType()) - ->GetName(); - return ConstString(std::string(pointee_type_name.AsCString()) + "&"); - } - - void Dump(Stream *s) override { - static_cast(m_pointee_type.GetOpaqueQualType())->Dump(s); - } - - bool IsCompleteType() override { return m_pointee_type.IsCompleteType(); } - -private: - CompilerType m_pointee_type; -}; - -class JavaArrayType : public JavaDynamicType { -public: - JavaArrayType(const ConstString &linkage_name, CompilerType element_type, - const DWARFExpression &length_expression, - lldb::addr_t data_offset) - : JavaDynamicType(JavaType::eKindArray, linkage_name), - m_element_type(element_type), m_length_expression(length_expression), - m_data_offset(data_offset) {} - - static bool classof(const JavaType *jt) { - return jt->getKind() == JavaType::eKindArray; - } - - CompilerType GetElementType() { return m_element_type; } - - ConstString GetName() override { - ConstString element_type_name = - static_cast(GetElementType().GetOpaqueQualType()) - ->GetName(); - return ConstString(std::string(element_type_name.AsCString()) + "[]"); - } - - void Dump(Stream *s) override { s->Printf("%s\n", GetName().GetCString()); } - - bool IsCompleteType() override { return m_length_expression.IsValid(); } - - uint32_t GetNumElements(ValueObject *value_obj) { - if (!m_length_expression.IsValid()) - return UINT32_MAX; - - Status error; - ValueObjectSP address_obj = value_obj->AddressOf(error); - if (error.Fail()) - return UINT32_MAX; - - Value obj_load_address = address_obj->GetValue(); - obj_load_address.SetValueType(Value::eValueTypeLoadAddress); - - Value result; - ExecutionContextScope *exec_ctx_scope = value_obj->GetExecutionContextRef() - .Lock(true) - .GetBestExecutionContextScope(); - if (m_length_expression.Evaluate(exec_ctx_scope, 0, nullptr, - &obj_load_address, result, nullptr)) - return result.GetScalar().UInt(); - - return UINT32_MAX; - } - - uint64_t GetElementOffset(size_t idx) { - return m_data_offset + idx * m_element_type.GetByteSize(nullptr); - } - -private: - CompilerType m_element_type; - DWARFExpression m_length_expression; - lldb::addr_t m_data_offset; -}; - -} // end of anonymous namespace - -ConstString JavaASTContext::GetPluginNameStatic() { - return ConstString("java"); -} - -ConstString JavaASTContext::GetPluginName() { - return JavaASTContext::GetPluginNameStatic(); -} - -uint32_t JavaASTContext::GetPluginVersion() { return 1; } - -lldb::TypeSystemSP JavaASTContext::CreateInstance(lldb::LanguageType language, - Module *module, - Target *target) { - if (language == eLanguageTypeJava) { - if (module) - return std::make_shared(module->GetArchitecture()); - if (target) - return std::make_shared(target->GetArchitecture()); - assert(false && "Either a module or a target has to be specifed to create " - "a JavaASTContext"); - } - return lldb::TypeSystemSP(); -} - -void JavaASTContext::EnumerateSupportedLanguages( - std::set &languages_for_types, - std::set &languages_for_expressions) { - static std::vector s_languages_for_types( - {lldb::eLanguageTypeJava}); - static std::vector s_languages_for_expressions({}); - - languages_for_types.insert(s_languages_for_types.begin(), - s_languages_for_types.end()); - languages_for_expressions.insert(s_languages_for_expressions.begin(), - s_languages_for_expressions.end()); -} - -void JavaASTContext::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), "AST context plug-in", - CreateInstance, EnumerateSupportedLanguages); -} - -void JavaASTContext::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -JavaASTContext::JavaASTContext(const ArchSpec &arch) - : TypeSystem(eKindJava), m_pointer_byte_size(arch.GetAddressByteSize()) {} - -JavaASTContext::~JavaASTContext() {} - -uint32_t JavaASTContext::GetPointerByteSize() { return m_pointer_byte_size; } - -DWARFASTParser *JavaASTContext::GetDWARFParser() { - if (!m_dwarf_ast_parser_ap) - m_dwarf_ast_parser_ap.reset(new DWARFASTParserJava(*this)); - return m_dwarf_ast_parser_ap.get(); -} - -ConstString JavaASTContext::DeclGetName(void *opaque_decl) { - return ConstString(); -} - -std::vector JavaASTContext::DeclContextFindDeclByName( - void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls) { - return std::vector(); -} - -bool JavaASTContext::DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) { - return false; -} - -ConstString JavaASTContext::DeclContextGetName(void *opaque_decl_ctx) { - return ConstString(); -} - -bool JavaASTContext::DeclContextIsClassMethod( - void *opaque_decl_ctx, lldb::LanguageType *language_ptr, - bool *is_instance_method_ptr, ConstString *language_object_name_ptr) { - return false; -} - -bool JavaASTContext::IsArrayType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size, - bool *is_incomplete) { - if (element_type) - element_type->Clear(); - if (size) - *size = 0; - if (is_incomplete) - *is_incomplete = false; - - if (JavaArrayType *array = - llvm::dyn_cast(static_cast(type))) { - if (element_type) - *element_type = array->GetElementType(); - return true; - } - return false; -} - -bool JavaASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) { - return llvm::isa(static_cast(type)); -} - -bool JavaASTContext::IsCharType(lldb::opaque_compiler_type_t type) { - if (JavaPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) - return ptype->GetTypeKind() == JavaPrimitiveType::eTypeChar; - return false; -} - -bool JavaASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, - uint32_t &count, bool &is_complex) { - is_complex = true; - - if (JavaPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case JavaPrimitiveType::eTypeFloat: - case JavaPrimitiveType::eTypeDouble: - count = 1; - return true; - default: - break; - } - } - - count = 0; - return false; -} - -bool JavaASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, - bool *is_variadic_ptr) { - if (is_variadic_ptr) - *is_variadic_ptr = false; - return false; -} - -size_t JavaASTContext::GetNumberOfFunctionArguments( - lldb::opaque_compiler_type_t type) { - return 0; -} - -CompilerType -JavaASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, - const size_t index) { - return CompilerType(); -} - -bool JavaASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { - return false; -} - -bool JavaASTContext::IsBlockPointerType( - lldb::opaque_compiler_type_t type, - CompilerType *function_pointer_type_ptr) { - return false; -} - -bool JavaASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, - bool &is_signed) { - if (JavaPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case JavaPrimitiveType::eTypeByte: - case JavaPrimitiveType::eTypeShort: - case JavaPrimitiveType::eTypeInt: - case JavaPrimitiveType::eTypeLong: - is_signed = true; - return true; - default: - break; - } - } - - is_signed = false; - return false; -} - -bool JavaASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, - CompilerType *target_type, - bool check_cplusplus, - bool check_objc) { - return llvm::isa(static_cast(type)); -} - -bool JavaASTContext::IsPointerType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type) { - if (pointee_type) - pointee_type->Clear(); - return false; -} - -bool JavaASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type, - bool *is_rvalue) { - if (is_rvalue) - *is_rvalue = false; - - if (JavaReferenceType *ref = - llvm::dyn_cast(static_cast(type))) { - if (pointee_type) - *pointee_type = ref->GetPointeeType(); - return true; - } - - if (pointee_type) - pointee_type->Clear(); - return false; -} - -bool JavaASTContext::IsScalarType(lldb::opaque_compiler_type_t type) { - return llvm::isa(static_cast(type)) || - llvm::isa(static_cast(type)); -} - -bool JavaASTContext::IsVoidType(lldb::opaque_compiler_type_t type) { - return false; // TODO: Implement if we introduce the void type -} - -bool JavaASTContext::SupportsLanguage(lldb::LanguageType language) { - return language == lldb::eLanguageTypeJava; -} - -bool JavaASTContext::IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) { - return true; -} - -bool JavaASTContext::IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type) { - return IsPointerType(type, pointee_type) || - IsReferenceType(type, pointee_type); -} - -bool JavaASTContext::IsCStringType(lldb::opaque_compiler_type_t type, - uint32_t &length) { - return false; // TODO: Implement it if we need it for string literals -} - -bool JavaASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) { - return false; -} - -bool JavaASTContext::IsVectorType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size) { - if (element_type) - element_type->Clear(); - if (size) - *size = 0; - return false; -} - -bool JavaASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) { - return llvm::isa(static_cast(type)); -} - -uint32_t -JavaASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, - CompilerType *base_type_ptr) { - return false; -} - -bool JavaASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) { - return static_cast(type)->IsCompleteType(); -} - -bool JavaASTContext::IsConst(lldb::opaque_compiler_type_t type) { - return false; -} - -bool JavaASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) { - return false; -} - -bool JavaASTContext::IsDefined(lldb::opaque_compiler_type_t type) { - return type != nullptr; -} - -bool JavaASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) { - if (IsCompleteType(type)) - return true; - - if (JavaArrayType *array = - llvm::dyn_cast(static_cast(type))) - return GetCompleteType(array->GetElementType().GetOpaqueQualType()); - - if (JavaReferenceType *reference = - llvm::dyn_cast(static_cast(type))) - return GetCompleteType(reference->GetPointeeType().GetOpaqueQualType()); - - if (llvm::isa(static_cast(type))) { - SymbolFile *symbol_file = GetSymbolFile(); - if (!symbol_file) - return false; - - CompilerType object_type(this, type); - return symbol_file->CompleteType(object_type); - } - return false; -} - -ConstString JavaASTContext::GetTypeName(lldb::opaque_compiler_type_t type) { - if (type) - return static_cast(type)->GetName(); - return ConstString(); -} - -uint32_t -JavaASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type) { - if (pointee_or_element_compiler_type) - pointee_or_element_compiler_type->Clear(); - if (!type) - return 0; - - if (IsReferenceType(type, pointee_or_element_compiler_type)) - return eTypeHasChildren | eTypeHasValue | eTypeIsReference; - if (IsArrayType(type, pointee_or_element_compiler_type, nullptr, nullptr)) - return eTypeHasChildren | eTypeIsArray; - if (llvm::isa(static_cast(type))) - return eTypeHasChildren | eTypeIsClass; - - if (JavaPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case JavaPrimitiveType::eTypeByte: - case JavaPrimitiveType::eTypeShort: - case JavaPrimitiveType::eTypeInt: - case JavaPrimitiveType::eTypeLong: - return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger | - eTypeIsSigned; - case JavaPrimitiveType::eTypeFloat: - case JavaPrimitiveType::eTypeDouble: - return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsFloat | - eTypeIsSigned; - case JavaPrimitiveType::eTypeBoolean: - return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar; - case JavaPrimitiveType::eTypeChar: - return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar; - } - } - return 0; -} - -lldb::TypeClass -JavaASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) { - if (!type) - return eTypeClassInvalid; - if (llvm::isa(static_cast(type))) - return eTypeClassReference; - if (llvm::isa(static_cast(type))) - return eTypeClassArray; - if (llvm::isa(static_cast(type))) - return eTypeClassClass; - if (llvm::isa(static_cast(type))) - return eTypeClassBuiltin; - assert(false && "Java type with unhandled type class"); - return eTypeClassInvalid; -} - -lldb::LanguageType -JavaASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { - return lldb::eLanguageTypeJava; -} - -CompilerType -JavaASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, - uint64_t *stride) { - if (stride) - *stride = 0; - - CompilerType element_type; - if (IsArrayType(type, &element_type, nullptr, nullptr)) - return element_type; - return CompilerType(); -} - -CompilerType JavaASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) { - CompilerType pointee_type; - if (IsPointerType(type, &pointee_type)) - return pointee_type; - return CompilerType(); -} - -CompilerType JavaASTContext::GetPointerType(lldb::opaque_compiler_type_t type) { - return CompilerType(); // No pointer types in java -} - -CompilerType -JavaASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -CompilerType -JavaASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -CompilerType -JavaASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) { - CompilerType pointee_type; - if (IsReferenceType(type, &pointee_type)) - return pointee_type; - return CompilerType(this, type); -} - -CompilerType -JavaASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) { - return CompilerType(); -} - -CompilerType JavaASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) { - return CompilerType(); -} - -CompilerType -JavaASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, - size_t bit_size) { - return CompilerType(); -} - -size_t JavaASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) { - return 0; -} - -lldb::BasicType -JavaASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) { - if (JavaPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case JavaPrimitiveType::eTypeByte: - return eBasicTypeOther; - case JavaPrimitiveType::eTypeShort: - return eBasicTypeShort; - case JavaPrimitiveType::eTypeInt: - return eBasicTypeInt; - case JavaPrimitiveType::eTypeLong: - return eBasicTypeLong; - case JavaPrimitiveType::eTypeFloat: - return eBasicTypeFloat; - case JavaPrimitiveType::eTypeDouble: - return eBasicTypeDouble; - case JavaPrimitiveType::eTypeBoolean: - return eBasicTypeBool; - case JavaPrimitiveType::eTypeChar: - return eBasicTypeChar; - } - } - return eBasicTypeInvalid; -} - -uint64_t JavaASTContext::GetBitSize(lldb::opaque_compiler_type_t type, - ExecutionContextScope *exe_scope) { - if (JavaPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case JavaPrimitiveType::eTypeByte: - return 8; - case JavaPrimitiveType::eTypeShort: - return 16; - case JavaPrimitiveType::eTypeInt: - return 32; - case JavaPrimitiveType::eTypeLong: - return 64; - case JavaPrimitiveType::eTypeFloat: - return 32; - case JavaPrimitiveType::eTypeDouble: - return 64; - case JavaPrimitiveType::eTypeBoolean: - return 1; - case JavaPrimitiveType::eTypeChar: - return 16; - } - } else if (llvm::isa(static_cast(type))) { - return 32; // References are always 4 byte long in java - } else if (llvm::isa(static_cast(type))) { - return 64; - } else if (JavaObjectType *obj = llvm::dyn_cast( - static_cast(type))) { - return obj->GetByteSize() * 8; - } - return 0; -} - -lldb::Encoding JavaASTContext::GetEncoding(lldb::opaque_compiler_type_t type, - uint64_t &count) { - count = 1; - - if (JavaPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case JavaPrimitiveType::eTypeByte: - case JavaPrimitiveType::eTypeShort: - case JavaPrimitiveType::eTypeInt: - case JavaPrimitiveType::eTypeLong: - return eEncodingSint; - case JavaPrimitiveType::eTypeFloat: - case JavaPrimitiveType::eTypeDouble: - return eEncodingIEEE754; - case JavaPrimitiveType::eTypeBoolean: - case JavaPrimitiveType::eTypeChar: - return eEncodingUint; - } - } - if (IsReferenceType(type)) - return eEncodingUint; - return eEncodingInvalid; -} - -lldb::Format JavaASTContext::GetFormat(lldb::opaque_compiler_type_t type) { - if (JavaPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case JavaPrimitiveType::eTypeByte: - case JavaPrimitiveType::eTypeShort: - case JavaPrimitiveType::eTypeInt: - case JavaPrimitiveType::eTypeLong: - return eFormatDecimal; - case JavaPrimitiveType::eTypeFloat: - case JavaPrimitiveType::eTypeDouble: - return eFormatFloat; - case JavaPrimitiveType::eTypeBoolean: - return eFormatBoolean; - case JavaPrimitiveType::eTypeChar: - return eFormatUnicode16; - } - } - if (IsReferenceType(type)) - return eFormatHex; - return eFormatDefault; -} - -unsigned JavaASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) { - return 0; -} - -size_t -JavaASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) { - assert(false && "Not implemented"); - return 0; -} - -size_t -JavaASTContext::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { - return 0; -} - -uint32_t JavaASTContext::GetNumFields(lldb::opaque_compiler_type_t type) { - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - return obj->GetNumFields(); - } - return 0; -} - -CompilerType JavaASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, std::string &name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) { - if (bit_offset_ptr) - *bit_offset_ptr = 0; - if (bitfield_bit_size_ptr) - *bitfield_bit_size_ptr = 0; - if (is_bitfield_ptr) - *is_bitfield_ptr = false; - - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - - JavaObjectType::Field *field = obj->GetFieldAtIndex(idx); - if (!field) - return CompilerType(); - name = field->m_name.AsCString(); - if (bit_offset_ptr) - *bit_offset_ptr = field->m_offset * 8; - return field->m_type; - } - return CompilerType(); -} - -uint32_t JavaASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) { - GetCompleteType(type); - - if (JavaReferenceType *ref = - llvm::dyn_cast(static_cast(type))) - return ref->GetPointeeType().GetNumChildren(omit_empty_base_classes); - - if (llvm::isa(static_cast(type))) - return GetNumFields(type) + GetNumDirectBaseClasses(type); - - return 0; -} - -uint32_t -JavaASTContext::GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) { - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - return obj->GetNumInterfaces() + (obj->GetBaseClass() ? 1 : 0); - } - return 0; -} - -uint32_t -JavaASTContext::GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) { - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - return obj->GetNumInterfaces(); - } - return 0; -} - -CompilerType JavaASTContext::GetDirectBaseClassAtIndex( - lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - - if (CompilerType base_class = obj->GetBaseClass()) { - if (idx == 0) - return base_class; - else - --idx; - } - return obj->GetInterfaceAtIndex(idx); - } - return CompilerType(); -} - -CompilerType JavaASTContext::GetVirtualBaseClassAtIndex( - lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) { - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - return obj->GetInterfaceAtIndex(idx); - } - return CompilerType(); -} - -void JavaASTContext::DumpValue( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, - lldb::Format format, const DataExtractor &data, lldb::offset_t data_offset, - size_t data_byte_size, uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, bool show_types, bool show_summary, - bool verbose, uint32_t depth) { - assert(false && "Not implemented"); -} - -bool JavaASTContext::DumpTypeValue( - lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, - const DataExtractor &data, lldb::offset_t data_offset, - size_t data_byte_size, uint32_t bitfield_bit_size, - uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) { - if (IsScalarType(type)) { - return DumpDataExtractor(data, s, data_offset, format, data_byte_size, - 1, // count - UINT32_MAX, LLDB_INVALID_ADDRESS, - bitfield_bit_size, bitfield_bit_offset, exe_scope); - } - return false; -} - -void JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) { - StreamFile s(stdout, false); - DumpTypeDescription(type, &s); -} - -void JavaASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s) { - static_cast(type)->Dump(s); -} - -void JavaASTContext::DumpSummary(lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size) { - assert(false && "Not implemented"); -} - -int JavaASTContext::GetFunctionArgumentCount( - lldb::opaque_compiler_type_t type) { - return 0; -} - -CompilerType JavaASTContext::GetFunctionArgumentTypeAtIndex( - lldb::opaque_compiler_type_t type, size_t idx) { - return CompilerType(); -} - -CompilerType -JavaASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) { - return CompilerType(); -} - -size_t -JavaASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) { - return 0; -} - -TypeMemberFunctionImpl -JavaASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) { - return TypeMemberFunctionImpl(); -} - -CompilerType JavaASTContext::GetChildCompilerTypeAtIndex( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, - ValueObject *valobj, uint64_t &language_flags) { - child_name.clear(); - child_byte_size = 0; - child_byte_offset = 0; - child_bitfield_bit_size = 0; - child_bitfield_bit_offset = 0; - child_is_base_class = false; - child_is_deref_of_parent = false; - language_flags = 0; - - ExecutionContextScope *exec_ctx_scope = - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr; - - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - - if (CompilerType base_class = obj->GetBaseClass()) { - if (idx == 0) { - JavaType *base_class_type = - static_cast(base_class.GetOpaqueQualType()); - child_name = base_class_type->GetName().GetCString(); - child_byte_size = base_class.GetByteSize( - exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr); - child_byte_offset = obj->GetBaseClassOffset(); - child_is_base_class = true; - return base_class; - } - idx -= 1; - } - - JavaObjectType::Field *field = obj->GetFieldAtIndex(idx); - if (!field) - return CompilerType(); - - child_name = field->m_name.AsCString(); - child_byte_size = field->m_type.GetByteSize(exec_ctx_scope); - child_byte_offset = field->m_offset; - return field->m_type; - } else if (JavaReferenceType *ref = llvm::dyn_cast( - static_cast(type))) { - CompilerType pointee_type = ref->GetPointeeType(); - - if (transparent_pointers) - return pointee_type.GetChildCompilerTypeAtIndex( - exe_ctx, idx, transparent_pointers, omit_empty_base_classes, - ignore_array_bounds, child_name, child_byte_size, child_byte_offset, - child_bitfield_bit_size, child_bitfield_bit_offset, - child_is_base_class, child_is_deref_of_parent, valobj, - language_flags); - - if (idx != 0) - return CompilerType(); - - if (valobj && valobj->GetName()) - child_name = valobj->GetName().GetCString(); - child_is_deref_of_parent = true; - child_byte_offset = 0; - child_byte_size = pointee_type.GetByteSize(exec_ctx_scope); - return pointee_type; - } - return CompilerType(); -} - -uint32_t -JavaASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes) { - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - - uint32_t index_offset = 0; - if (CompilerType base_class = obj->GetBaseClass()) { - if (base_class.GetTypeName() == ConstString(name)) - return 0; - index_offset = 1; - } - for (uint32_t i = 0; i < obj->GetNumFields(); ++i) { - if (obj->GetFieldAtIndex(i)->m_name == ConstString(name)) - return i + index_offset; - } - } else if (JavaReferenceType *ref = llvm::dyn_cast( - static_cast(type))) { - return GetIndexOfChildWithName(ref->GetPointeeType().GetOpaqueQualType(), - name, omit_empty_base_classes); - } - return UINT_MAX; -} - -size_t JavaASTContext::GetIndexOfChildMemberWithName( - lldb::opaque_compiler_type_t type, const char *name, - bool omit_empty_base_classes, std::vector &child_indexes) { - child_indexes.clear(); - - if (JavaObjectType *obj = - llvm::dyn_cast(static_cast(type))) { - GetCompleteType(type); - - uint32_t index_offset = 0; - if (CompilerType base_class = obj->GetBaseClass()) { - if (GetIndexOfChildMemberWithName(base_class.GetOpaqueQualType(), name, - omit_empty_base_classes, - child_indexes) != 0) { - child_indexes.insert(child_indexes.begin(), 0); - return child_indexes.size(); - } - index_offset = 1; - } - - for (uint32_t i = 0; i < obj->GetNumFields(); ++i) { - if (obj->GetFieldAtIndex(i)->m_name == ConstString(name)) { - child_indexes.push_back(i + index_offset); - return child_indexes.size(); - } - } - } else if (JavaReferenceType *ref = llvm::dyn_cast( - static_cast(type))) { - return GetIndexOfChildMemberWithName( - ref->GetPointeeType().GetOpaqueQualType(), name, - omit_empty_base_classes, child_indexes); - } - return 0; -} - -CompilerType -JavaASTContext::GetLValueReferenceType(lldb::opaque_compiler_type_t type) { - return CreateReferenceType(CompilerType(this, type)); -} - -ConstString JavaASTContext::DeclContextGetScopeQualifiedName( - lldb::opaque_compiler_type_t opaque_decl_ctx) { - return GetTypeName(opaque_decl_ctx); -} - -static void AddPrimitiveType(JavaASTContext::JavaTypeMap &type_map, - JavaPrimitiveType::TypeKind type_kind) { - JavaPrimitiveType *type = new JavaPrimitiveType(type_kind); - type_map.emplace(type->GetName(), - std::unique_ptr(type)); -} - -CompilerType JavaASTContext::CreateBaseType(const ConstString &name) { - if (m_base_type_map.empty()) { - AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeByte); - AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeShort); - AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeInt); - AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeLong); - AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeFloat); - AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeDouble); - AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeBoolean); - AddPrimitiveType(m_base_type_map, JavaPrimitiveType::eTypeChar); - } - auto it = m_base_type_map.find(name); - if (it != m_base_type_map.end()) - return CompilerType(this, it->second.get()); - return CompilerType(); -} - -CompilerType JavaASTContext::CreateObjectType(const ConstString &name, - const ConstString &linkage_name, - uint32_t byte_size) { - auto it = m_object_type_map.find(name); - if (it == m_object_type_map.end()) { - std::unique_ptr object_type( - new JavaObjectType(name, linkage_name, byte_size)); - it = m_object_type_map.emplace(name, std::move(object_type)).first; - } - return CompilerType(this, it->second.get()); -} - -CompilerType JavaASTContext::CreateArrayType( - const ConstString &linkage_name, const CompilerType &element_type, - const DWARFExpression &length_expression, const lldb::addr_t data_offset) { - ConstString name = element_type.GetTypeName(); - auto it = m_array_type_map.find(name); - if (it == m_array_type_map.end()) { - std::unique_ptr array_type(new JavaArrayType( - linkage_name, element_type, length_expression, data_offset)); - it = m_array_type_map.emplace(name, std::move(array_type)).first; - } - return CompilerType(this, it->second.get()); -} - -CompilerType -JavaASTContext::CreateReferenceType(const CompilerType &pointee_type) { - ConstString name = pointee_type.GetTypeName(); - auto it = m_reference_type_map.find(name); - if (it == m_reference_type_map.end()) - it = m_reference_type_map - .emplace(name, std::unique_ptr( - new JavaReferenceType(pointee_type))) - .first; - return CompilerType(this, it->second.get()); -} - -void JavaASTContext::CompleteObjectType(const CompilerType &object_type) { - JavaObjectType *obj = llvm::dyn_cast( - static_cast(object_type.GetOpaqueQualType())); - assert(obj && - "JavaASTContext::CompleteObjectType called with not a JavaObjectType"); - obj->SetCompleteType(true); -} - -void JavaASTContext::AddBaseClassToObject(const CompilerType &object_type, - const CompilerType &member_type, - uint32_t member_offset) { - JavaObjectType *obj = llvm::dyn_cast( - static_cast(object_type.GetOpaqueQualType())); - assert(obj && - "JavaASTContext::AddMemberToObject called with not a JavaObjectType"); - obj->AddBaseClass(member_type, member_offset); -} - -void JavaASTContext::AddMemberToObject(const CompilerType &object_type, - const ConstString &name, - const CompilerType &member_type, - uint32_t member_offset) { - JavaObjectType *obj = llvm::dyn_cast( - static_cast(object_type.GetOpaqueQualType())); - assert(obj && - "JavaASTContext::AddMemberToObject called with not a JavaObjectType"); - obj->AddField(name, member_type, member_offset); -} - -void JavaASTContext::SetDynamicTypeId(const CompilerType &type, - const DWARFExpression &type_id) { - JavaObjectType *obj = llvm::dyn_cast( - static_cast(type.GetOpaqueQualType())); - assert(obj && - "JavaASTContext::SetDynamicTypeId called with not a JavaObjectType"); - obj->SetDynamicTypeId(type_id); -} - -uint64_t JavaASTContext::CalculateDynamicTypeId(ExecutionContext *exe_ctx, - const CompilerType &type, - ValueObject &in_value) { - if (JavaObjectType *obj = llvm::dyn_cast( - static_cast(type.GetOpaqueQualType()))) - return obj->CalculateDynamicTypeId(exe_ctx, in_value); - if (JavaArrayType *arr = llvm::dyn_cast( - static_cast(type.GetOpaqueQualType()))) - return arr->CalculateDynamicTypeId(exe_ctx, in_value); - return UINT64_MAX; -} - -uint32_t JavaASTContext::CalculateArraySize(const CompilerType &type, - ValueObject &in_value) { - if (JavaArrayType *arr = llvm::dyn_cast( - static_cast(type.GetOpaqueQualType()))) - return arr->GetNumElements(&in_value); - return UINT32_MAX; -} - -uint64_t JavaASTContext::CalculateArrayElementOffset(const CompilerType &type, - size_t index) { - if (JavaArrayType *arr = llvm::dyn_cast( - static_cast(type.GetOpaqueQualType()))) - return arr->GetElementOffset(index); - return UINT64_MAX; -} - -ConstString JavaASTContext::GetLinkageName(const CompilerType &type) { - if (JavaObjectType *obj = llvm::dyn_cast( - static_cast(type.GetOpaqueQualType()))) - return obj->GetLinkageName(); - return ConstString(); -} diff --git a/contrib/llvm/tools/lldb/source/Symbol/LineEntry.cpp b/contrib/llvm/tools/lldb/source/Symbol/LineEntry.cpp index 21aa2557518d..bffcc5321b11 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/LineEntry.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/LineEntry.cpp @@ -50,7 +50,6 @@ bool LineEntry::IsValid() const { } bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const { - bool result = false; if (file) { if (show_fullpaths) file.Dump(s); @@ -59,14 +58,15 @@ bool LineEntry::DumpStopContext(Stream *s, bool show_fullpaths) const { if (line) s->PutChar(':'); - result = true; } - if (line) + if (line) { s->Printf("%u", line); - else - result = false; - - return result; + if (column) { + s->PutChar(':'); + s->Printf("%u", column); + } + } + return file || line; } bool LineEntry::Dump(Stream *s, Target *target, bool show_file, diff --git a/contrib/llvm/tools/lldb/source/Symbol/OCamlASTContext.cpp b/contrib/llvm/tools/lldb/source/Symbol/OCamlASTContext.cpp deleted file mode 100644 index 1456ebfa9dce..000000000000 --- a/contrib/llvm/tools/lldb/source/Symbol/OCamlASTContext.cpp +++ /dev/null @@ -1,670 +0,0 @@ -//===-- OCamlASTContext.cpp ----------------------------------------*- C++ -//-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Symbol/OCamlASTContext.h" -#include "lldb/Core/DumpDataExtractor.h" -#include "lldb/Core/Module.h" -#include "lldb/Core/PluginManager.h" -#include "lldb/Core/StreamFile.h" -#include "lldb/Core/ValueObject.h" -#include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/SymbolFile.h" -#include "lldb/Symbol/Type.h" -#include "lldb/Target/ExecutionContext.h" -#include "lldb/Target/Target.h" -#include "lldb/Utility/Log.h" - -#include "Plugins/SymbolFile/DWARF/DWARFASTParserOCaml.h" - -using namespace lldb; -using namespace lldb_private; - -namespace lldb_private { -class OCamlASTContext::OCamlType { -public: - enum LLVMCastKind { - eKindPrimitive, - eKindObject, - eKindReference, - eKindArray, - kNumKinds - }; - - OCamlType(LLVMCastKind kind) : m_kind(kind) {} - - virtual ~OCamlType() = default; - - virtual ConstString GetName() = 0; - - virtual void Dump(Stream *s) = 0; - - virtual bool IsCompleteType() = 0; - - LLVMCastKind getKind() const { return m_kind; } - -private: - LLVMCastKind m_kind; -}; - -} // end of namespace lldb_private - -namespace { - -class OCamlPrimitiveType : public OCamlASTContext::OCamlType { -public: - enum TypeKind { - eTypeInt, - }; - - OCamlPrimitiveType(TypeKind type_kind, uint32_t byte_size) - : OCamlType(OCamlType::eKindPrimitive), m_type_kind(type_kind), - m_type(ConstString()), m_byte_size(byte_size) {} - - OCamlPrimitiveType(TypeKind type_kind, ConstString s, uint32_t byte_size) - : OCamlType(OCamlType::eKindPrimitive), m_type_kind(type_kind), m_type(s), - m_byte_size(byte_size) {} - - ConstString GetName() override { - switch (m_type_kind) { - case eTypeInt: - return m_type; - } - return ConstString(); - } - - TypeKind GetTypeKind() { return m_type_kind; } - - void Dump(Stream *s) override { s->Printf("%s\n", GetName().GetCString()); } - - bool IsCompleteType() override { return true; } - - static bool classof(const OCamlType *ot) { - return ot->getKind() == OCamlType::eKindPrimitive; - } - - uint64_t GetByteSize() const { return m_byte_size; } - -private: - const TypeKind m_type_kind; - const ConstString m_type; - uint64_t m_byte_size; -}; -} - -OCamlASTContext::OCamlASTContext() - : TypeSystem(eKindOCaml), m_pointer_byte_size(0) {} - -OCamlASTContext::~OCamlASTContext() {} - -ConstString OCamlASTContext::GetPluginNameStatic() { - return ConstString("ocaml"); -} - -ConstString OCamlASTContext::GetPluginName() { - return OCamlASTContext::GetPluginNameStatic(); -} - -uint32_t OCamlASTContext::GetPluginVersion() { return 1; } - -lldb::TypeSystemSP OCamlASTContext::CreateInstance(lldb::LanguageType language, - Module *module, - Target *target) { - Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_LANGUAGE)); - - if (language == lldb::eLanguageTypeOCaml) { - std::shared_ptr ocaml_ast_sp; - ArchSpec arch; - - if (module) { - arch = module->GetArchitecture(); - - ObjectFile *objfile = module->GetObjectFile(); - ArchSpec object_arch; - - if (!objfile || !objfile->GetArchitecture(object_arch)) - return lldb::TypeSystemSP(); - - ocaml_ast_sp = std::shared_ptr(new OCamlASTContext); - - if (log) { - log->Printf( - "((Module*)%p) [%s]->GetOCamlASTContext() = %p", (void *)module, - module->GetFileSpec().GetFilename().AsCString(""), - (void *)ocaml_ast_sp.get()); - } - - } else if (target) { - arch = target->GetArchitecture(); - ocaml_ast_sp = std::shared_ptr( - new OCamlASTContextForExpr(target->shared_from_this())); - - if (log) { - log->Printf("((Target*)%p)->GetOCamlASTContext() = %p", (void *)target, - (void *)ocaml_ast_sp.get()); - } - } - - if (arch.IsValid()) { - ocaml_ast_sp->SetAddressByteSize(arch.GetAddressByteSize()); - return ocaml_ast_sp; - } - } - - return lldb::TypeSystemSP(); -} - -void OCamlASTContext::EnumerateSupportedLanguages( - std::set &languages_for_types, - std::set &languages_for_expressions) { - static std::vector s_supported_languages_for_types( - {lldb::eLanguageTypeOCaml}); - static std::vector s_supported_languages_for_expressions( - {}); - - languages_for_types.insert(s_supported_languages_for_types.begin(), - s_supported_languages_for_types.end()); - languages_for_expressions.insert( - s_supported_languages_for_expressions.begin(), - s_supported_languages_for_expressions.end()); -} - -void OCamlASTContext::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - "OCaml AST context plug-in", CreateInstance, - EnumerateSupportedLanguages); -} - -void OCamlASTContext::Terminate() { - PluginManager::UnregisterPlugin(CreateInstance); -} - -DWARFASTParser *OCamlASTContext::GetDWARFParser() { - if (!m_dwarf_ast_parser_ap) { - m_dwarf_ast_parser_ap.reset(new DWARFASTParserOCaml(*this)); - } - - return m_dwarf_ast_parser_ap.get(); -} - -bool OCamlASTContext::IsArrayType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size, - bool *is_incomplete) { - return false; -} - -bool OCamlASTContext::IsVectorType(lldb::opaque_compiler_type_t type, - CompilerType *element_type, uint64_t *size) { - return false; -} - -bool OCamlASTContext::IsAggregateType(lldb::opaque_compiler_type_t type) { - return false; -} - -bool OCamlASTContext::IsBeingDefined(lldb::opaque_compiler_type_t type) { - return false; -} - -bool OCamlASTContext::IsCharType(lldb::opaque_compiler_type_t type) { - return false; -} - -bool OCamlASTContext::IsCompleteType(lldb::opaque_compiler_type_t type) { - return static_cast(type)->IsCompleteType(); -} - -bool OCamlASTContext::IsConst(lldb::opaque_compiler_type_t type) { - return false; -} - -bool OCamlASTContext::IsCStringType(lldb::opaque_compiler_type_t type, - uint32_t &length) { - return false; -} - -bool OCamlASTContext::IsDefined(lldb::opaque_compiler_type_t type) { - return type != nullptr; -} - -bool OCamlASTContext::IsFloatingPointType(lldb::opaque_compiler_type_t type, - uint32_t &count, bool &is_complex) { - return false; -} - -bool OCamlASTContext::IsFunctionType(lldb::opaque_compiler_type_t type, - bool *is_variadic_ptr) { - return false; -} - -uint32_t -OCamlASTContext::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, - CompilerType *base_type_ptr) { - return false; -} - -size_t OCamlASTContext::GetNumberOfFunctionArguments( - lldb::opaque_compiler_type_t type) { - return 0; -} - -CompilerType -OCamlASTContext::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, - const size_t index) { - return CompilerType(); -} - -bool OCamlASTContext::IsFunctionPointerType(lldb::opaque_compiler_type_t type) { - return IsFunctionType(type); -} - -bool OCamlASTContext::IsBlockPointerType( - lldb::opaque_compiler_type_t type, - CompilerType *function_pointer_type_ptr) { - return false; -} - -bool OCamlASTContext::IsIntegerType(lldb::opaque_compiler_type_t type, - bool &is_signed) { - if (OCamlPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case OCamlPrimitiveType::eTypeInt: - is_signed = true; - return true; - } - } - - is_signed = false; - return false; -} - -bool OCamlASTContext::IsPolymorphicClass(lldb::opaque_compiler_type_t type) { - return false; -} - -bool OCamlASTContext::IsPossibleDynamicType(lldb::opaque_compiler_type_t type, - CompilerType *target_type, - bool check_cplusplus, - bool check_objc) { - return false; -} - -bool OCamlASTContext::IsRuntimeGeneratedType( - lldb::opaque_compiler_type_t type) { - return false; -} - -bool OCamlASTContext::IsPointerType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type) { - if (pointee_type) - pointee_type->Clear(); - return false; -} - -bool OCamlASTContext::IsPointerOrReferenceType( - lldb::opaque_compiler_type_t type, CompilerType *pointee_type) { - return IsPointerType(type, pointee_type); -} - -bool OCamlASTContext::IsReferenceType(lldb::opaque_compiler_type_t type, - CompilerType *pointee_type, - bool *is_rvalue) { - return false; -} - -bool OCamlASTContext::IsScalarType(lldb::opaque_compiler_type_t type) { - return llvm::isa(static_cast(type)); -} - -bool OCamlASTContext::IsTypedefType(lldb::opaque_compiler_type_t type) { - return false; -} - -bool OCamlASTContext::IsVoidType(lldb::opaque_compiler_type_t type) { - return false; -} - -bool OCamlASTContext::SupportsLanguage(lldb::LanguageType language) { - return language == lldb::eLanguageTypeOCaml; -} - -bool OCamlASTContext::GetCompleteType(lldb::opaque_compiler_type_t type) { - if (IsCompleteType(type)) - return true; - - return false; -} - -uint32_t OCamlASTContext::GetPointerByteSize() { return m_pointer_byte_size; } - -ConstString OCamlASTContext::GetTypeName(lldb::opaque_compiler_type_t type) { - if (type) - return static_cast(type)->GetName(); - - return ConstString(); -} - -uint32_t -OCamlASTContext::GetTypeInfo(lldb::opaque_compiler_type_t type, - CompilerType *pointee_or_element_compiler_type) { - if (pointee_or_element_compiler_type) - pointee_or_element_compiler_type->Clear(); - if (!type) - return 0; - - if (OCamlPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case OCamlPrimitiveType::eTypeInt: - return eTypeHasValue | eTypeIsBuiltIn | eTypeIsScalar | eTypeIsInteger | - eTypeIsSigned; - } - } - - return 0; -} - -lldb::TypeClass -OCamlASTContext::GetTypeClass(lldb::opaque_compiler_type_t type) { - if (llvm::isa(static_cast(type))) - return eTypeClassBuiltin; - - return lldb::eTypeClassInvalid; -} - -lldb::BasicType -OCamlASTContext::GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) { - return lldb::eBasicTypeInvalid; -} - -lldb::LanguageType -OCamlASTContext::GetMinimumLanguage(lldb::opaque_compiler_type_t type) { - return lldb::eLanguageTypeOCaml; -} - -unsigned OCamlASTContext::GetTypeQualifiers(lldb::opaque_compiler_type_t type) { - return 0; -} - -//---------------------------------------------------------------------- -// Creating related types -//---------------------------------------------------------------------- - -CompilerType -OCamlASTContext::GetArrayElementType(lldb::opaque_compiler_type_t type, - uint64_t *stride) { - return CompilerType(); -} - -CompilerType -OCamlASTContext::GetCanonicalType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -CompilerType -OCamlASTContext::GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -int OCamlASTContext::GetFunctionArgumentCount( - lldb::opaque_compiler_type_t type) { - return GetNumberOfFunctionArguments(type); -} - -CompilerType OCamlASTContext::GetFunctionArgumentTypeAtIndex( - lldb::opaque_compiler_type_t type, size_t idx) { - return GetFunctionArgumentAtIndex(type, idx); -} - -CompilerType -OCamlASTContext::GetFunctionReturnType(lldb::opaque_compiler_type_t type) { - return CompilerType(); -} - -size_t -OCamlASTContext::GetNumMemberFunctions(lldb::opaque_compiler_type_t type) { - return 0; -} - -TypeMemberFunctionImpl -OCamlASTContext::GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, - size_t idx) { - return TypeMemberFunctionImpl(); -} - -CompilerType -OCamlASTContext::GetNonReferenceType(lldb::opaque_compiler_type_t type) { - return CompilerType(this, type); -} - -CompilerType -OCamlASTContext::GetPointeeType(lldb::opaque_compiler_type_t type) { - return CompilerType(); -} - -CompilerType -OCamlASTContext::GetPointerType(lldb::opaque_compiler_type_t type) { - return CompilerType(); -} - -CompilerType -OCamlASTContext::GetTypedefedType(lldb::opaque_compiler_type_t type) { - return CompilerType(); -} - -CompilerType OCamlASTContext::GetBasicTypeFromAST(lldb::BasicType basic_type) { - return CompilerType(); -} - -CompilerType -OCamlASTContext::GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, - size_t bit_size) { - return CompilerType(); -} - -uint64_t OCamlASTContext::GetBitSize(lldb::opaque_compiler_type_t type, - ExecutionContextScope *exe_scope) { - if (OCamlPrimitiveType *ptype = - llvm::dyn_cast(static_cast(type))) { - switch (ptype->GetTypeKind()) { - case OCamlPrimitiveType::eTypeInt: - return ptype->GetByteSize() * 8; - } - } - return 0; -} - -lldb::Encoding OCamlASTContext::GetEncoding(lldb::opaque_compiler_type_t type, - uint64_t &count) { - count = 1; - bool is_signed; - if (IsIntegerType(type, is_signed)) - return is_signed ? lldb::eEncodingSint : lldb::eEncodingUint; - bool is_complex; - uint32_t complex_count; - if (IsFloatingPointType(type, complex_count, is_complex)) { - count = complex_count; - return lldb::eEncodingIEEE754; - } - if (IsPointerType(type)) - return lldb::eEncodingUint; - return lldb::eEncodingInvalid; -} - -lldb::Format OCamlASTContext::GetFormat(lldb::opaque_compiler_type_t type) { - if (!type) - return lldb::eFormatDefault; - return lldb::eFormatBytes; -} - -size_t OCamlASTContext::GetTypeBitAlign(lldb::opaque_compiler_type_t type) { - return 0; -} - -uint32_t OCamlASTContext::GetNumChildren(lldb::opaque_compiler_type_t type, - bool omit_empty_base_classes) { - if (!type || !GetCompleteType(type)) - return 0; - - return GetNumFields(type); -} - -uint32_t OCamlASTContext::GetNumFields(lldb::opaque_compiler_type_t type) { - if (!type || !GetCompleteType(type)) - return 0; - return 0; -} - -CompilerType OCamlASTContext::GetFieldAtIndex(lldb::opaque_compiler_type_t type, - size_t idx, std::string &name, - uint64_t *bit_offset_ptr, - uint32_t *bitfield_bit_size_ptr, - bool *is_bitfield_ptr) { - if (bit_offset_ptr) - *bit_offset_ptr = 0; - if (bitfield_bit_size_ptr) - *bitfield_bit_size_ptr = 0; - if (is_bitfield_ptr) - *is_bitfield_ptr = false; - - if (!type || !GetCompleteType(type)) - return CompilerType(); - - return CompilerType(); -} - -CompilerType OCamlASTContext::GetChildCompilerTypeAtIndex( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, - bool transparent_pointers, bool omit_empty_base_classes, - bool ignore_array_bounds, std::string &child_name, - uint32_t &child_byte_size, int32_t &child_byte_offset, - uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, - bool &child_is_base_class, bool &child_is_deref_of_parent, - ValueObject *valobj, uint64_t &language_flags) { - child_name.clear(); - child_byte_size = 0; - child_byte_offset = 0; - child_bitfield_bit_size = 0; - child_bitfield_bit_offset = 0; - child_is_base_class = false; - child_is_deref_of_parent = false; - language_flags = 0; - - if (!type || !GetCompleteType(type)) - return CompilerType(); - - return CompilerType(); -} - -uint32_t -OCamlASTContext::GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, - const char *name, - bool omit_empty_base_classes) { - if (!type || !GetCompleteType(type)) - return UINT_MAX; - - return UINT_MAX; -} - -size_t OCamlASTContext::GetIndexOfChildMemberWithName( - lldb::opaque_compiler_type_t type, const char *name, - bool omit_empty_base_classes, std::vector &child_indexes) { - uint32_t index = GetIndexOfChildWithName(type, name, omit_empty_base_classes); - if (index == UINT_MAX) - return 0; - child_indexes.push_back(index); - return 1; -} - -size_t -OCamlASTContext::ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, - const char *s, uint8_t *dst, - size_t dst_size) { - assert(false); - return 0; -} -//---------------------------------------------------------------------- -// Dumping types -//---------------------------------------------------------------------- - -void OCamlASTContext::DumpValue( - lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, - lldb::Format format, const DataExtractor &data, - lldb::offset_t data_byte_offset, size_t data_byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, bool show_types, - bool show_summary, bool verbose, uint32_t depth) { - if (!type) { - s->Printf("no type\n"); - return; - } - - s->Printf("no value\n"); - - if (show_summary) - DumpSummary(type, exe_ctx, s, data, data_byte_offset, data_byte_size); -} - -bool OCamlASTContext::DumpTypeValue( - lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, - const DataExtractor &data, lldb::offset_t byte_offset, size_t byte_size, - uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset, - ExecutionContextScope *exe_scope) { - if (!type) { - s->Printf("no type value\n"); - return false; - } - - if (IsScalarType(type)) { - return DumpDataExtractor(data, s, byte_offset, format, byte_size, 1, - SIZE_MAX, LLDB_INVALID_ADDRESS, bitfield_bit_size, - bitfield_bit_offset, exe_scope); - } - - return false; -} - -void OCamlASTContext::DumpSummary(lldb::opaque_compiler_type_t type, - ExecutionContext *exe_ctx, Stream *s, - const DataExtractor &data, - lldb::offset_t data_offset, - size_t data_byte_size) { - s->Printf("no summary\n"); -} - -void OCamlASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type) { - StreamFile s(stdout, false); - DumpTypeDescription(type, &s); -} - -void OCamlASTContext::DumpTypeDescription(lldb::opaque_compiler_type_t type, - Stream *s) { - static_cast(type)->Dump(s); -} - -CompilerType OCamlASTContext::CreateBaseType(const ConstString &name, - uint64_t byte_size) { - if (m_base_type_map.empty()) { - OCamlPrimitiveType *type = new OCamlPrimitiveType( - OCamlPrimitiveType::eTypeInt, ConstString("ocaml_int"), byte_size); - m_base_type_map.emplace(type->GetName(), - std::unique_ptr(type)); - } - - auto it = m_base_type_map.find(name); - if (it == m_base_type_map.end()) { - OCamlPrimitiveType *type = - new OCamlPrimitiveType(OCamlPrimitiveType::eTypeInt, name, byte_size); - it = m_base_type_map - .emplace(name, std::unique_ptr(type)) - .first; - } - - return CompilerType(this, it->second.get()); -} diff --git a/contrib/llvm/tools/lldb/source/Symbol/ObjectFile.cpp b/contrib/llvm/tools/lldb/source/Symbol/ObjectFile.cpp index 59012b1f8261..86c18c7beb0b 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/ObjectFile.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/ObjectFile.cpp @@ -19,7 +19,6 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" -#include "lldb/Utility/DataBufferLLVM.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Timer.h" @@ -47,7 +46,7 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, FileSpec archive_file; ObjectContainerCreateInstance create_object_container_callback; - const bool file_exists = file->Exists(); + const bool file_exists = FileSystem::Instance().Exists(*file); if (!data_sp) { // We have an object name which most likely means we have a .o file in // a static archive (.a file). Try and see if we have a cached archive @@ -75,8 +74,8 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, // container plug-ins can use these bytes to see if they can parse this // file. if (file_size > 0) { - data_sp = - DataBufferLLVM::CreateSliceFromPath(file->GetPath(), 512, file_offset); + data_sp = FileSystem::Instance().CreateDataBuffer(file->GetPath(), + 512, file_offset); data_offset = 0; } } @@ -91,7 +90,7 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, const bool must_exist = true; if (ObjectFile::SplitArchivePathWithObject( path_with_object, archive_file, archive_object, must_exist)) { - file_size = archive_file.GetByteSize(); + file_size = FileSystem::Instance().GetByteSize(archive_file); if (file_size > 0) { file = &archive_file; module_sp->SetFileSpecAndObjectName(archive_file, archive_object); @@ -120,8 +119,8 @@ ObjectFile::FindPlugin(const lldb::ModuleSP &module_sp, const FileSpec *file, } // We failed to find any cached object files in the container plug- // ins, so lets read the first 512 bytes and try again below... - data_sp = DataBufferLLVM::CreateSliceFromPath(archive_file.GetPath(), - 512, file_offset); + data_sp = FileSystem::Instance().CreateDataBuffer( + archive_file.GetPath(), 512, file_offset); } } } @@ -209,10 +208,12 @@ size_t ObjectFile::GetModuleSpecifications(const FileSpec &file, lldb::offset_t file_offset, lldb::offset_t file_size, ModuleSpecList &specs) { - DataBufferSP data_sp = DataBufferLLVM::CreateSliceFromPath(file.GetPath(), 512, file_offset); + DataBufferSP data_sp = + FileSystem::Instance().CreateDataBuffer(file.GetPath(), 512, file_offset); if (data_sp) { if (file_size == 0) { - const lldb::offset_t actual_file_size = file.GetByteSize(); + const lldb::offset_t actual_file_size = + FileSystem::Instance().GetByteSize(file); if (actual_file_size > file_offset) file_size = actual_file_size - file_offset; } @@ -344,21 +345,28 @@ AddressClass ObjectFile::GetAddressClass(addr_t file_addr) { return AddressClass::eData; case eSectionTypeDebug: case eSectionTypeDWARFDebugAbbrev: + case eSectionTypeDWARFDebugAbbrevDwo: case eSectionTypeDWARFDebugAddr: case eSectionTypeDWARFDebugAranges: case eSectionTypeDWARFDebugCuIndex: case eSectionTypeDWARFDebugFrame: case eSectionTypeDWARFDebugInfo: + case eSectionTypeDWARFDebugInfoDwo: case eSectionTypeDWARFDebugLine: + case eSectionTypeDWARFDebugLineStr: case eSectionTypeDWARFDebugLoc: + case eSectionTypeDWARFDebugLocLists: case eSectionTypeDWARFDebugMacInfo: case eSectionTypeDWARFDebugMacro: case eSectionTypeDWARFDebugNames: case eSectionTypeDWARFDebugPubNames: case eSectionTypeDWARFDebugPubTypes: case eSectionTypeDWARFDebugRanges: + case eSectionTypeDWARFDebugRngLists: case eSectionTypeDWARFDebugStr: + case eSectionTypeDWARFDebugStrDwo: case eSectionTypeDWARFDebugStrOffsets: + case eSectionTypeDWARFDebugStrOffsetsDwo: case eSectionTypeDWARFDebugTypes: case eSectionTypeDWARFAppleNames: case eSectionTypeDWARFAppleTypes: @@ -578,11 +586,9 @@ bool ObjectFile::SplitArchivePathWithObject(const char *path_with_object, std::string obj; if (regex_match.GetMatchAtIndex(path_with_object, 1, path) && regex_match.GetMatchAtIndex(path_with_object, 2, obj)) { - archive_file.SetFile(path, false, FileSpec::Style::native); + archive_file.SetFile(path, FileSpec::Style::native); archive_object.SetCString(obj.c_str()); - if (must_exist && !archive_file.Exists()) - return false; - return true; + return !(must_exist && !FileSystem::Instance().Exists(archive_file)); } } return false; @@ -678,5 +684,65 @@ void ObjectFile::RelocateSection(lldb_private::Section *section) DataBufferSP ObjectFile::MapFileData(const FileSpec &file, uint64_t Size, uint64_t Offset) { - return DataBufferLLVM::CreateSliceFromPath(file.GetPath(), Size, Offset); + return FileSystem::Instance().CreateDataBuffer(file.GetPath(), Size, Offset); +} + +void llvm::format_provider::format( + const ObjectFile::Type &type, raw_ostream &OS, StringRef Style) { + switch (type) { + case ObjectFile::eTypeInvalid: + OS << "invalid"; + break; + case ObjectFile::eTypeCoreFile: + OS << "core file"; + break; + case ObjectFile::eTypeExecutable: + OS << "executable"; + break; + case ObjectFile::eTypeDebugInfo: + OS << "debug info"; + break; + case ObjectFile::eTypeDynamicLinker: + OS << "dynamic linker"; + break; + case ObjectFile::eTypeObjectFile: + OS << "object file"; + break; + case ObjectFile::eTypeSharedLibrary: + OS << "shared library"; + break; + case ObjectFile::eTypeStubLibrary: + OS << "stub library"; + break; + case ObjectFile::eTypeJIT: + OS << "jit"; + break; + case ObjectFile::eTypeUnknown: + OS << "unknown"; + break; + } +} + +void llvm::format_provider::format( + const ObjectFile::Strata &strata, raw_ostream &OS, StringRef Style) { + switch (strata) { + case ObjectFile::eStrataInvalid: + OS << "invalid"; + break; + case ObjectFile::eStrataUnknown: + OS << "unknown"; + break; + case ObjectFile::eStrataUser: + OS << "user"; + break; + case ObjectFile::eStrataKernel: + OS << "kernel"; + break; + case ObjectFile::eStrataRawImage: + OS << "raw image"; + break; + case ObjectFile::eStrataJIT: + OS << "jit"; + break; + } } diff --git a/contrib/llvm/tools/lldb/source/Symbol/Symbol.cpp b/contrib/llvm/tools/lldb/source/Symbol/Symbol.cpp index 69fd5424bd9a..8d055c1c6712 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/Symbol.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/Symbol.cpp @@ -141,7 +141,7 @@ FileSpec Symbol::GetReExportedSymbolSharedLibrary() const { // back into a string that is the re-exported name. intptr_t str_ptr = m_addr_range.GetByteSize(); if (str_ptr != 0) - return FileSpec((const char *)str_ptr, false); + return FileSpec((const char *)str_ptr); } return FileSpec(); } diff --git a/contrib/llvm/tools/lldb/source/Symbol/SymbolContext.cpp b/contrib/llvm/tools/lldb/source/Symbol/SymbolContext.cpp index 8716f50a384d..da00875bfa15 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/SymbolContext.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/SymbolContext.cpp @@ -105,12 +105,12 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, if (function != nullptr) { SymbolContext inline_parent_sc; Address inline_parent_addr; - if (show_function_name == false) { + if (!show_function_name) { s->Printf("<"); dumped_something = true; } else { ConstString name; - if (show_function_arguments == false) + if (!show_function_arguments) name = function->GetNameNoArguments(); if (!name) name = function->GetName(); @@ -122,7 +122,7 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, const addr_t function_offset = addr.GetOffset() - function->GetAddressRange().GetBaseAddress().GetOffset(); - if (show_function_name == false) { + if (!show_function_name) { // Print +offset even if offset is 0 dumped_something = true; s->Printf("+%" PRIu64 ">", function_offset); @@ -171,7 +171,7 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, } } } else if (symbol != nullptr) { - if (show_function_name == false) { + if (!show_function_name) { s->Printf("<"); dumped_something = true; } else if (symbol->GetName()) { @@ -184,7 +184,7 @@ bool SymbolContext::DumpStopContext(Stream *s, ExecutionContextScope *exe_scope, if (addr.IsValid() && symbol->ValueIsAddress()) { const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRef().GetOffset(); - if (show_function_name == false) { + if (!show_function_name) { // Print +offset even if offset is 0 dumped_something = true; s->Printf("+%" PRIu64 ">", symbol_offset); @@ -393,12 +393,7 @@ bool lldb_private::operator==(const SymbolContext &lhs, bool lldb_private::operator!=(const SymbolContext &lhs, const SymbolContext &rhs) { - return lhs.function != rhs.function || lhs.symbol != rhs.symbol || - lhs.module_sp.get() != rhs.module_sp.get() || - lhs.comp_unit != rhs.comp_unit || - lhs.target_sp.get() != rhs.target_sp.get() || - LineEntry::Compare(lhs.line_entry, rhs.line_entry) != 0 || - lhs.variable != rhs.variable; + return !(lhs == rhs); } bool SymbolContext::GetAddressRange(uint32_t scope, uint32_t range_idx, @@ -801,14 +796,14 @@ bool SymbolContext::GetAddressRangeFromHereToEndLine(uint32_t end_line, const Symbol * SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error) { error.Clear(); - + if (!target_sp) { return nullptr; } - + Target &target = *target_sp; Module *module = module_sp.get(); - + auto ProcessMatches = [this, &name, &target, module] (SymbolContextList &sc_list, Status &error) -> const Symbol* { llvm::SmallVector external_symbols; @@ -820,7 +815,7 @@ SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error) if (sym_ctx.symbol) { const Symbol *symbol = sym_ctx.symbol; const Address sym_address = symbol->GetAddress(); - + if (sym_address.IsValid()) { switch (symbol->GetType()) { case eSymbolTypeData: @@ -865,12 +860,12 @@ SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error) if (name == symbol->GetReExportedSymbolName() && module == reexport_module_sp.get()) return nullptr; - + return FindBestGlobalDataSymbol( symbol->GetReExportedSymbolName(), error); } } break; - + case eSymbolTypeCode: // We already lookup functions elsewhere case eSymbolTypeVariable: case eSymbolTypeLocal: @@ -898,7 +893,7 @@ SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error) } } } - + if (external_symbols.size() > 1) { StreamString ss; ss.Printf("Multiple external symbols found for '%s'\n", name.AsCString()); @@ -925,32 +920,32 @@ SymbolContext::FindBestGlobalDataSymbol(const ConstString &name, Status &error) return nullptr; } }; - + if (module) { SymbolContextList sc_list; module->FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); const Symbol *const module_symbol = ProcessMatches(sc_list, error); - + if (!error.Success()) { return nullptr; } else if (module_symbol) { return module_symbol; } } - + { SymbolContextList sc_list; target.GetImages().FindSymbolsWithNameAndType(name, eSymbolTypeAny, sc_list); const Symbol *const target_symbol = ProcessMatches(sc_list, error); - + if (!error.Success()) { return nullptr; } else if (target_symbol) { return target_symbol; } } - + return nullptr; // no error; we just didn't find anything } @@ -999,7 +994,7 @@ bool SymbolContextSpecifier::AddSpecification(const char *spec_string, break; case eModuleSpecified: { // See if we can find the Module, if so stick it in the SymbolContext. - FileSpec module_file_spec(spec_string, false); + FileSpec module_file_spec(spec_string); ModuleSpec module_spec(module_file_spec); lldb::ModuleSP module_sp( m_target_sp->GetImages().FindFirstModule(module_spec)); @@ -1013,7 +1008,7 @@ bool SymbolContextSpecifier::AddSpecification(const char *spec_string, // CompUnits can't necessarily be resolved here, since an inlined function // might show up in a number of CompUnits. Instead we just convert to a // FileSpec and store it away. - m_file_spec_ap.reset(new FileSpec(spec_string, false)); + m_file_spec_ap.reset(new FileSpec(spec_string)); m_type |= eFileSpecified; break; case eLineStartSpecified: @@ -1068,7 +1063,7 @@ bool SymbolContextSpecifier::SymbolContextMatches(SymbolContext &sc) { if (m_module_sp.get() != sc.module_sp.get()) return false; } else { - FileSpec module_file_spec(m_module_spec, false); + FileSpec module_file_spec(m_module_spec); if (!FileSpec::Equal(module_file_spec, sc.module_sp->GetFileSpec(), false)) return false; @@ -1259,7 +1254,7 @@ bool SymbolContextList::AppendIfUnique(const SymbolContext &sc, } if (merge_symbol_into_function && sc.symbol != nullptr && sc.comp_unit == nullptr && sc.function == nullptr && - sc.block == nullptr && sc.line_entry.IsValid() == false) { + sc.block == nullptr && !sc.line_entry.IsValid()) { if (sc.symbol->ValueIsAddress()) { for (pos = m_symbol_contexts.begin(); pos != end; ++pos) { // Don't merge symbols into inlined function symbol contexts @@ -1285,41 +1280,6 @@ bool SymbolContextList::AppendIfUnique(const SymbolContext &sc, return true; } -bool SymbolContextList::MergeSymbolContextIntoFunctionContext( - const SymbolContext &symbol_sc, uint32_t start_idx, uint32_t stop_idx) { - if (symbol_sc.symbol != nullptr && symbol_sc.comp_unit == nullptr && - symbol_sc.function == nullptr && symbol_sc.block == nullptr && - symbol_sc.line_entry.IsValid() == false) { - if (symbol_sc.symbol->ValueIsAddress()) { - const size_t end = std::min(m_symbol_contexts.size(), stop_idx); - for (size_t i = start_idx; i < end; ++i) { - const SymbolContext &function_sc = m_symbol_contexts[i]; - // Don't merge symbols into inlined function symbol contexts - if (function_sc.block && function_sc.block->GetContainingInlinedBlock()) - continue; - - if (function_sc.function) { - if (function_sc.function->GetAddressRange().GetBaseAddress() == - symbol_sc.symbol->GetAddressRef()) { - // Do we already have a function with this symbol? - if (function_sc.symbol == symbol_sc.symbol) - return true; // Already have a symbol context with this symbol, - // return true - - if (function_sc.symbol == nullptr) { - // We successfully merged this symbol into an existing symbol - // context - m_symbol_contexts[i].symbol = symbol_sc.symbol; - return true; - } - } - } - } - } - } - return false; -} - void SymbolContextList::Clear() { m_symbol_contexts.clear(); } void SymbolContextList::Dump(Stream *s, Target *target) const { @@ -1346,14 +1306,6 @@ bool SymbolContextList::GetContextAtIndex(size_t idx, SymbolContext &sc) const { return false; } -bool SymbolContextList::GetLastContext(SymbolContext &sc) const { - if (!m_symbol_contexts.empty()) { - sc = m_symbol_contexts.back(); - return true; - } - return false; -} - bool SymbolContextList::RemoveContextAtIndex(size_t idx) { if (idx < m_symbol_contexts.size()) { m_symbol_contexts.erase(m_symbol_contexts.begin() + idx); diff --git a/contrib/llvm/tools/lldb/source/Symbol/SymbolFile.cpp b/contrib/llvm/tools/lldb/source/Symbol/SymbolFile.cpp index 6b4da9c53009..6087374969fb 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/SymbolFile.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/SymbolFile.cpp @@ -19,12 +19,18 @@ #include "lldb/Utility/StreamString.h" #include "lldb/lldb-private.h" +#include + using namespace lldb_private; void SymbolFile::PreloadSymbols() { // No-op for most implementations. } +std::recursive_mutex &SymbolFile::GetModuleMutex() const { + return GetObjectFile()->GetModule()->GetMutex(); +} + SymbolFile *SymbolFile::FindPlugin(ObjectFile *obj_file) { std::unique_ptr best_symfile_ap; if (obj_file != nullptr) { @@ -91,7 +97,7 @@ TypeSystem *SymbolFile::GetTypeSystemForLanguage(lldb::LanguageType language) { uint32_t SymbolFile::ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, + lldb::SymbolContextItem resolve_scope, SymbolContextList &sc_list) { return 0; } @@ -111,7 +117,7 @@ uint32_t SymbolFile::FindGlobalVariables(const RegularExpression ®ex, uint32_t SymbolFile::FindFunctions(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, + lldb::FunctionNameType name_type_mask, bool include_inlines, bool append, SymbolContextList &sc_list) { if (!append) @@ -134,9 +140,8 @@ void SymbolFile::GetMangledNamesForFunction( } uint32_t SymbolFile::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { if (!append) @@ -150,3 +155,17 @@ size_t SymbolFile::FindTypes(const std::vector &context, types.Clear(); return 0; } + +void SymbolFile::AssertModuleLock() { + // The code below is too expensive to leave enabled in release builds. It's + // enabled in debug builds or when the correct macro is set. +#if defined(LLDB_CONFIGURATION_DEBUG) + // We assert that we have to module lock by trying to acquire the lock from a + // different thread. Note that we must abort if the result is true to + // guarantee correctness. + assert(std::async(std::launch::async, + [this] { return this->GetModuleMutex().try_lock(); }) + .get() == false && + "Module is not locked"); +#endif +} diff --git a/contrib/llvm/tools/lldb/source/Symbol/SymbolVendor.cpp b/contrib/llvm/tools/lldb/source/Symbol/SymbolVendor.cpp index 245f7bbf8add..a9badc15a5d6 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/SymbolVendor.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/SymbolVendor.cpp @@ -9,10 +9,6 @@ #include "lldb/Symbol/SymbolVendor.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Symbol/CompileUnit.h" @@ -61,7 +57,7 @@ SymbolVendor *SymbolVendor::FindPlugin(const lldb::ModuleSP &module_sp, //---------------------------------------------------------------------- SymbolVendor::SymbolVendor(const lldb::ModuleSP &module_sp) : ModuleChild(module_sp), m_type_list(), m_compile_units(), - m_sym_file_ap() {} + m_sym_file_ap(), m_symtab() {} //---------------------------------------------------------------------- // Destructor @@ -122,63 +118,62 @@ size_t SymbolVendor::GetNumCompileUnits() { return m_compile_units.size(); } -lldb::LanguageType -SymbolVendor::ParseCompileUnitLanguage(const SymbolContext &sc) { +lldb::LanguageType SymbolVendor::ParseLanguage(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseCompileUnitLanguage(sc); + return m_sym_file_ap->ParseLanguage(comp_unit); } return eLanguageTypeUnknown; } -size_t SymbolVendor::ParseCompileUnitFunctions(const SymbolContext &sc) { +size_t SymbolVendor::ParseFunctions(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseCompileUnitFunctions(sc); + return m_sym_file_ap->ParseFunctions(comp_unit); } return 0; } -bool SymbolVendor::ParseCompileUnitLineTable(const SymbolContext &sc) { +bool SymbolVendor::ParseLineTable(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseCompileUnitLineTable(sc); + return m_sym_file_ap->ParseLineTable(comp_unit); } return false; } -bool SymbolVendor::ParseCompileUnitDebugMacros(const SymbolContext &sc) { +bool SymbolVendor::ParseDebugMacros(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseCompileUnitDebugMacros(sc); + return m_sym_file_ap->ParseDebugMacros(comp_unit); } return false; } -bool SymbolVendor::ParseCompileUnitSupportFiles(const SymbolContext &sc, - FileSpecList &support_files) { +bool SymbolVendor::ParseSupportFiles(CompileUnit &comp_unit, + FileSpecList &support_files) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseCompileUnitSupportFiles(sc, support_files); + return m_sym_file_ap->ParseSupportFiles(comp_unit, support_files); } return false; } -bool SymbolVendor::ParseCompileUnitIsOptimized(const SymbolContext &sc) { +bool SymbolVendor::ParseIsOptimized(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseCompileUnitIsOptimized(sc); + return m_sym_file_ap->ParseIsOptimized(comp_unit); } return false; } @@ -194,22 +189,22 @@ bool SymbolVendor::ParseImportedModules( return false; } -size_t SymbolVendor::ParseFunctionBlocks(const SymbolContext &sc) { +size_t SymbolVendor::ParseBlocksRecursive(Function &func) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseFunctionBlocks(sc); + return m_sym_file_ap->ParseBlocksRecursive(func); } return 0; } -size_t SymbolVendor::ParseTypes(const SymbolContext &sc) { +size_t SymbolVendor::ParseTypes(CompileUnit &comp_unit) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->ParseTypes(sc); + return m_sym_file_ap->ParseTypes(comp_unit); } return 0; } @@ -235,7 +230,7 @@ Type *SymbolVendor::ResolveTypeUID(lldb::user_id_t type_uid) { } uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr, - uint32_t resolve_scope, + SymbolContextItem resolve_scope, SymbolContext &sc) { ModuleSP module_sp(GetModule()); if (module_sp) { @@ -248,7 +243,7 @@ uint32_t SymbolVendor::ResolveSymbolContext(const Address &so_addr, uint32_t SymbolVendor::ResolveSymbolContext(const FileSpec &file_spec, uint32_t line, bool check_inlines, - uint32_t resolve_scope, + SymbolContextItem resolve_scope, SymbolContextList &sc_list) { ModuleSP module_sp(GetModule()); if (module_sp) { @@ -288,7 +283,7 @@ size_t SymbolVendor::FindGlobalVariables(const RegularExpression ®ex, size_t SymbolVendor::FindFunctions(const ConstString &name, const CompilerDeclContext *parent_decl_ctx, - uint32_t name_type_mask, + FunctionNameType name_type_mask, bool include_inlines, bool append, SymbolContextList &sc_list) { ModuleSP module_sp(GetModule()); @@ -315,15 +310,15 @@ size_t SymbolVendor::FindFunctions(const RegularExpression ®ex, } size_t SymbolVendor::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, + const ConstString &name, const CompilerDeclContext *parent_decl_ctx, + bool append, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, append, + return m_sym_file_ap->FindTypes(name, parent_decl_ctx, append, max_matches, searched_symbol_files, types); } @@ -345,7 +340,7 @@ size_t SymbolVendor::FindTypes(const std::vector &context, return 0; } -size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, uint32_t type_mask, +size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, TypeClass type_mask, lldb_private::TypeList &type_list) { ModuleSP module_sp(GetModule()); if (module_sp) { @@ -357,15 +352,14 @@ size_t SymbolVendor::GetTypes(SymbolContextScope *sc_scope, uint32_t type_mask, } CompilerDeclContext -SymbolVendor::FindNamespace(const SymbolContext &sc, const ConstString &name, +SymbolVendor::FindNamespace(const ConstString &name, const CompilerDeclContext *parent_decl_ctx) { CompilerDeclContext namespace_decl_ctx; ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - namespace_decl_ctx = - m_sym_file_ap->FindNamespace(sc, name, parent_decl_ctx); + namespace_decl_ctx = m_sym_file_ap->FindNamespace(name, parent_decl_ctx); } return namespace_decl_ctx; } @@ -381,6 +375,7 @@ void SymbolVendor::Dump(Stream *s) { s->Indent(); s->PutCString("SymbolVendor"); if (m_sym_file_ap.get()) { + *s << " " << m_sym_file_ap->GetPluginName(); ObjectFile *objfile = m_sym_file_ap->GetObjectFile(); if (objfile) { const FileSpec &objfile_file_spec = objfile->GetFileSpec(); @@ -405,6 +400,9 @@ void SymbolVendor::Dump(Stream *s) { (*cu_pos)->Dump(s, show_context); } + if (Symtab *symtab = GetSymtab()) + symtab->Dump(s, nullptr, eSortOrderNone); + s->IndentLess(); } } @@ -438,14 +436,23 @@ FileSpec SymbolVendor::GetMainFileSpec() const { Symtab *SymbolVendor::GetSymtab() { ModuleSP module_sp(GetModule()); - if (module_sp) { - ObjectFile *objfile = module_sp->GetObjectFile(); - if (objfile) { - // Get symbol table from unified section list. - return objfile->GetSymtab(); - } - } - return nullptr; + if (!module_sp) + return nullptr; + + std::lock_guard guard(module_sp->GetMutex()); + + if (m_symtab) + return m_symtab; + + ObjectFile *objfile = module_sp->GetObjectFile(); + if (!objfile) + return nullptr; + + m_symtab = objfile->GetSymtab(); + if (m_symtab && m_sym_file_ap) + m_sym_file_ap->AddSymbols(*m_symtab); + + return m_symtab; } void SymbolVendor::ClearSymtab() { diff --git a/contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp b/contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp index c502b18555f0..2472580a41d5 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/Symtab.cpp @@ -10,9 +10,10 @@ #include #include -#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" + #include "lldb/Core/Module.h" +#include "lldb/Core/RichManglingContext.h" #include "lldb/Core/STLUtils.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/ObjectFile.h" @@ -23,6 +24,8 @@ #include "lldb/Utility/Stream.h" #include "lldb/Utility/Timer.h" +#include "llvm/ADT/StringRef.h" + using namespace lldb; using namespace lldb_private; @@ -136,6 +139,8 @@ void Symtab::Dump(Stream *s, Target *target, SortOrder sort_order) { } break; } + } else { + s->PutCString("\n"); } } @@ -215,6 +220,40 @@ const Symbol *Symtab::SymbolAtIndex(size_t idx) const { //---------------------------------------------------------------------- // InitNameIndexes //---------------------------------------------------------------------- +static bool lldb_skip_name(llvm::StringRef mangled, + Mangled::ManglingScheme scheme) { + switch (scheme) { + case Mangled::eManglingSchemeItanium: { + if (mangled.size() < 3 || !mangled.startswith("_Z")) + return true; + + // Avoid the following types of symbols in the index. + switch (mangled[2]) { + case 'G': // guard variables + case 'T': // virtual tables, VTT structures, typeinfo structures + names + case 'Z': // named local entities (if we eventually handle + // eSymbolTypeData, we will want this back) + return true; + + default: + break; + } + + // Include this name in the index. + return false; + } + + // No filters for this scheme yet. Include all names in indexing. + case Mangled::eManglingSchemeMSVC: + return false; + + // Don't try and demangle things we can't categorize. + case Mangled::eManglingSchemeNone: + return true; + } + llvm_unreachable("unknown scheme!"); +} + void Symtab::InitNameIndexes() { // Protected function, no need to lock mutex... if (!m_name_indexes_computed) { @@ -243,16 +282,19 @@ void Symtab::InitNameIndexes() { m_name_to_index.Reserve(actual_count); #endif + // The "const char *" in "class_contexts" and backlog::value_type::second + // must come from a ConstString::GetCString() + std::set class_contexts; + std::vector> backlog; + backlog.reserve(num_symbols / 2); + + // Instantiation of the demangler is expensive, so better use a single one + // for all entries during batch processing. + RichManglingContext rmc; NameToIndexMap::Entry entry; - // The "const char *" in "class_contexts" must come from a - // ConstString::GetCString() - std::set class_contexts; - UniqueCStringMap mangled_name_to_index; - std::vector symbol_contexts(num_symbols, nullptr); - for (entry.value = 0; entry.value < num_symbols; ++entry.value) { - const Symbol *symbol = &m_symbols[entry.value]; + Symbol *symbol = &m_symbols[entry.value]; // Don't let trampolines get into the lookup by name map If we ever need // the trampoline symbols to be searchable by name we can remove this and @@ -261,7 +303,9 @@ void Symtab::InitNameIndexes() { if (symbol->IsTrampoline()) continue; - const Mangled &mangled = symbol->GetMangled(); + // If the symbol's name string matched a Mangled::ManglingScheme, it is + // stored in the mangled field. + Mangled &mangled = symbol->GetMangled(); entry.cstring = mangled.GetMangledName(); if (entry.cstring) { m_name_to_index.Append(entry); @@ -274,70 +318,15 @@ void Symtab::InitNameIndexes() { m_name_to_index.Append(entry); } - const SymbolType symbol_type = symbol->GetType(); - if (symbol_type == eSymbolTypeCode || - symbol_type == eSymbolTypeResolver) { - llvm::StringRef entry_ref(entry.cstring.GetStringRef()); - if (entry_ref[0] == '_' && entry_ref[1] == 'Z' && - (entry_ref[2] != 'T' && // avoid virtual table, VTT structure, - // typeinfo structure, and typeinfo - // name - entry_ref[2] != 'G' && // avoid guard variables - entry_ref[2] != 'Z')) // named local entities (if we - // eventually handle eSymbolTypeData, - // we will want this back) - { - CPlusPlusLanguage::MethodName cxx_method( - mangled.GetDemangledName(lldb::eLanguageTypeC_plus_plus)); - entry.cstring = ConstString(cxx_method.GetBasename()); - if (entry.cstring) { - // ConstString objects permanently store the string in the pool - // so calling GetCString() on the value gets us a const char * - // that will never go away - const char *const_context = - ConstString(cxx_method.GetContext()).GetCString(); - - if (!const_context || const_context[0] == 0) { - // No context for this function so this has to be a basename - m_basename_to_index.Append(entry); - // If there is no context (no namespaces or class scopes that - // come before the function name) then this also could be a - // fullname. - m_name_to_index.Append(entry); - } else { - entry_ref = entry.cstring.GetStringRef(); - if (entry_ref[0] == '~' || - !cxx_method.GetQualifiers().empty()) { - // The first character of the demangled basename is '~' which - // means we have a class destructor. We can use this - // information to help us know what is a class and what - // isn't. - if (class_contexts.find(const_context) == class_contexts.end()) - class_contexts.insert(const_context); - m_method_to_index.Append(entry); - } else { - if (class_contexts.find(const_context) != - class_contexts.end()) { - // The current decl context is in our "class_contexts" - // which means this is a method on a class - m_method_to_index.Append(entry); - } else { - // We don't know if this is a function basename or a - // method, so put it into a temporary collection so once we - // are done we can look in class_contexts to see if each - // entry is a class or just a function and will put any - // remaining items into m_method_to_index or - // m_basename_to_index as needed - mangled_name_to_index.Append(entry); - symbol_contexts[entry.value] = const_context; - } - } - } - } - } + const SymbolType type = symbol->GetType(); + if (type == eSymbolTypeCode || type == eSymbolTypeResolver) { + if (mangled.DemangleWithRichManglingInfo(rmc, lldb_skip_name)) + RegisterMangledNameEntry(entry, class_contexts, backlog, rmc); } } + // Symbol name strings that didn't match a Mangled::ManglingScheme, are + // stored in the demangled field. entry.cstring = mangled.GetDemangledName(symbol->GetLanguage()); if (entry.cstring) { m_name_to_index.Append(entry); @@ -367,25 +356,10 @@ void Symtab::InitNameIndexes() { } } - size_t count; - if (!mangled_name_to_index.IsEmpty()) { - count = mangled_name_to_index.GetSize(); - for (size_t i = 0; i < count; ++i) { - if (mangled_name_to_index.GetValueAtIndex(i, entry.value)) { - entry.cstring = mangled_name_to_index.GetCStringAtIndex(i); - if (symbol_contexts[entry.value] && - class_contexts.find(symbol_contexts[entry.value]) != - class_contexts.end()) { - m_method_to_index.Append(entry); - } else { - // If we got here, we have something that had a context (was inside - // a namespace or class) yet we don't know if the entry - m_method_to_index.Append(entry); - m_basename_to_index.Append(entry); - } - } - } + for (const auto &record : backlog) { + RegisterBacklogEntry(record.first, record.second, class_contexts); } + m_name_to_index.Sort(); m_name_to_index.SizeToFit(); m_selector_to_index.Sort(); @@ -397,6 +371,71 @@ void Symtab::InitNameIndexes() { } } +void Symtab::RegisterMangledNameEntry( + NameToIndexMap::Entry &entry, std::set &class_contexts, + std::vector> &backlog, + RichManglingContext &rmc) { + // Only register functions that have a base name. + rmc.ParseFunctionBaseName(); + llvm::StringRef base_name = rmc.GetBufferRef(); + if (base_name.empty()) + return; + + // The base name will be our entry's name. + entry.cstring = ConstString(base_name); + + rmc.ParseFunctionDeclContextName(); + llvm::StringRef decl_context = rmc.GetBufferRef(); + + // Register functions with no context. + if (decl_context.empty()) { + // This has to be a basename + m_basename_to_index.Append(entry); + // If there is no context (no namespaces or class scopes that come before + // the function name) then this also could be a fullname. + m_name_to_index.Append(entry); + return; + } + + // Make sure we have a pool-string pointer and see if we already know the + // context name. + const char *decl_context_ccstr = ConstString(decl_context).GetCString(); + auto it = class_contexts.find(decl_context_ccstr); + + // Register constructors and destructors. They are methods and create + // declaration contexts. + if (rmc.IsCtorOrDtor()) { + m_method_to_index.Append(entry); + if (it == class_contexts.end()) + class_contexts.insert(it, decl_context_ccstr); + return; + } + + // Register regular methods with a known declaration context. + if (it != class_contexts.end()) { + m_method_to_index.Append(entry); + return; + } + + // Regular methods in unknown declaration contexts are put to the backlog. We + // will revisit them once we processed all remaining symbols. + backlog.push_back(std::make_pair(entry, decl_context_ccstr)); +} + +void Symtab::RegisterBacklogEntry( + const NameToIndexMap::Entry &entry, const char *decl_context, + const std::set &class_contexts) { + auto it = class_contexts.find(decl_context); + if (it != class_contexts.end()) { + m_method_to_index.Append(entry); + } else { + // If we got here, we have something that had a context (was inside + // a namespace or class) yet we don't know the entry + m_method_to_index.Append(entry); + m_basename_to_index.Append(entry); + } +} + void Symtab::PreloadSymbols() { std::lock_guard guard(m_mutex); InitNameIndexes(); @@ -571,10 +610,9 @@ void Symtab::SortSymbolIndexesByValue(std::vector &indexes, return; // Sort the indexes in place using std::stable_sort. - // NOTE: The use of std::stable_sort instead of std::sort here is strictly for - // performance, - // not correctness. The indexes vector tends to be "close" to sorted, which - // the stable sort handles better. + // NOTE: The use of std::stable_sort instead of llvm::sort here is strictly + // for performance, not correctness. The indexes vector tends to be "close" + // to sorted, which the stable sort handles better. std::vector addr_cache(m_symbols.size(), LLDB_INVALID_ADDRESS); @@ -701,7 +739,7 @@ uint32_t Symtab::AppendSymbolIndexesMatchingRegExAndType( for (uint32_t i = 0; i < sym_end; i++) { if (symbol_type == eSymbolTypeAny || m_symbols[i].GetType() == symbol_type) { - if (CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility) == false) + if (!CheckSymbolAtIndex(i, symbol_debug_type, symbol_visibility)) continue; const char *name = m_symbols[i].GetName().AsCString(); @@ -937,32 +975,8 @@ void Symtab::InitAddressIndexes() { void Symtab::CalculateSymbolSizes() { std::lock_guard guard(m_mutex); - - if (!m_symbols.empty()) { - if (!m_file_addr_to_index_computed) - InitAddressIndexes(); - - const size_t num_entries = m_file_addr_to_index.GetSize(); - - for (size_t i = 0; i < num_entries; ++i) { - // The entries in the m_file_addr_to_index have calculated the sizes - // already so we will use this size if we need to. - const FileRangeToIndexMap::Entry &entry = - m_file_addr_to_index.GetEntryRef(i); - - Symbol &symbol = m_symbols[entry.data]; - - // If the symbol size is already valid, no need to do anything - if (symbol.GetByteSizeIsValid()) - continue; - - const addr_t range_size = entry.GetByteSize(); - if (range_size > 0) { - symbol.SetByteSize(range_size); - symbol.SetSizeIsSynthesized(true); - } - } - } + // Size computation happens inside InitAddressIndexes. + InitAddressIndexes(); } Symbol *Symtab::FindSymbolAtFileAddress(addr_t file_addr) { @@ -1117,7 +1131,7 @@ size_t Symtab::FindFunctionSymbols(const ConstString &name, } if (!symbol_indexes.empty()) { - std::sort(symbol_indexes.begin(), symbol_indexes.end()); + llvm::sort(symbol_indexes.begin(), symbol_indexes.end()); symbol_indexes.erase( std::unique(symbol_indexes.begin(), symbol_indexes.end()), symbol_indexes.end()); diff --git a/contrib/llvm/tools/lldb/source/Symbol/Type.cpp b/contrib/llvm/tools/lldb/source/Symbol/Type.cpp index b62c55f76e2b..e966c269408a 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/Type.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/Type.cpp @@ -7,16 +7,12 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Module.h" -#include "lldb/Core/Scalar.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" +#include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" #include "lldb/Symbol/CompilerType.h" @@ -325,15 +321,16 @@ uint64_t Type::GetByteSize() { if (encoding_type) m_byte_size = encoding_type->GetByteSize(); if (m_byte_size == 0) - m_byte_size = GetLayoutCompilerType().GetByteSize(nullptr); + if (llvm::Optional size = + GetLayoutCompilerType().GetByteSize(nullptr)) + m_byte_size = *size; } break; // If we are a pointer or reference, then this is just a pointer size; case eEncodingIsPointerUID: case eEncodingIsLValueReferenceUID: case eEncodingIsRValueReferenceUID: { - ArchSpec arch; - if (m_symbol_file->GetObjectFile()->GetArchitecture(arch)) + if (ArchSpec arch = m_symbol_file->GetObjectFile()->GetArchitecture()) m_byte_size = arch.GetAddressByteSize(); } break; } @@ -342,7 +339,7 @@ uint64_t Type::GetByteSize() { } uint32_t Type::GetNumChildren(bool omit_empty_base_classes) { - return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes); + return GetForwardCompilerType().GetNumChildren(omit_empty_base_classes, nullptr); } bool Type::IsAggregateType() { @@ -714,11 +711,7 @@ bool TypeAndOrName::operator==(const TypeAndOrName &other) const { } bool TypeAndOrName::operator!=(const TypeAndOrName &other) const { - if (m_type_pair != other.m_type_pair) - return true; - if (m_type_name != other.m_type_name) - return true; - return false; + return !(*this == other); } ConstString TypeAndOrName::GetName() const { @@ -750,10 +743,7 @@ void TypeAndOrName::SetCompilerType(CompilerType compiler_type) { } bool TypeAndOrName::IsEmpty() const { - if ((bool)m_type_name || (bool)m_type_pair) - return false; - else - return true; + return !((bool)m_type_name || (bool)m_type_pair); } void TypeAndOrName::Clear() { @@ -878,8 +868,7 @@ bool TypeImpl::operator==(const TypeImpl &rhs) const { } bool TypeImpl::operator!=(const TypeImpl &rhs) const { - return m_static_type != rhs.m_static_type || - m_dynamic_type != rhs.m_dynamic_type; + return !(*this == rhs); } bool TypeImpl::IsValid() const { diff --git a/contrib/llvm/tools/lldb/source/Symbol/TypeList.cpp b/contrib/llvm/tools/lldb/source/Symbol/TypeList.cpp index 4a0a06f3e8e3..26a646e64693 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/TypeList.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/TypeList.cpp @@ -7,15 +7,11 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "llvm/Support/FormattedStream.h" #include "llvm/Support/raw_ostream.h" -// Project includes #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Type.h" @@ -184,8 +180,7 @@ void TypeList::RemoveMismatchedTypes(const std::string &type_scope, } else { // The type we are currently looking at doesn't exists in a namespace // or class, so it only matches if there is no type scope... - keep_match = - type_scope.empty() && type_basename.compare(match_type_name) == 0; + keep_match = type_scope.empty() && type_basename == match_type_name; } } diff --git a/contrib/llvm/tools/lldb/source/Symbol/TypeMap.cpp b/contrib/llvm/tools/lldb/source/Symbol/TypeMap.cpp index 2838039ad603..337278c202ed 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/TypeMap.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/TypeMap.cpp @@ -7,11 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" @@ -27,7 +24,6 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Support/raw_ostream.h" -// Project includes #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Type.h" @@ -227,8 +223,7 @@ void TypeMap::RemoveMismatchedTypes(const std::string &type_scope, } else { // The type we are currently looking at doesn't exists in a namespace // or class, so it only matches if there is no type scope... - keep_match = - type_scope.empty() && type_basename.compare(match_type_name) == 0; + keep_match = type_scope.empty() && type_basename == match_type_name; } } diff --git a/contrib/llvm/tools/lldb/source/Symbol/TypeSystem.cpp b/contrib/llvm/tools/lldb/source/Symbol/TypeSystem.cpp index b99f21e1e347..91d347edfc79 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/TypeSystem.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/TypeSystem.cpp @@ -101,6 +101,10 @@ CompilerType TypeSystem::GetTypeForFormatters(void *type) { return CompilerType(this, type); } +size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type) { + return 0; +} + TemplateArgumentKind TypeSystem::GetTemplateArgumentKind(opaque_compiler_type_t type, size_t idx) { return eTemplateArgumentKindNull; @@ -189,7 +193,7 @@ void TypeSystemMap::ForEach(std::function const &callback) { TypeSystem *type_system = pair.second.get(); if (type_system && !visited.count(type_system)) { visited.insert(type_system); - if (callback(type_system) == false) + if (!callback(type_system)) break; } } diff --git a/contrib/llvm/tools/lldb/source/Symbol/UnwindPlan.cpp b/contrib/llvm/tools/lldb/source/Symbol/UnwindPlan.cpp index 23ca1324ab06..0f8d9bf7e5a4 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/UnwindPlan.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/UnwindPlan.cpp @@ -29,6 +29,8 @@ operator==(const UnwindPlan::Row::RegisterLocation &rhs) const { case atCFAPlusOffset: case isCFAPlusOffset: + case atAFAPlusOffset: + case isAFAPlusOffset: return m_location.offset == rhs.m_location.offset; case inOtherRegister: @@ -95,6 +97,16 @@ void UnwindPlan::Row::RegisterLocation::Dump(Stream &s, s.PutChar(']'); } break; + case atAFAPlusOffset: + case isAFAPlusOffset: { + s.PutChar('='); + if (m_type == atAFAPlusOffset) + s.PutChar('['); + s.Printf("AFA%+d", m_location.offset); + if (m_type == atAFAPlusOffset) + s.PutChar(']'); + } break; + case inOtherRegister: { const RegisterInfo *other_reg_info = nullptr; if (unwind_plan) @@ -125,8 +137,8 @@ static void DumpRegisterName(Stream &s, const UnwindPlan *unwind_plan, s.Printf("reg(%u)", reg_num); } -bool UnwindPlan::Row::CFAValue:: -operator==(const UnwindPlan::Row::CFAValue &rhs) const { +bool UnwindPlan::Row::FAValue:: +operator==(const UnwindPlan::Row::FAValue &rhs) const { if (m_type == rhs.m_type) { switch (m_type) { case unspecified: @@ -148,7 +160,7 @@ operator==(const UnwindPlan::Row::CFAValue &rhs) const { return false; } -void UnwindPlan::Row::CFAValue::Dump(Stream &s, const UnwindPlan *unwind_plan, +void UnwindPlan::Row::FAValue::Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread) const { switch (m_type) { case isRegisterPlusOffset: @@ -171,6 +183,7 @@ void UnwindPlan::Row::CFAValue::Dump(Stream &s, const UnwindPlan *unwind_plan, void UnwindPlan::Row::Clear() { m_cfa_value.SetUnspecified(); + m_afa_value.SetUnspecified(); m_offset = 0; m_register_locations.clear(); } @@ -183,6 +196,12 @@ void UnwindPlan::Row::Dump(Stream &s, const UnwindPlan *unwind_plan, s.Printf("%4" PRId64 ": CFA=", GetOffset()); m_cfa_value.Dump(s, unwind_plan, thread); + + if (!m_afa_value.IsUnspecified()) { + s.Printf(" AFA="); + m_afa_value.Dump(s, unwind_plan, thread); + } + s.Printf(" => "); for (collection::const_iterator idx = m_register_locations.begin(); idx != m_register_locations.end(); ++idx) { @@ -194,7 +213,8 @@ void UnwindPlan::Row::Dump(Stream &s, const UnwindPlan *unwind_plan, s.EOL(); } -UnwindPlan::Row::Row() : m_offset(0), m_cfa_value(), m_register_locations() {} +UnwindPlan::Row::Row() + : m_offset(0), m_cfa_value(), m_afa_value(), m_register_locations() {} bool UnwindPlan::Row::GetRegisterInfo( uint32_t reg_num, @@ -296,8 +316,10 @@ bool UnwindPlan::Row::SetRegisterLocationToSame(uint32_t reg_num, } bool UnwindPlan::Row::operator==(const UnwindPlan::Row &rhs) const { - return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value && - m_register_locations == rhs.m_register_locations; + return m_offset == rhs.m_offset && + m_cfa_value == rhs.m_cfa_value && + m_afa_value == rhs.m_afa_value && + m_register_locations == rhs.m_register_locations; } void UnwindPlan::AppendRow(const UnwindPlan::RowSP &row_sp) { @@ -399,7 +421,7 @@ bool UnwindPlan::PlanValidAtAddress(Address addr) { // UnwindPlan. if (GetRowAtIndex(0).get() == nullptr || GetRowAtIndex(0)->GetCFAValue().GetValueType() == - Row::CFAValue::unspecified) { + Row::FAValue::unspecified) { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); if (log) { StreamString s; diff --git a/contrib/llvm/tools/lldb/source/Symbol/UnwindTable.cpp b/contrib/llvm/tools/lldb/source/Symbol/UnwindTable.cpp index 7f98eaca2521..4f0b875c5c6f 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/UnwindTable.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/UnwindTable.cpp @@ -180,8 +180,8 @@ ArmUnwindInfo *UnwindTable::GetArmUnwindInfo() { return m_arm_unwind_up.get(); } -bool UnwindTable::GetArchitecture(lldb_private::ArchSpec &arch) { - return m_object_file.GetArchitecture(arch); +ArchSpec UnwindTable::GetArchitecture() { + return m_object_file.GetArchitecture(); } bool UnwindTable::GetAllowAssemblyEmulationUnwindPlans() { diff --git a/contrib/llvm/tools/lldb/source/Symbol/Variable.cpp b/contrib/llvm/tools/lldb/source/Symbol/Variable.cpp index af84872a97a0..ffed48a33bf1 100644 --- a/contrib/llvm/tools/lldb/source/Symbol/Variable.cpp +++ b/contrib/llvm/tools/lldb/source/Symbol/Variable.cpp @@ -50,7 +50,8 @@ Variable::Variable( m_symfile_type_sp(symfile_type_sp), m_scope(scope), m_owner_scope(context), m_scope_range(scope_range), m_declaration(decl_ptr), m_location(location), m_external(external), - m_artificial(artificial), m_static_member(static_member) {} + m_artificial(artificial), m_loc_is_const_data(false), + m_static_member(static_member) {} //---------------------------------------------------------------------- // Destructor @@ -156,14 +157,14 @@ void Variable::Dump(Stream *s, bool show_context) const { .GetBaseAddress() .GetFileAddress(); } - ABI *abi = nullptr; + ABISP abi; if (m_owner_scope) { ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); if (module_sp) - abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()).get(); + abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); } m_location.GetDescription(s, lldb::eDescriptionLevelBrief, - loclist_base_addr, abi); + loclist_base_addr, abi.get()); } if (m_external) @@ -458,11 +459,11 @@ bool Variable::DumpLocationForAddress(Stream *s, const Address &address) { SymbolContext sc; CalculateSymbolContext(&sc); if (sc.module_sp == address.GetModule()) { - ABI *abi = nullptr; + ABISP abi; if (m_owner_scope) { ModuleSP module_sp(m_owner_scope->CalculateSymbolContextModule()); if (module_sp) - abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()).get(); + abi = ABI::FindPlugin(ProcessSP(), module_sp->GetArchitecture()); } const addr_t file_addr = address.GetFileAddress(); @@ -474,11 +475,12 @@ bool Variable::DumpLocationForAddress(Stream *s, const Address &address) { return false; return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief, loclist_base_file_addr, - file_addr, abi); + file_addr, abi.get()); } } - return m_location.DumpLocationForAddress( - s, eDescriptionLevelBrief, LLDB_INVALID_ADDRESS, file_addr, abi); + return m_location.DumpLocationForAddress(s, eDescriptionLevelBrief, + LLDB_INVALID_ADDRESS, file_addr, + abi.get()); } } return false; @@ -603,7 +605,7 @@ static void PrivateAutoComplete( case eTypeClassObjCObjectPointer: case eTypeClassPointer: { bool omit_empty_base_classes = true; - if (compiler_type.GetNumChildren(omit_empty_base_classes) > 0) + if (compiler_type.GetNumChildren(omit_empty_base_classes, nullptr) > 0) matches.AppendString((prefix_path + "->").str()); else { matches.AppendString(prefix_path.str()); diff --git a/contrib/llvm/tools/lldb/source/Target/ABI.cpp b/contrib/llvm/tools/lldb/source/Target/ABI.cpp index 8d4513ad6811..96e09b75094a 100644 --- a/contrib/llvm/tools/lldb/source/Target/ABI.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ABI.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ABI.h" #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" #include "lldb/Core/PluginManager.h" diff --git a/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp index c7e7b2511971..f0bd1758461c 100644 --- a/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp @@ -14,9 +14,19 @@ #include "llvm/ADT/StringRef.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/VariableList.h" + #include "lldb/Core/PluginManager.h" #include "lldb/Core/UniqueCStringMap.h" +#include "lldb/Symbol/ClangASTContext.h" +#include "lldb/Target/ABI.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/RegisterContext.h" +#include "lldb/Target/SectionLoadList.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/ThreadPlanRunToAddress.h" +#include "lldb/Target/ThreadPlanStepInRange.h" using namespace lldb; using namespace lldb_private; @@ -40,3 +50,297 @@ bool CPPLanguageRuntime::GetObjectDescription( // C++ has no generic way to do this. return false; } + +CPPLanguageRuntime::LibCppStdFunctionCallableInfo +CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo( + lldb::ValueObjectSP &valobj_sp) { + LibCppStdFunctionCallableInfo optional_info; + + if (!valobj_sp) + return optional_info; + + // Member __f_ has type __base*, the contents of which will hold: + // 1) a vtable entry which may hold type information needed to discover the + // lambda being called + // 2) possibly hold a pointer to the callable object + // e.g. + // + // (lldb) frame var -R f_display + // (std::__1::function) f_display = { + // __buf_ = { + // … + // } + // __f_ = 0x00007ffeefbffa00 + // } + // (lldb) memory read -fA 0x00007ffeefbffa00 + // 0x7ffeefbffa00: ... `vtable for std::__1::__function::__funcGetChildMemberWithName(ConstString("__f_"), true)); + + if (member__f_) { + ValueObjectSP sub_member__f_( + member__f_->GetChildMemberWithName(ConstString("__f_"), true)); + + if (sub_member__f_) + member__f_ = sub_member__f_; + } + + lldb::addr_t member__f_pointer_value = member__f_->GetValueAsUnsigned(0); + + optional_info.member__f_pointer_value = member__f_pointer_value; + + ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef()); + Process *process = exe_ctx.GetProcessPtr(); + + if (process == nullptr) + return optional_info; + + uint32_t address_size = process->GetAddressByteSize(); + Status status; + + // First item pointed to by __f_ should be the pointer to the vtable for + // a __base object. + lldb::addr_t vtable_address = + process->ReadPointerFromMemory(member__f_pointer_value, status); + + if (status.Fail()) + return optional_info; + + lldb::addr_t address_after_vtable = member__f_pointer_value + address_size; + // As commened above we may not have a function pointer but if we do we will + // need it. + lldb::addr_t possible_function_address = + process->ReadPointerFromMemory(address_after_vtable, status); + + if (status.Fail()) + return optional_info; + + Target &target = process->GetTarget(); + + if (target.GetSectionLoadList().IsEmpty()) + return optional_info; + + Address vtable_addr_resolved; + SymbolContext sc; + Symbol *symbol; + + if (!target.GetSectionLoadList().ResolveLoadAddress(vtable_address, + vtable_addr_resolved)) + return optional_info; + + target.GetImages().ResolveSymbolContextForAddress( + vtable_addr_resolved, eSymbolContextEverything, sc); + symbol = sc.symbol; + + if (symbol == nullptr) + return optional_info; + + llvm::StringRef vtable_name(symbol->GetName().GetCString()); + bool found_expected_start_string = + vtable_name.startswith("vtable for std::__1::__function::__func<"); + + if (!found_expected_start_string) + return optional_info; + + // Given case 1 or 3 we have a vtable name, we are want to extract the first + // template parameter + // + // ... __func ... + // ^^^^^^^^^ + // + // We do this by find the first < and , and extracting in between. + // + // This covers the case of the lambda known at compile time. + size_t first_open_angle_bracket = vtable_name.find('<') + 1; + size_t first_comma = vtable_name.find_first_of(','); + + llvm::StringRef first_template_parameter = + vtable_name.slice(first_open_angle_bracket, first_comma); + + Address function_address_resolved; + + // Setup for cases 2, 4 and 5 we have a pointer to a function after the + // vtable. We will use a process of elimination to drop through each case + // and obtain the data we need. + if (target.GetSectionLoadList().ResolveLoadAddress( + possible_function_address, function_address_resolved)) { + target.GetImages().ResolveSymbolContextForAddress( + function_address_resolved, eSymbolContextEverything, sc); + symbol = sc.symbol; + } + + auto get_name = [&first_template_parameter, &symbol]() { + // Given case 1: + // + // main::$_0 + // + // we want to append ::operator()() + if (first_template_parameter.contains("$_")) + return llvm::Regex::escape(first_template_parameter.str()) + + R"(::operator\(\)\(.*\))"; + + if (symbol != NULL && + symbol->GetName().GetStringRef().contains("__invoke")) { + + llvm::StringRef symbol_name = symbol->GetName().GetStringRef(); + size_t pos2 = symbol_name.find_last_of(':'); + + // Given case 2: + // + // main::$_1::__invoke(...) + // + // We want to slice off __invoke(...) and append operator()() + std::string lambda_operator = + llvm::Regex::escape(symbol_name.slice(0, pos2 + 1).str()) + + R"(operator\(\)\(.*\))"; + + return lambda_operator; + } + + // Case 3 + return first_template_parameter.str() + R"(::operator\(\)\(.*\))"; + ; + }; + + std::string func_to_match = get_name(); + + SymbolContextList scl; + + target.GetImages().FindFunctions(RegularExpression{func_to_match}, true, true, + true, scl); + + // Case 1,2 or 3 + if (scl.GetSize() >= 1) { + SymbolContext sc2 = scl[0]; + + AddressRange range; + sc2.GetAddressRange(eSymbolContextEverything, 0, false, range); + + Address address = range.GetBaseAddress(); + + Address addr; + if (target.ResolveLoadAddress(address.GetCallableLoadAddress(&target), + addr)) { + LineEntry line_entry; + addr.CalculateSymbolContextLineEntry(line_entry); + + if (first_template_parameter.contains("$_") || + (symbol != nullptr && + symbol->GetName().GetStringRef().contains("__invoke"))) { + // Case 1 and 2 + optional_info.callable_case = LibCppStdFunctionCallableCase::Lambda; + } else { + // Case 3 + optional_info.callable_case = + LibCppStdFunctionCallableCase::CallableObject; + } + + optional_info.callable_symbol = *symbol; + optional_info.callable_line_entry = line_entry; + optional_info.callable_address = addr; + return optional_info; + } + } + + // Case 4 or 5 + if (!symbol->GetName().GetStringRef().startswith("vtable for")) { + optional_info.callable_case = + LibCppStdFunctionCallableCase::FreeOrMemberFunction; + optional_info.callable_address = function_address_resolved; + optional_info.callable_symbol = *symbol; + + return optional_info; + } + + return optional_info; +} + +lldb::ThreadPlanSP +CPPLanguageRuntime::GetStepThroughTrampolinePlan(Thread &thread, + bool stop_others) { + ThreadPlanSP ret_plan_sp; + + lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC(); + + TargetSP target_sp(thread.CalculateTarget()); + + if (target_sp->GetSectionLoadList().IsEmpty()) + return ret_plan_sp; + + Address pc_addr_resolved; + SymbolContext sc; + Symbol *symbol; + + if (!target_sp->GetSectionLoadList().ResolveLoadAddress(curr_pc, + pc_addr_resolved)) + return ret_plan_sp; + + target_sp->GetImages().ResolveSymbolContextForAddress( + pc_addr_resolved, eSymbolContextEverything, sc); + symbol = sc.symbol; + + if (symbol == nullptr) + return ret_plan_sp; + + llvm::StringRef function_name(symbol->GetName().GetCString()); + + // Handling the case where we are attempting to step into std::function. + // The behavior will be that we will attempt to obtain the wrapped + // callable via FindLibCppStdFunctionCallableInfo() and if we find it we + // will return a ThreadPlanRunToAddress to the callable. Therefore we will + // step into the wrapped callable. + // + bool found_expected_start_string = + function_name.startswith("std::__1::function<"); + + if (!found_expected_start_string) + return ret_plan_sp; + + AddressRange range_of_curr_func; + sc.GetAddressRange(eSymbolContextEverything, 0, false, range_of_curr_func); + + StackFrameSP frame = thread.GetStackFrameAtIndex(0); + + if (frame) { + ValueObjectSP value_sp = frame->FindVariable(ConstString("this")); + + CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info = + FindLibCppStdFunctionCallableInfo(value_sp); + + if (callable_info.callable_case != LibCppStdFunctionCallableCase::Invalid && + value_sp->GetValueIsValid()) { + // We found the std::function wrapped callable and we have its address. + // We now create a ThreadPlan to run to the callable. + ret_plan_sp.reset(new ThreadPlanRunToAddress( + thread, callable_info.callable_address, stop_others)); + return ret_plan_sp; + } else { + // We are in std::function but we could not obtain the callable. + // We create a ThreadPlan to keep stepping through using the address range + // of the current function. + ret_plan_sp.reset(new ThreadPlanStepInRange(thread, range_of_curr_func, + sc, eOnlyThisThread, + eLazyBoolYes, eLazyBoolYes)); + return ret_plan_sp; + } + } + + return ret_plan_sp; +} diff --git a/contrib/llvm/tools/lldb/source/Target/ExecutionContext.cpp b/contrib/llvm/tools/lldb/source/Target/ExecutionContext.cpp index 73c64916cf1f..7f1f0331c922 100644 --- a/contrib/llvm/tools/lldb/source/Target/ExecutionContext.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ExecutionContext.cpp @@ -7,17 +7,13 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ExecutionContext.h" -#include "lldb/Core/State.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Process.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/State.h" using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/InstrumentationRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/InstrumentationRuntime.cpp index ac8b5dfe4599..e948d43d50af 100644 --- a/contrib/llvm/tools/lldb/source/Target/InstrumentationRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Target/InstrumentationRuntime.cpp @@ -7,10 +7,6 @@ // //===---------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/InstrumentationRuntime.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleList.h" diff --git a/contrib/llvm/tools/lldb/source/Target/JITLoader.cpp b/contrib/llvm/tools/lldb/source/Target/JITLoader.cpp index 77ce4add486f..ddadcfa87a0a 100644 --- a/contrib/llvm/tools/lldb/source/Target/JITLoader.cpp +++ b/contrib/llvm/tools/lldb/source/Target/JITLoader.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/JITLoader.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/JITLoaderList.h" diff --git a/contrib/llvm/tools/lldb/source/Target/Language.cpp b/contrib/llvm/tools/lldb/source/Target/Language.cpp index cde6f8654aec..5c7a4097dd6f 100644 --- a/contrib/llvm/tools/lldb/source/Target/Language.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Language.cpp @@ -77,7 +77,39 @@ Language *Language::FindPlugin(lldb::LanguageType language) { return nullptr; } +Language *Language::FindPlugin(llvm::StringRef file_path) { + Language *result = nullptr; + ForEach([&result, file_path](Language *language) { + if (language->IsSourceFile(file_path)) { + result = language; + return false; + } + return true; + }); + return result; +} + +Language *Language::FindPlugin(LanguageType language, + llvm::StringRef file_path) { + Language *result = FindPlugin(language); + // Finding a language by file path is slower, we so we use this as the + // fallback. + if (!result) + result = FindPlugin(file_path); + return result; +} + void Language::ForEach(std::function callback) { + // If we want to iterate over all languages, we first have to complete the + // LanguagesMap. + static llvm::once_flag g_initialize; + llvm::call_once(g_initialize, [] { + for (unsigned lang = eLanguageTypeUnknown; lang < eNumLanguageTypes; + ++lang) { + FindPlugin(static_cast(lang)); + } + }); + std::lock_guard guard(GetLanguagesMutex()); LanguagesMap &map(GetLanguagesMap()); for (const auto &entry : map) { @@ -353,11 +385,10 @@ bool Language::ImageListTypeScavenger::Find_Impl( Target *target = exe_scope->CalculateTarget().get(); if (target) { const auto &images(target->GetImages()); - SymbolContext null_sc; ConstString cs_key(key); llvm::DenseSet searched_sym_files; TypeList matches; - images.FindTypes(null_sc, cs_key, false, UINT32_MAX, searched_sym_files, + images.FindTypes(nullptr, cs_key, false, UINT32_MAX, searched_sym_files, matches); for (const auto &match : matches.Types()) { if (match.get()) { diff --git a/contrib/llvm/tools/lldb/source/Target/LanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/LanguageRuntime.cpp index bd02121f6a4d..ea6914fb076d 100644 --- a/contrib/llvm/tools/lldb/source/Target/LanguageRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Target/LanguageRuntime.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/LanguageRuntime.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" #include "lldb/Core/PluginManager.h" @@ -125,11 +121,11 @@ public: return eCallbackReturnStop; } - Searcher::Depth GetDepth() override { + lldb::SearchDepth GetDepth() override { if (SetActualResolver()) return m_actual_resolver_sp->GetDepth(); else - return eDepthTarget; + return lldb::eSearchDepthTarget; } void GetDescription(Stream *s) override { diff --git a/contrib/llvm/tools/lldb/source/Target/Memory.cpp b/contrib/llvm/tools/lldb/source/Target/Memory.cpp index ad1b4093155d..190c5057e881 100644 --- a/contrib/llvm/tools/lldb/source/Target/Memory.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Memory.cpp @@ -8,16 +8,12 @@ //===----------------------------------------------------------------------===// #include "lldb/Target/Memory.h" -// C Includes #include -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/RangeMap.h" -#include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/MemoryHistory.cpp b/contrib/llvm/tools/lldb/source/Target/MemoryHistory.cpp index 627942796507..eae931482552 100644 --- a/contrib/llvm/tools/lldb/source/Target/MemoryHistory.cpp +++ b/contrib/llvm/tools/lldb/source/Target/MemoryHistory.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/MemoryHistory.h" #include "lldb/Core/PluginManager.h" diff --git a/contrib/llvm/tools/lldb/source/Target/ModuleCache.cpp b/contrib/llvm/tools/lldb/source/Target/ModuleCache.cpp index 19adfbabe277..daf787b1fb22 100644 --- a/contrib/llvm/tools/lldb/source/Target/ModuleCache.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ModuleCache.cpp @@ -76,7 +76,7 @@ FileSpec GetModuleDirectory(const FileSpec &root_dir_spec, const UUID &uuid) { } FileSpec GetSymbolFileSpec(const FileSpec &module_file_spec) { - return FileSpec(module_file_spec.GetPath() + kSymFileExtension, false); + return FileSpec(module_file_spec.GetPath() + kSymFileExtension); } void DeleteExistingModule(const FileSpec &root_dir_spec, @@ -133,7 +133,7 @@ Status CreateHostSysRootModuleLink(const FileSpec &root_dir_spec, const auto sysroot_module_path_spec = JoinPath(JoinPath(root_dir_spec, hostname), platform_module_spec.GetPath().c_str()); - if (sysroot_module_path_spec.Exists()) { + if (FileSystem::Instance().Exists(sysroot_module_path_spec)) { if (!delete_existing) return Status(); @@ -141,7 +141,7 @@ Status CreateHostSysRootModuleLink(const FileSpec &root_dir_spec, } const auto error = MakeDirectory( - FileSpec(sysroot_module_path_spec.GetDirectory().AsCString(), false)); + FileSpec(sysroot_module_path_spec.GetDirectory().AsCString())); if (error.Fail()) return error; @@ -159,9 +159,10 @@ ModuleLock::ModuleLock(const FileSpec &root_dir_spec, const UUID &uuid, return; m_file_spec = JoinPath(lock_dir_spec, uuid.GetAsString().c_str()); - m_file.Open(m_file_spec.GetCString(), File::eOpenOptionWrite | - File::eOpenOptionCanCreate | - File::eOpenOptionCloseOnExec); + FileSystem::Instance().Open(m_file, m_file_spec, + File::eOpenOptionWrite | + File::eOpenOptionCanCreate | + File::eOpenOptionCloseOnExec); if (!m_file) { error.SetErrorToErrno(); return; @@ -225,9 +226,10 @@ Status ModuleCache::Get(const FileSpec &root_dir_spec, const char *hostname, const auto module_file_path = JoinPath( module_spec_dir, module_spec.GetFileSpec().GetFilename().AsCString()); - if (!module_file_path.Exists()) + if (!FileSystem::Instance().Exists(module_file_path)) return Status("Module %s not found", module_file_path.GetPath().c_str()); - if (module_file_path.GetByteSize() != module_spec.GetObjectSize()) + if (FileSystem::Instance().GetByteSize(module_file_path) != + module_spec.GetObjectSize()) return Status("Module %s has invalid file size", module_file_path.GetPath().c_str()); @@ -252,7 +254,7 @@ Status ModuleCache::Get(const FileSpec &root_dir_spec, const char *hostname, return error; FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec()); - if (symfile_spec.Exists()) + if (FileSystem::Instance().Exists(symfile_spec)) cached_module_sp->SetSymbolFileFileSpec(symfile_spec); m_loaded_modules.insert( diff --git a/contrib/llvm/tools/lldb/source/Target/ObjCLanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/ObjCLanguageRuntime.cpp index b1fcee6db63b..8627da938ea3 100644 --- a/contrib/llvm/tools/lldb/source/Target/ObjCLanguageRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ObjCLanguageRuntime.cpp @@ -108,14 +108,13 @@ ObjCLanguageRuntime::LookupInCompleteClassCache(ConstString &name) { if (!module_sp) return TypeSP(); - const SymbolContext null_sc; const bool exact_match = true; const uint32_t max_matches = UINT32_MAX; TypeList types; llvm::DenseSet searched_symbol_files; const uint32_t num_types = module_sp->FindTypes( - null_sc, name, exact_match, max_matches, searched_symbol_files, types); + name, exact_match, max_matches, searched_symbol_files, types); if (num_types) { uint32_t i; diff --git a/contrib/llvm/tools/lldb/source/Target/OperatingSystem.cpp b/contrib/llvm/tools/lldb/source/Target/OperatingSystem.cpp index 7a1d9d619879..099bfd055ed1 100644 --- a/contrib/llvm/tools/lldb/source/Target/OperatingSystem.cpp +++ b/contrib/llvm/tools/lldb/source/Target/OperatingSystem.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/OperatingSystem.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/Thread.h" diff --git a/contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp b/contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp index 778728eebb09..c2249cce89b9 100644 --- a/contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/PathMappingList.cpp @@ -7,19 +7,16 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes -// Project includes -#include "lldb/lldb-private-enumerations.h" +#include "lldb/Host/FileSystem.h" #include "lldb/Host/PosixApi.h" #include "lldb/Target/PathMappingList.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/Status.h" #include "lldb/Utility/Stream.h" +#include "lldb/lldb-private-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -37,7 +34,7 @@ namespace { ConstString NormalizePath(const ConstString &path) { // If we use "path" to construct a FileSpec, it will normalize the path for // us. We then grab the string and turn it back into a ConstString. - return ConstString(FileSpec(path.GetStringRef(), false).GetPath()); + return ConstString(FileSpec(path.GetStringRef()).GetPath()); } } //---------------------------------------------------------------------- @@ -176,13 +173,13 @@ bool PathMappingList::RemapPath(llvm::StringRef path, // We need to figure out if the "path" argument is relative. If it is, // then we should remap, else skip this entry. if (path_is_relative == eLazyBoolCalculate) { - path_is_relative = FileSpec(path, false).IsRelative() ? eLazyBoolYes : - eLazyBoolNo; + path_is_relative = + FileSpec(path).IsRelative() ? eLazyBoolYes : eLazyBoolNo; } if (!path_is_relative) continue; } - FileSpec remapped(it.second.GetStringRef(), false); + FileSpec remapped(it.second.GetStringRef()); remapped.AppendPathComponent(path); new_path = remapped.GetPath(); return true; @@ -196,7 +193,7 @@ bool PathMappingList::ReverseRemapPath(const FileSpec &file, FileSpec &fixed) co for (const auto &it : m_pairs) { if (!path_ref.consume_front(it.second.GetStringRef())) continue; - fixed.SetFile(it.first.GetStringRef(), false, FileSpec::Style::native); + fixed.SetFile(it.first.GetStringRef(), FileSpec::Style::native); fixed.AppendPathComponent(path_ref); return true; } @@ -216,10 +213,9 @@ bool PathMappingList::FindFile(const FileSpec &orig_spec, if (orig_path_len >= prefix_len) { if (::strncmp(pos->first.GetCString(), orig_path, prefix_len) == 0) { - new_spec.SetFile(pos->second.GetCString(), false, - FileSpec::Style::native); + new_spec.SetFile(pos->second.GetCString(), FileSpec::Style::native); new_spec.AppendPathComponent(orig_path + prefix_len); - if (new_spec.Exists()) + if (FileSystem::Instance().Exists(new_spec)) return true; } } diff --git a/contrib/llvm/tools/lldb/source/Target/Platform.cpp b/contrib/llvm/tools/lldb/source/Target/Platform.cpp index 5ae556ecc02a..400b3c92b5ab 100644 --- a/contrib/llvm/tools/lldb/source/Target/Platform.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Platform.cpp @@ -7,18 +7,14 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include #include #include #include -// Other libraries and framework includes #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" -// Project includes #include "lldb/Breakpoint/BreakpointIDList.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Debugger.h" @@ -67,12 +63,11 @@ const char *Platform::GetHostPlatformName() { return "host"; } namespace { -PropertyDefinition g_properties[] = { +static constexpr PropertyDefinition g_properties[] = { {"use-module-cache", OptionValue::eTypeBoolean, true, true, nullptr, - nullptr, "Use module cache."}, + {}, "Use module cache."}, {"module-cache-directory", OptionValue::eTypeFileSpec, true, 0, nullptr, - nullptr, "Root directory for cached modules."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + {}, "Root directory for cached modules."}}; enum { ePropertyUseModuleCache, ePropertyModuleCacheDirectory }; @@ -95,7 +90,7 @@ PlatformProperties::PlatformProperties() { if (!llvm::sys::path::home_directory(user_home_dir)) return; - module_cache_dir = FileSpec(user_home_dir.c_str(), false); + module_cache_dir = FileSpec(user_home_dir.c_str()); module_cache_dir.AppendPathComponent(".lldb"); module_cache_dir.AppendPathComponent("module_cache"); SetModuleCacheDirectory(module_cache_dir); @@ -228,16 +223,35 @@ Status Platform::GetSharedModule(const ModuleSpec &module_spec, module_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, did_create_ptr, false); - return GetRemoteSharedModule(module_spec, process, module_sp, - [&](const ModuleSpec &spec) { - Status error = ModuleList::GetSharedModule( - spec, module_sp, module_search_paths_ptr, - old_module_sp_ptr, did_create_ptr, false); - if (error.Success() && module_sp) - module_sp->SetPlatformFileSpec( - spec.GetFileSpec()); - return error; - }, + // Module resolver lambda. + auto resolver = [&](const ModuleSpec &spec) { + Status error(eErrorTypeGeneric); + ModuleSpec resolved_spec; + // Check if we have sysroot set. + if (m_sdk_sysroot) { + // Prepend sysroot to module spec. + resolved_spec = spec; + resolved_spec.GetFileSpec().PrependPathComponent( + m_sdk_sysroot.GetStringRef()); + // Try to get shared module with resolved spec. + error = ModuleList::GetSharedModule( + resolved_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, + did_create_ptr, false); + } + // If we don't have sysroot or it didn't work then + // try original module spec. + if (!error.Success()) { + resolved_spec = spec; + error = ModuleList::GetSharedModule( + resolved_spec, module_sp, module_search_paths_ptr, old_module_sp_ptr, + did_create_ptr, false); + } + if (error.Success() && module_sp) + module_sp->SetPlatformFileSpec(resolved_spec.GetFileSpec()); + return error; + }; + + return GetRemoteSharedModule(module_spec, process, module_sp, resolver, did_create_ptr); } @@ -518,9 +532,12 @@ FileSpec Platform::GetWorkingDirectory() { if (IsHost()) { llvm::SmallString<64> cwd; if (llvm::sys::fs::current_path(cwd)) - return FileSpec{}; - else - return FileSpec(cwd, true); + return {}; + else { + FileSpec file_spec(cwd); + FileSystem::Instance().Resolve(file_spec); + return file_spec; + } } else { if (!m_working_dir) m_working_dir = GetRemoteWorkingDirectory(); @@ -534,16 +551,17 @@ struct RecurseCopyBaton { Status error; }; -static FileSpec::EnumerateDirectoryResult +static FileSystem::EnumerateDirectoryResult RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, - const FileSpec &src) { + llvm::StringRef path) { RecurseCopyBaton *rc_baton = (RecurseCopyBaton *)baton; + FileSpec src(path); namespace fs = llvm::sys::fs; switch (ft) { case fs::file_type::fifo_file: case fs::file_type::socket_file: // we have no way to copy pipes and sockets - ignore them and continue - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; break; case fs::file_type::directory_file: { @@ -556,7 +574,7 @@ RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, if (error.Fail()) { rc_baton->error.SetErrorStringWithFormat( "unable to setup directory %s on remote end", dst_dir.GetCString()); - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out + return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out } // now recurse @@ -568,13 +586,13 @@ RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, recurse_dst.GetDirectory().SetCString(dst_dir.GetPath().c_str()); RecurseCopyBaton rc_baton2 = {recurse_dst, rc_baton->platform_ptr, Status()}; - FileSpec::EnumerateDirectory(src_dir_path, true, true, true, - RecurseCopy_Callback, &rc_baton2); + FileSystem::Instance().EnumerateDirectory(src_dir_path, true, true, true, + RecurseCopy_Callback, &rc_baton2); if (rc_baton2.error.Fail()) { rc_baton->error.SetErrorString(rc_baton2.error.AsCString()); - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out + return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out } - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; } break; case fs::file_type::symlink_file: { @@ -585,18 +603,18 @@ RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, FileSpec src_resolved; - rc_baton->error = FileSystem::Readlink(src, src_resolved); + rc_baton->error = FileSystem::Instance().Readlink(src, src_resolved); if (rc_baton->error.Fail()) - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out + return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out rc_baton->error = rc_baton->platform_ptr->CreateSymlink(dst_file, src_resolved); if (rc_baton->error.Fail()) - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out + return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; } break; case fs::file_type::regular_file: { @@ -607,15 +625,15 @@ RecurseCopy_Callback(void *baton, llvm::sys::fs::file_type ft, Status err = rc_baton->platform_ptr->PutFile(src, dst_file); if (err.Fail()) { rc_baton->error.SetErrorString(err.AsCString()); - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out + return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out } - return FileSpec::eEnumerateDirectoryResultNext; + return FileSystem::eEnumerateDirectoryResultNext; } break; default: rc_baton->error.SetErrorStringWithFormat( "invalid file detected during copy: %s", src.GetPath().c_str()); - return FileSpec::eEnumerateDirectoryResultQuit; // got an error, bail out + return FileSystem::eEnumerateDirectoryResultQuit; // got an error, bail out break; } llvm_unreachable("Unhandled file_type!"); @@ -690,7 +708,7 @@ Status Platform::Install(const FileSpec &src, const FileSpec &dst) { switch (fs::get_file_type(src.GetPath(), false)) { case fs::file_type::directory_file: { llvm::sys::fs::remove(fixed_dst.GetPath()); - uint32_t permissions = src.GetPermissions(); + uint32_t permissions = FileSystem::Instance().GetPermissions(src); if (permissions == 0) permissions = eFilePermissionsDirectoryDefault; error = MakeDirectory(fixed_dst, permissions); @@ -701,8 +719,8 @@ Status Platform::Install(const FileSpec &src, const FileSpec &dst) { recurse_dst.GetDirectory().SetCString(fixed_dst.GetCString()); std::string src_dir_path(src.GetPath()); RecurseCopyBaton baton = {recurse_dst, this, Status()}; - FileSpec::EnumerateDirectory(src_dir_path, true, true, true, - RecurseCopy_Callback, &baton); + FileSystem::Instance().EnumerateDirectory( + src_dir_path, true, true, true, RecurseCopy_Callback, &baton); return baton.error; } } break; @@ -715,7 +733,7 @@ Status Platform::Install(const FileSpec &src, const FileSpec &dst) { case fs::file_type::symlink_file: { llvm::sys::fs::remove(fixed_dst.GetPath()); FileSpec src_resolved; - error = FileSystem::Readlink(src, src_resolved); + error = FileSystem::Instance().Readlink(src, src_resolved); if (error.Success()) error = CreateSymlink(dst, src_resolved); } break; @@ -871,7 +889,7 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, lldb::ModuleSP &exe_module_sp, const FileSpecList *module_search_paths_ptr) { Status error; - if (module_spec.GetFileSpec().Exists()) { + if (FileSystem::Instance().Exists(module_spec.GetFileSpec())) { if (module_spec.GetArchitecture().IsValid()) { error = ModuleList::GetSharedModule(module_spec, exe_module_sp, module_search_paths_ptr, nullptr, @@ -902,7 +920,7 @@ Platform::ResolveExecutable(const ModuleSpec &module_spec, Status Platform::ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec, FileSpec &sym_file) { Status error; - if (sym_spec.GetSymbolFileSpec().Exists()) + if (FileSystem::Instance().Exists(sym_spec.GetSymbolFileSpec())) sym_file = sym_spec.GetSymbolFileSpec(); else error.SetErrorString("unable to resolve symbol file"); @@ -912,7 +930,8 @@ Status Platform::ResolveSymbolFile(Target &target, const ModuleSpec &sym_spec, bool Platform::ResolveRemotePath(const FileSpec &platform_path, FileSpec &resolved_platform_path) { resolved_platform_path = platform_path; - return resolved_platform_path.ResolvePath(); + FileSystem::Instance().Resolve(resolved_platform_path); + return true; } const ArchSpec &Platform::GetSystemArchitecture() { @@ -1257,8 +1276,9 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, if (fs::is_symlink_file(source.GetPath())) source_open_options |= File::eOpenOptionDontFollowSymlinks; - File source_file(source, source_open_options, lldb::eFilePermissionsUserRW); - Status error; + File source_file; + Status error = FileSystem::Instance().Open( + source_file, source, source_open_options, lldb::eFilePermissionsUserRW); uint32_t permissions = source_file.GetPermissions(error); if (permissions == 0) permissions = lldb::eFilePermissionsFileDefault; @@ -1276,7 +1296,7 @@ Status Platform::PutFile(const FileSpec &source, const FileSpec &destination, return error; if (dest_file == UINT64_MAX) return Status("unable to open target file"); - lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024, 0)); + lldb::DataBufferSP buffer_sp(new DataBufferHeap(1024 * 16, 0)); uint64_t offset = 0; for (;;) { size_t bytes_read = buffer_sp->GetByteSize(); @@ -1378,32 +1398,32 @@ const char *Platform::GetLocalCacheDirectory() { return m_local_cache_directory.c_str(); } -static OptionDefinition g_rsync_option_table[] = { +static constexpr OptionDefinition g_rsync_option_table[] = { {LLDB_OPT_SET_ALL, false, "rsync", 'r', OptionParser::eNoArgument, nullptr, - nullptr, 0, eArgTypeNone, "Enable rsync."}, + {}, 0, eArgTypeNone, "Enable rsync."}, {LLDB_OPT_SET_ALL, false, "rsync-opts", 'R', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommandName, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommandName, "Platform-specific options required for rsync to work."}, {LLDB_OPT_SET_ALL, false, "rsync-prefix", 'P', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeCommandName, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCommandName, "Platform-specific rsync prefix put before the remote path."}, {LLDB_OPT_SET_ALL, false, "ignore-remote-hostname", 'i', - OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Do not automatically fill in the remote hostname when composing the " "rsync command."}, }; -static OptionDefinition g_ssh_option_table[] = { +static constexpr OptionDefinition g_ssh_option_table[] = { {LLDB_OPT_SET_ALL, false, "ssh", 's', OptionParser::eNoArgument, nullptr, - nullptr, 0, eArgTypeNone, "Enable SSH."}, + {}, 0, eArgTypeNone, "Enable SSH."}, {LLDB_OPT_SET_ALL, false, "ssh-opts", 'S', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeCommandName, + nullptr, {}, 0, eArgTypeCommandName, "Platform-specific options required for SSH to work."}, }; -static OptionDefinition g_caching_option_table[] = { +static constexpr OptionDefinition g_caching_option_table[] = { {LLDB_OPT_SET_ALL, false, "local-cache-dir", 'c', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypePath, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypePath, "Path in which to store local copies of files."}, }; @@ -1566,14 +1586,14 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, if (process->GetModuleSpec(module_spec.GetFileSpec(), module_spec.GetArchitecture(), resolved_module_spec)) { - if (module_spec.GetUUID().IsValid() == false || + if (!module_spec.GetUUID().IsValid() || module_spec.GetUUID() == resolved_module_spec.GetUUID()) { got_module_spec = true; } } } - if (module_spec.GetArchitecture().IsValid() == false) { + if (!module_spec.GetArchitecture().IsValid()) { Status error; // No valid architecture was specified, ask the platform for the // architectures that we should be using (in the correct order) and see if @@ -1596,7 +1616,7 @@ Status Platform::GetRemoteSharedModule(const ModuleSpec &module_spec, // Get module information from a target. if (!GetModuleSpec(module_spec.GetFileSpec(), module_spec.GetArchitecture(), resolved_module_spec)) { - if (module_spec.GetUUID().IsValid() == false || + if (!module_spec.GetUUID().IsValid() || module_spec.GetUUID() == resolved_module_spec.GetUUID()) { return module_resolver(module_spec); } @@ -1780,9 +1800,9 @@ uint32_t Platform::LoadImageUsingPaths(lldb_private::Process *process, { FileSpec file_to_use; if (remote_filename.IsAbsolute()) - file_to_use = FileSpec(remote_filename.GetFilename().GetStringRef(), - false, - remote_filename.GetPathStyle()); + file_to_use = FileSpec(remote_filename.GetFilename().GetStringRef(), + + remote_filename.GetPathStyle()); else file_to_use = remote_filename; @@ -1802,9 +1822,19 @@ lldb::ProcessSP Platform::ConnectProcess(llvm::StringRef connect_url, error.Clear(); if (!target) { + ArchSpec arch; + if (target && target->GetArchitecture().IsValid()) + arch = target->GetArchitecture(); + else + arch = Target::GetDefaultArchitecture(); + + const char *triple = ""; + if (arch.IsValid()) + triple = arch.GetTriple().getTriple().c_str(); + TargetSP new_target_sp; - error = debugger.GetTargetList().CreateTarget(debugger, "", "", false, - nullptr, new_target_sp); + error = debugger.GetTargetList().CreateTarget( + debugger, "", triple, eLoadDependentsNo, nullptr, new_target_sp); target = new_target_sp.get(); } diff --git a/contrib/llvm/tools/lldb/source/Target/Process.cpp b/contrib/llvm/tools/lldb/source/Target/Process.cpp index c3d8abc9f78d..fb3b758912eb 100644 --- a/contrib/llvm/tools/lldb/source/Target/Process.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Process.cpp @@ -7,25 +7,19 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include #include -// Other libraries and framework includes #include "llvm/Support/ScopedPrinter.h" #include "llvm/Support/Threading.h" -// Project includes #include "Plugins/Process/Utility/InferiorCallPOSIX.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Event.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Expression/DiagnosticManager.h" #include "lldb/Expression/IRDynamicChecks.h" @@ -67,9 +61,11 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanBase.h" #include "lldb/Target/UnixSignals.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/NameMatches.h" #include "lldb/Utility/SelectHelper.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; @@ -116,39 +112,38 @@ public: } }; -static PropertyDefinition g_properties[] = { +static constexpr PropertyDefinition g_properties[] = { {"disable-memory-cache", OptionValue::eTypeBoolean, false, - DISABLE_MEM_CACHE_DEFAULT, nullptr, nullptr, + DISABLE_MEM_CACHE_DEFAULT, nullptr, {}, "Disable reading and caching of memory in fixed-size units."}, {"extra-startup-command", OptionValue::eTypeArray, false, - OptionValue::eTypeString, nullptr, nullptr, + OptionValue::eTypeString, nullptr, {}, "A list containing extra commands understood by the particular process " "plugin used. " "For instance, to turn on debugserver logging set this to " "\"QSetLogging:bitmask=LOG_DEFAULT;\""}, {"ignore-breakpoints-in-expressions", OptionValue::eTypeBoolean, true, true, - nullptr, nullptr, + nullptr, {}, "If true, breakpoints will be ignored during expression evaluation."}, {"unwind-on-error-in-expressions", OptionValue::eTypeBoolean, true, true, - nullptr, nullptr, "If true, errors in expression evaluation will unwind " - "the stack back to the state before the call."}, + nullptr, {}, "If true, errors in expression evaluation will unwind " + "the stack back to the state before the call."}, {"python-os-plugin-path", OptionValue::eTypeFileSpec, false, true, nullptr, - nullptr, "A path to a python OS plug-in module file that contains a " - "OperatingSystemPlugIn class."}, + {}, "A path to a python OS plug-in module file that contains a " + "OperatingSystemPlugIn class."}, {"stop-on-sharedlibrary-events", OptionValue::eTypeBoolean, true, false, - nullptr, nullptr, + nullptr, {}, "If true, stop when a shared library is loaded or unloaded."}, {"detach-keeps-stopped", OptionValue::eTypeBoolean, true, false, nullptr, - nullptr, "If true, detach will attempt to keep the process stopped."}, + {}, "If true, detach will attempt to keep the process stopped."}, {"memory-cache-line-size", OptionValue::eTypeUInt64, false, 512, nullptr, - nullptr, "The memory cache line size"}, + {}, "The memory cache line size"}, {"optimization-warnings", OptionValue::eTypeBoolean, false, true, nullptr, - nullptr, "If true, warn when stopped in code that is optimized where " - "stepping and variable availability may not behave as expected."}, + {}, "If true, warn when stopped in code that is optimized where " + "stepping and variable availability may not behave as expected."}, {"stop-on-exec", OptionValue::eTypeBoolean, true, true, - nullptr, nullptr, - "If true, stop when a shared library is loaded or unloaded."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + nullptr, {}, + "If true, stop when a shared library is loaded or unloaded."}}; enum { ePropertyDisableMemCache, @@ -431,7 +426,7 @@ Status ProcessLaunchCommandOptions::SetOptionValue( case 'i': // STDIN for read only { FileAction action; - if (action.Open(STDIN_FILENO, FileSpec{option_arg, false}, true, false)) + if (action.Open(STDIN_FILENO, FileSpec(option_arg), true, false)) launch_info.AppendFileAction(action); break; } @@ -439,7 +434,7 @@ Status ProcessLaunchCommandOptions::SetOptionValue( case 'o': // Open STDOUT for write only { FileAction action; - if (action.Open(STDOUT_FILENO, FileSpec{option_arg, false}, false, true)) + if (action.Open(STDOUT_FILENO, FileSpec(option_arg), false, true)) launch_info.AppendFileAction(action); break; } @@ -447,7 +442,7 @@ Status ProcessLaunchCommandOptions::SetOptionValue( case 'e': // STDERR for write only { FileAction action; - if (action.Open(STDERR_FILENO, FileSpec{option_arg, false}, false, true)) + if (action.Open(STDERR_FILENO, FileSpec(option_arg), false, true)) launch_info.AppendFileAction(action); break; } @@ -459,7 +454,7 @@ Status ProcessLaunchCommandOptions::SetOptionValue( case 'n': // Disable STDIO { FileAction action; - const FileSpec dev_null{FileSystem::DEV_NULL, false}; + const FileSpec dev_null(FileSystem::DEV_NULL); if (action.Open(STDIN_FILENO, dev_null, true, false)) launch_info.AppendFileAction(action); if (action.Open(STDOUT_FILENO, dev_null, false, true)) @@ -470,7 +465,7 @@ Status ProcessLaunchCommandOptions::SetOptionValue( } case 'w': - launch_info.SetWorkingDirectory(FileSpec{option_arg, false}); + launch_info.SetWorkingDirectory(FileSpec(option_arg)); break; case 't': // Open process in new terminal window @@ -516,7 +511,7 @@ Status ProcessLaunchCommandOptions::SetOptionValue( case 'c': if (!option_arg.empty()) - launch_info.SetShell(FileSpec(option_arg, false)); + launch_info.SetShell(FileSpec(option_arg)); else launch_info.SetShell(HostInfo::GetDefaultShell()); break; @@ -533,52 +528,52 @@ Status ProcessLaunchCommandOptions::SetOptionValue( return error; } -static OptionDefinition g_process_launch_options[] = { +static constexpr OptionDefinition g_process_launch_options[] = { {LLDB_OPT_SET_ALL, false, "stop-at-entry", 's', OptionParser::eNoArgument, - nullptr, nullptr, 0, eArgTypeNone, + nullptr, {}, 0, eArgTypeNone, "Stop at the entry point of the program when launching a process."}, {LLDB_OPT_SET_ALL, false, "disable-aslr", 'A', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set whether to disable address space layout randomization when launching " "a process."}, {LLDB_OPT_SET_ALL, false, "plugin", 'p', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypePlugin, + nullptr, {}, 0, eArgTypePlugin, "Name of the process plugin you want to use."}, {LLDB_OPT_SET_ALL, false, "working-dir", 'w', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeDirectoryName, "Set the current working directory to when running the inferior."}, {LLDB_OPT_SET_ALL, false, "arch", 'a', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeArchitecture, + nullptr, {}, 0, eArgTypeArchitecture, "Set the architecture for the process to launch when ambiguous."}, {LLDB_OPT_SET_ALL, false, "environment", 'v', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeNone, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone, "Specify an environment variable name/value string (--environment " "NAME=VALUE). Can be specified multiple times for subsequent environment " "entries."}, {LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3, false, "shell", 'c', - OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeFilename, + OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeFilename, "Run the process in a shell (not supported on all platforms)."}, {LLDB_OPT_SET_1, false, "stdin", 'i', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeFilename, + nullptr, {}, 0, eArgTypeFilename, "Redirect stdin for the process to ."}, {LLDB_OPT_SET_1, false, "stdout", 'o', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeFilename, + nullptr, {}, 0, eArgTypeFilename, "Redirect stdout for the process to ."}, {LLDB_OPT_SET_1, false, "stderr", 'e', OptionParser::eRequiredArgument, - nullptr, nullptr, 0, eArgTypeFilename, + nullptr, {}, 0, eArgTypeFilename, "Redirect stderr for the process to ."}, {LLDB_OPT_SET_2, false, "tty", 't', OptionParser::eNoArgument, nullptr, - nullptr, 0, eArgTypeNone, + {}, 0, eArgTypeNone, "Start the process in a terminal (not supported on all platforms)."}, {LLDB_OPT_SET_3, false, "no-stdio", 'n', OptionParser::eNoArgument, nullptr, - nullptr, 0, eArgTypeNone, + {}, 0, eArgTypeNone, "Do not set up for terminal I/O to go to running process."}, {LLDB_OPT_SET_4, false, "shell-expand-args", 'X', - OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeBoolean, + OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeBoolean, "Set whether to shell expand arguments to the process when launching."}, }; @@ -1729,6 +1724,10 @@ void Process::SetRunningUserExpression(bool on) { m_mod_id.SetRunningUserExpression(on); } +void Process::SetRunningUtilityFunction(bool on) { + m_mod_id.SetRunningUtilityFunction(on); +} + addr_t Process::GetImageInfoAddress() { return LLDB_INVALID_ADDRESS; } const lldb::ABISP &Process::GetABI() { @@ -1921,7 +1920,7 @@ Process::CreateBreakpointSite(const BreakpointLocationSP &owner, owner->SetBreakpointSite(bp_site_sp); return m_breakpoint_site_list.Add(bp_site_sp); } else { - if (show_error) { + if (show_error || use_hardware) { // Report error for setting breakpoint... GetTarget().GetDebugger().GetErrorFile()->Printf( "warning: failed to set breakpoint site at 0x%" PRIx64 @@ -2731,7 +2730,7 @@ Status Process::Launch(ProcessLaunchInfo &launch_info) { sizeof(local_exec_file_path)); exe_module->GetPlatformFileSpec().GetPath(platform_exec_file_path, sizeof(platform_exec_file_path)); - if (exe_module->GetFileSpec().Exists()) { + if (FileSystem::Instance().Exists(exe_module->GetFileSpec())) { // Install anything that might need to be installed prior to launching. // For host systems, this will do nothing, but if we are connected to a // remote platform it will install any needed binaries @@ -3211,7 +3210,8 @@ void Process::CompleteAttach() { } } if (new_executable_module_sp) { - GetTarget().SetExecutableModule(new_executable_module_sp, false); + GetTarget().SetExecutableModule(new_executable_module_sp, + eLoadDependentsNo); if (log) { ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); log->Printf( @@ -3291,6 +3291,11 @@ Status Process::PrivateResume() { m_thread_list.DidResume(); if (log) log->Printf("Process thinks the process has resumed."); + } else { + if (log) + log->Printf( + "Process::PrivateResume() DoResume failed."); + return error; } } } else { @@ -4685,7 +4690,12 @@ bool Process::PushProcessIOHandler() { log->Printf("Process::%s pushing IO handler", __FUNCTION__); io_handler_sp->SetIsDone(false); - GetTarget().GetDebugger().PushIOHandler(io_handler_sp); + // If we evaluate an utility function, then we don't cancel the current + // IOHandler. Our IOHandler is non-interactive and shouldn't disturb the + // existing IOHandler that potentially provides the user interface (e.g. + // the IOHandler for Editline). + bool cancel_top_handler = !m_mod_id.IsRunningUtilityFunction(); + GetTarget().GetDebugger().PushIOHandler(io_handler_sp, cancel_top_handler); return true; } return false; @@ -4875,6 +4885,11 @@ Process::RunThreadPlan(ExecutionContext &exe_ctx, thread_plan_sp->SetIsMasterPlan(true); thread_plan_sp->SetOkayToDiscard(false); + // If we are running some utility expression for LLDB, we now have to mark + // this in the ProcesModID of this process. This RAII takes care of marking + // and reverting the mark it once we are done running the expression. + UtilityFunctionScope util_scope(options.IsForUtilityExpr() ? this : nullptr); + if (m_private_state.GetValue() != eStateStopped) { diagnostic_manager.PutString( eDiagnosticSeverityError, @@ -5842,7 +5857,7 @@ void Process::ModulesDidLoad(ModuleList &module_list) { // that loaded. // Iterate over a copy of this language runtime list in case the language - // runtime ModulesDidLoad somehow causes the language riuntime to be + // runtime ModulesDidLoad somehow causes the language runtime to be // unloaded. LanguageRuntimeCollection language_runtimes(m_language_runtimes); for (const auto &pair : language_runtimes) { @@ -6020,7 +6035,7 @@ Process::AdvanceAddressToNextBranchInstruction(Address default_stop_addr, } Status -Process::GetMemoryRegions(std::vector ®ion_list) { +Process::GetMemoryRegions(lldb_private::MemoryRegionInfos ®ion_list) { Status error; @@ -6028,17 +6043,17 @@ Process::GetMemoryRegions(std::vector ®ion_list) { region_list.clear(); do { - lldb::MemoryRegionInfoSP region_info(new lldb_private::MemoryRegionInfo()); - error = GetMemoryRegionInfo(range_end, *region_info); + lldb_private::MemoryRegionInfo region_info; + error = GetMemoryRegionInfo(range_end, region_info); // GetMemoryRegionInfo should only return an error if it is unimplemented. if (error.Fail()) { region_list.clear(); break; } - range_end = region_info->GetRange().GetRangeEnd(); - if (region_info->GetMapped() == MemoryRegionInfo::eYes) { - region_list.push_back(region_info); + range_end = region_info.GetRange().GetRangeEnd(); + if (region_info.GetMapped() == MemoryRegionInfo::eYes) { + region_list.push_back(std::move(region_info)); } } while (range_end != LLDB_INVALID_ADDRESS); @@ -6095,7 +6110,7 @@ void Process::MapSupportedStructuredDataPlugins( // For each StructuredDataPlugin, if the plugin handles any of the types in // the supported_type_names, map that type name to that plugin. Stop when // we've consumed all the type names. - // FIXME: should we return an error if there are type names nobody + // FIXME: should we return an error if there are type names nobody // supports? for (uint32_t plugin_index = 0; !const_type_names.empty(); plugin_index++) { auto create_instance = @@ -6103,7 +6118,7 @@ void Process::MapSupportedStructuredDataPlugins( plugin_index); if (!create_instance) break; - + // Create the plugin. StructuredDataPluginSP plugin_sp = (*create_instance)(*this); if (!plugin_sp) { diff --git a/contrib/llvm/tools/lldb/source/Target/ProcessInfo.cpp b/contrib/llvm/tools/lldb/source/Target/ProcessInfo.cpp index ac0350686706..1ada6123fa1e 100644 --- a/contrib/llvm/tools/lldb/source/Target/ProcessInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ProcessInfo.cpp @@ -9,12 +9,8 @@ #include "lldb/Target/ProcessInfo.h" -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Host/PosixApi.h" #include "lldb/Utility/Stream.h" @@ -29,8 +25,8 @@ ProcessInfo::ProcessInfo() ProcessInfo::ProcessInfo(const char *name, const ArchSpec &arch, lldb::pid_t pid) - : m_executable(name, false), m_arguments(), m_environment(), - m_uid(UINT32_MAX), m_gid(UINT32_MAX), m_arch(arch), m_pid(pid) {} + : m_executable(name), m_arguments(), m_environment(), m_uid(UINT32_MAX), + m_gid(UINT32_MAX), m_arch(arch), m_pid(pid) {} void ProcessInfo::Clear() { m_executable.Clear(); @@ -67,7 +63,7 @@ void ProcessInfo::SetExecutableFile(const FileSpec &exe_file, if (exe_file) { m_executable = exe_file; if (add_exe_file_as_first_arg) { - llvm::SmallString filename; + llvm::SmallString<128> filename; exe_file.GetPath(filename); if (!filename.empty()) m_arguments.InsertArgumentAtIndex(0, filename); @@ -96,8 +92,7 @@ void ProcessInfo::SetArguments(char const **argv, // Yes the first argument is an executable, set it as the executable in // the launch options. Don't resolve the file path as the path could be a // remote platform path - const bool resolve = false; - m_executable.SetFile(first_arg, resolve, FileSpec::Style::native); + m_executable.SetFile(first_arg, FileSpec::Style::native); } } } @@ -113,8 +108,7 @@ void ProcessInfo::SetArguments(const Args &args, bool first_arg_is_executable) { // Yes the first argument is an executable, set it as the executable in // the launch options. Don't resolve the file path as the path could be a // remote platform path - const bool resolve = false; - m_executable.SetFile(first_arg, resolve, FileSpec::Style::native); + m_executable.SetFile(first_arg, FileSpec::Style::native); } } } diff --git a/contrib/llvm/tools/lldb/source/Target/ProcessLaunchInfo.cpp b/contrib/llvm/tools/lldb/source/Target/ProcessLaunchInfo.cpp index 9569750bc5fd..ac1eba04f0cb 100644 --- a/contrib/llvm/tools/lldb/source/Target/ProcessLaunchInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ProcessLaunchInfo.cpp @@ -7,19 +7,13 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes -#include "lldb/Core/Debugger.h" #include "lldb/Host/Config.h" #include "lldb/Host/FileSystem.h" #include "lldb/Host/HostInfo.h" #include "lldb/Target/FileAction.h" #include "lldb/Target/ProcessLaunchInfo.h" -#include "lldb/Target/Target.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" @@ -108,8 +102,7 @@ bool ProcessLaunchInfo::AppendOpenFileAction(int fd, const FileSpec &file_spec, bool ProcessLaunchInfo::AppendSuppressFileAction(int fd, bool read, bool write) { FileAction file_action; - if (file_action.Open(fd, FileSpec{FileSystem::DEV_NULL, false}, read, - write)) { + if (file_action.Open(fd, FileSpec(FileSystem::DEV_NULL), read, write)) { AppendFileAction(file_action); return true; } @@ -151,7 +144,7 @@ const FileSpec &ProcessLaunchInfo::GetShell() const { return m_shell; } void ProcessLaunchInfo::SetShell(const FileSpec &shell) { m_shell = shell; if (m_shell) { - m_shell.ResolveExecutableLocation(); + FileSystem::Instance().ResolveExecutableLocation(m_shell); m_flags.Set(lldb::eLaunchFlagLaunchInShell); } else m_flags.Clear(lldb::eLaunchFlagLaunchInShell); @@ -212,124 +205,38 @@ void ProcessLaunchInfo::SetDetachOnError(bool enable) { m_flags.Clear(lldb::eLaunchFlagDetachOnError); } -void ProcessLaunchInfo::FinalizeFileActions(Target *target, - bool default_to_use_pty) { - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); +llvm::Error ProcessLaunchInfo::SetUpPtyRedirection() { + Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS); + LLDB_LOG(log, "Generating a pty to use for stdin/out/err"); - // If nothing for stdin or stdout or stderr was specified, then check the - // process for any default settings that were set with "settings set" - if (GetFileActionForFD(STDIN_FILENO) == nullptr || - GetFileActionForFD(STDOUT_FILENO) == nullptr || - GetFileActionForFD(STDERR_FILENO) == nullptr) { - if (log) - log->Printf("ProcessLaunchInfo::%s at least one of stdin/stdout/stderr " - "was not set, evaluating default handling", - __FUNCTION__); - - if (m_flags.Test(eLaunchFlagLaunchInTTY)) { - // Do nothing, if we are launching in a remote terminal no file actions - // should be done at all. - return; - } - - if (m_flags.Test(eLaunchFlagDisableSTDIO)) { - if (log) - log->Printf("ProcessLaunchInfo::%s eLaunchFlagDisableSTDIO set, adding " - "suppression action for stdin, stdout and stderr", - __FUNCTION__); - AppendSuppressFileAction(STDIN_FILENO, true, false); - AppendSuppressFileAction(STDOUT_FILENO, false, true); - AppendSuppressFileAction(STDERR_FILENO, false, true); - } else { - // Check for any values that might have gotten set with any of: (lldb) - // settings set target.input-path (lldb) settings set target.output-path - // (lldb) settings set target.error-path - FileSpec in_file_spec; - FileSpec out_file_spec; - FileSpec err_file_spec; - if (target) { - // Only override with the target settings if we don't already have an - // action for in, out or error - if (GetFileActionForFD(STDIN_FILENO) == nullptr) - in_file_spec = target->GetStandardInputPath(); - if (GetFileActionForFD(STDOUT_FILENO) == nullptr) - out_file_spec = target->GetStandardOutputPath(); - if (GetFileActionForFD(STDERR_FILENO) == nullptr) - err_file_spec = target->GetStandardErrorPath(); - } - - if (log) - log->Printf("ProcessLaunchInfo::%s target stdin='%s', target " - "stdout='%s', stderr='%s'", - __FUNCTION__, - in_file_spec ? in_file_spec.GetCString() : "", - out_file_spec ? out_file_spec.GetCString() : "", - err_file_spec ? err_file_spec.GetCString() : ""); - - if (in_file_spec) { - AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false); - if (log) - log->Printf( - "ProcessLaunchInfo::%s appended stdin open file action for %s", - __FUNCTION__, in_file_spec.GetCString()); - } - - if (out_file_spec) { - AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true); - if (log) - log->Printf( - "ProcessLaunchInfo::%s appended stdout open file action for %s", - __FUNCTION__, out_file_spec.GetCString()); - } - - if (err_file_spec) { - AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true); - if (log) - log->Printf( - "ProcessLaunchInfo::%s appended stderr open file action for %s", - __FUNCTION__, err_file_spec.GetCString()); - } - - if (default_to_use_pty && - (!in_file_spec || !out_file_spec || !err_file_spec)) { - if (log) - log->Printf("ProcessLaunchInfo::%s default_to_use_pty is set, and at " - "least one stdin/stderr/stdout is unset, so generating a " - "pty to use for it", - __FUNCTION__); - - int open_flags = O_RDWR | O_NOCTTY; + int open_flags = O_RDWR | O_NOCTTY; #if !defined(_WIN32) - // We really shouldn't be specifying platform specific flags that are - // intended for a system call in generic code. But this will have to - // do for now. - open_flags |= O_CLOEXEC; + // We really shouldn't be specifying platform specific flags that are + // intended for a system call in generic code. But this will have to + // do for now. + open_flags |= O_CLOEXEC; #endif - if (m_pty->OpenFirstAvailableMaster(open_flags, nullptr, 0)) { - const FileSpec slave_file_spec{m_pty->GetSlaveName(nullptr, 0), - false}; - - // Only use the slave tty if we don't have anything specified for - // input and don't have an action for stdin - if (!in_file_spec && GetFileActionForFD(STDIN_FILENO) == nullptr) { - AppendOpenFileAction(STDIN_FILENO, slave_file_spec, true, false); - } - - // Only use the slave tty if we don't have anything specified for - // output and don't have an action for stdout - if (!out_file_spec && GetFileActionForFD(STDOUT_FILENO) == nullptr) { - AppendOpenFileAction(STDOUT_FILENO, slave_file_spec, false, true); - } - - // Only use the slave tty if we don't have anything specified for - // error and don't have an action for stderr - if (!err_file_spec && GetFileActionForFD(STDERR_FILENO) == nullptr) { - AppendOpenFileAction(STDERR_FILENO, slave_file_spec, false, true); - } - } - } - } + if (!m_pty->OpenFirstAvailableMaster(open_flags, nullptr, 0)) { + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "PTY::OpenFirstAvailableMaster failed"); } + const FileSpec slave_file_spec(m_pty->GetSlaveName(nullptr, 0)); + + // Only use the slave tty if we don't have anything specified for + // input and don't have an action for stdin + if (GetFileActionForFD(STDIN_FILENO) == nullptr) + AppendOpenFileAction(STDIN_FILENO, slave_file_spec, true, false); + + // Only use the slave tty if we don't have anything specified for + // output and don't have an action for stdout + if (GetFileActionForFD(STDOUT_FILENO) == nullptr) + AppendOpenFileAction(STDOUT_FILENO, slave_file_spec, false, true); + + // Only use the slave tty if we don't have anything specified for + // error and don't have an action for stderr + if (GetFileActionForFD(STDERR_FILENO) == nullptr) + AppendOpenFileAction(STDERR_FILENO, slave_file_spec, false, true); + return llvm::Error::success(); } bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell( @@ -359,7 +266,7 @@ bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell( // Add a modified PATH environment variable in case argv[0] is a // relative path. const char *argv0 = argv[0]; - FileSpec arg_spec(argv0, false); + FileSpec arg_spec(argv0); if (arg_spec.IsRelative()) { // We have a relative path to our executable which may not work if we // just try to run "a.out" (without it being converted to "./a.out") @@ -439,10 +346,3 @@ bool ProcessLaunchInfo::ConvertArgumentsForLaunchingInShell( } return false; } - -ListenerSP ProcessLaunchInfo::GetListenerForProcess(Debugger &debugger) { - if (m_listener_sp) - return m_listener_sp; - else - return debugger.GetListener(); -} diff --git a/contrib/llvm/tools/lldb/source/Target/Queue.cpp b/contrib/llvm/tools/lldb/source/Target/Queue.cpp index 45fdbea13db5..c0683d10b151 100644 --- a/contrib/llvm/tools/lldb/source/Target/Queue.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Queue.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Queue.h" #include "lldb/Target/Process.h" #include "lldb/Target/QueueList.h" diff --git a/contrib/llvm/tools/lldb/source/Target/QueueItem.cpp b/contrib/llvm/tools/lldb/source/Target/QueueItem.cpp index fe58980c01c1..a20fa918a758 100644 --- a/contrib/llvm/tools/lldb/source/Target/QueueItem.cpp +++ b/contrib/llvm/tools/lldb/source/Target/QueueItem.cpp @@ -94,7 +94,7 @@ std::string QueueItem::GetQueueLabel() { ProcessSP QueueItem::GetProcessSP() { return m_process_wp.lock(); } void QueueItem::FetchEntireItem() { - if (m_have_fetched_entire_item == true) + if (m_have_fetched_entire_item) return; ProcessSP process_sp = m_process_wp.lock(); if (process_sp) { diff --git a/contrib/llvm/tools/lldb/source/Target/RegisterContext.cpp b/contrib/llvm/tools/lldb/source/Target/RegisterContext.cpp index eaec03d9b595..976f9e8b45e7 100644 --- a/contrib/llvm/tools/lldb/source/Target/RegisterContext.cpp +++ b/contrib/llvm/tools/lldb/source/Target/RegisterContext.cpp @@ -7,14 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/RegisterContext.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" -#include "lldb/Core/Scalar.h" #include "lldb/Core/Value.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Target/ExecutionContext.h" @@ -24,6 +18,8 @@ #include "lldb/Target/Thread.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" +#include "lldb/Utility/RegisterValue.h" +#include "lldb/Utility/Scalar.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/RegisterNumber.cpp b/contrib/llvm/tools/lldb/source/Target/RegisterNumber.cpp index d1bb8adf56e1..8b01bd103395 100644 --- a/contrib/llvm/tools/lldb/source/Target/RegisterNumber.cpp +++ b/contrib/llvm/tools/lldb/source/Target/RegisterNumber.cpp @@ -61,26 +61,15 @@ bool RegisterNumber::operator==(RegisterNumber &rhs) { return false; if (m_kind == rhs.m_kind) { - if (m_regnum == rhs.m_regnum) - return true; - else - return false; + return m_regnum == rhs.m_regnum; } uint32_t rhs_regnum = rhs.GetAsKind(m_kind); if (rhs_regnum != LLDB_INVALID_REGNUM) { - if (m_regnum == rhs_regnum) - return true; - else - return false; + return m_regnum == rhs_regnum; } uint32_t lhs_regnum = GetAsKind(rhs.m_kind); - { - if (lhs_regnum == rhs.m_regnum) - return true; - else - return false; - } + { return lhs_regnum == rhs.m_regnum; } return false; } diff --git a/contrib/llvm/tools/lldb/source/Target/SectionLoadHistory.cpp b/contrib/llvm/tools/lldb/source/Target/SectionLoadHistory.cpp index 5844da5d41e9..1229933793ff 100644 --- a/contrib/llvm/tools/lldb/source/Target/SectionLoadHistory.cpp +++ b/contrib/llvm/tools/lldb/source/Target/SectionLoadHistory.cpp @@ -9,10 +9,6 @@ #include "lldb/Target/SectionLoadHistory.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/SectionLoadList.h" #include "lldb/Utility/Stream.h" diff --git a/contrib/llvm/tools/lldb/source/Target/SectionLoadList.cpp b/contrib/llvm/tools/lldb/source/Target/SectionLoadList.cpp index 6839aaccaa52..ea9f7ea9911c 100644 --- a/contrib/llvm/tools/lldb/source/Target/SectionLoadList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/SectionLoadList.cpp @@ -9,10 +9,6 @@ #include "lldb/Target/SectionLoadList.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Module.h" #include "lldb/Core/Section.h" #include "lldb/Symbol/Block.h" diff --git a/contrib/llvm/tools/lldb/source/Target/StackFrame.cpp b/contrib/llvm/tools/lldb/source/Target/StackFrame.cpp index 2b9260f95f3f..3cea6444596c 100644 --- a/contrib/llvm/tools/lldb/source/Target/StackFrame.cpp +++ b/contrib/llvm/tools/lldb/source/Target/StackFrame.cpp @@ -7,17 +7,12 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/StackFrame.h" #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/Module.h" -#include "lldb/Core/RegisterValue.h" #include "lldb/Core/Value.h" #include "lldb/Core/ValueObjectConstResult.h" #include "lldb/Core/ValueObjectMemory.h" @@ -32,8 +27,12 @@ #include "lldb/Target/ExecutionContext.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" +#include "lldb/Utility/RegisterValue.h" + +#include "lldb/lldb-enumerations.h" using namespace lldb; using namespace lldb_private; @@ -49,20 +48,19 @@ using namespace lldb_private; StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, user_id_t unwind_frame_index, addr_t cfa, - bool cfa_is_valid, addr_t pc, uint32_t stop_id, - bool stop_id_is_valid, bool is_history_frame, + bool cfa_is_valid, addr_t pc, StackFrame::Kind kind, const SymbolContext *sc_ptr) : m_thread_wp(thread_sp), m_frame_index(frame_idx), m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(), m_id(pc, cfa, nullptr), m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(), m_frame_base_error(), m_cfa_is_valid(cfa_is_valid), - m_stop_id(stop_id), m_stop_id_is_valid(stop_id_is_valid), - m_is_history_frame(is_history_frame), m_variable_list_sp(), - m_variable_list_value_objects(), m_disassembly(), m_mutex() { + m_stack_frame_kind(kind), m_variable_list_sp(), + m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(), + m_mutex() { // If we don't have a CFA value, use the frame index for our StackID so that // recursive functions properly aren't confused with one another on a history // stack. - if (m_is_history_frame && !m_cfa_is_valid) { + if (IsHistorical() && !m_cfa_is_valid) { m_id.SetCFA(m_frame_index); } @@ -80,9 +78,9 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, m_concrete_frame_index(unwind_frame_index), m_reg_context_sp(reg_context_sp), m_id(pc, cfa, nullptr), m_frame_code_addr(pc), m_sc(), m_flags(), m_frame_base(), - m_frame_base_error(), m_cfa_is_valid(true), m_stop_id(0), - m_stop_id_is_valid(false), m_is_history_frame(false), - m_variable_list_sp(), m_variable_list_value_objects(), m_disassembly(), + m_frame_base_error(), m_cfa_is_valid(true), + m_stack_frame_kind(StackFrame::Kind::Regular), m_variable_list_sp(), + m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(), m_mutex() { if (sc_ptr != nullptr) { m_sc = *sc_ptr; @@ -106,9 +104,9 @@ StackFrame::StackFrame(const ThreadSP &thread_sp, user_id_t frame_idx, m_id(pc_addr.GetLoadAddress(thread_sp->CalculateTarget().get()), cfa, nullptr), m_frame_code_addr(pc_addr), m_sc(), m_flags(), m_frame_base(), - m_frame_base_error(), m_cfa_is_valid(true), m_stop_id(0), - m_stop_id_is_valid(false), m_is_history_frame(false), - m_variable_list_sp(), m_variable_list_value_objects(), m_disassembly(), + m_frame_base_error(), m_cfa_is_valid(true), + m_stack_frame_kind(StackFrame::Kind::Regular), m_variable_list_sp(), + m_variable_list_value_objects(), m_recognized_frame_sp(), m_disassembly(), m_mutex() { if (sc_ptr != nullptr) { m_sc = *sc_ptr; @@ -210,7 +208,7 @@ const Address &StackFrame::GetFrameCodeAddress() { bool StackFrame::ChangePC(addr_t pc) { std::lock_guard guard(m_mutex); // We can't change the pc value of a history stack frame - it is immutable. - if (m_is_history_frame) + if (IsHistorical()) return false; m_frame_code_addr.SetRawAddress(pc); m_sc.Clear(false); @@ -266,7 +264,8 @@ Block *StackFrame::GetFrameBlock() { // StackFrame object, everyone will have as much information as possible and no // one will ever have to look things up manually. //---------------------------------------------------------------------- -const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) { +const SymbolContext & +StackFrame::GetSymbolContext(SymbolContextItem resolve_scope) { std::lock_guard guard(m_mutex); // Copy our internal symbol context into "sc". if ((m_flags.Get() & resolve_scope) != resolve_scope) { @@ -318,7 +317,7 @@ const SymbolContext &StackFrame::GetSymbolContext(uint32_t resolve_scope) { // haven't already tried to lookup one of those things. If we haven't // then we will do the query. - uint32_t actual_resolve_scope = 0; + SymbolContextItem actual_resolve_scope = SymbolContextItem(0); if (resolve_scope & eSymbolContextCompUnit) { if (m_flags.IsClear(eSymbolContextCompUnit)) { @@ -456,7 +455,7 @@ StackFrame::GetInScopeVariableList(bool get_file_globals, bool must_have_valid_location) { std::lock_guard guard(m_mutex); // We can't fetch variable information for a history stack frame. - if (m_is_history_frame) + if (IsHistorical()) return VariableListSP(); VariableListSP var_list_sp(new VariableList); @@ -490,7 +489,7 @@ ValueObjectSP StackFrame::GetValueForVariableExpressionPath( VariableSP &var_sp, Status &error) { llvm::StringRef original_var_expr = var_expr; // We can't fetch variable information for a history stack frame. - if (m_is_history_frame) + if (IsHistorical()) return ValueObjectSP(); if (var_expr.empty()) { @@ -1080,9 +1079,9 @@ bool StackFrame::GetFrameBaseValue(Scalar &frame_base, Status *error_ptr) { m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress( exe_ctx.GetTargetPtr()); - if (m_sc.function->GetFrameBaseExpression().Evaluate( + if (!m_sc.function->GetFrameBaseExpression().Evaluate( &exe_ctx, nullptr, loclist_base_addr, nullptr, nullptr, - expr_value, &m_frame_base_error) == false) { + expr_value, &m_frame_base_error)) { // We should really have an error if evaluate returns, but in case we // don't, lets set the error to something at least. if (m_frame_base_error.Success()) @@ -1135,7 +1134,7 @@ StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp, DynamicValueType use_dynamic) { std::lock_guard guard(m_mutex); ValueObjectSP valobj_sp; - if (m_is_history_frame) { + if (IsHistorical()) { return valobj_sp; } VariableList *var_list = GetVariableList(true); @@ -1164,7 +1163,7 @@ StackFrame::GetValueObjectForFrameVariable(const VariableSP &variable_sp, ValueObjectSP StackFrame::TrackGlobalVariable(const VariableSP &variable_sp, DynamicValueType use_dynamic) { std::lock_guard guard(m_mutex); - if (m_is_history_frame) + if (IsHistorical()) return ValueObjectSP(); // Check to make sure we aren't already tracking this variable? @@ -1194,6 +1193,14 @@ bool StackFrame::IsInlined() { return false; } +bool StackFrame::IsHistorical() const { + return m_stack_frame_kind == StackFrame::Kind::History; +} + +bool StackFrame::IsArtificial() const { + return m_stack_frame_kind == StackFrame::Kind::Artificial; +} + lldb::LanguageType StackFrame::GetLanguage() { CompileUnit *cu = GetSymbolContext(eSymbolContextCompUnit).comp_unit; if (cu) @@ -1709,6 +1716,41 @@ lldb::ValueObjectSP StackFrame::GuessValueForRegisterAndOffset(ConstString reg, GetFrameCodeAddress()); } +lldb::ValueObjectSP StackFrame::FindVariable(ConstString name) { + ValueObjectSP value_sp; + + if (!name) + return value_sp; + + TargetSP target_sp = CalculateTarget(); + ProcessSP process_sp = CalculateProcess(); + + if (!target_sp && !process_sp) + return value_sp; + + VariableList variable_list; + VariableSP var_sp; + SymbolContext sc(GetSymbolContext(eSymbolContextBlock)); + + if (sc.block) { + const bool can_create = true; + const bool get_parent_variables = true; + const bool stop_if_block_is_inlined_function = true; + + if (sc.block->AppendVariables( + can_create, get_parent_variables, stop_if_block_is_inlined_function, + [this](Variable *v) { return v->IsInScope(this); }, + &variable_list)) { + var_sp = variable_list.FindVariable(name); + } + + if (var_sp) + value_sp = GetValueObjectForFrameVariable(var_sp, eNoDynamicValues); + } + + return value_sp; +} + TargetSP StackFrame::CalculateTarget() { TargetSP target_sp; ThreadSP thread_sp(GetThread()); @@ -1910,3 +1952,11 @@ bool StackFrame::GetStatus(Stream &strm, bool show_frame_info, bool show_source, } return true; } + +RecognizedStackFrameSP StackFrame::GetRecognizedFrame() { + if (!m_recognized_frame_sp) { + m_recognized_frame_sp = + StackFrameRecognizerManager::RecognizeFrame(CalculateStackFrame()); + } + return m_recognized_frame_sp; +} diff --git a/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp b/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp index 2380a91df41d..fc9fcec6c076 100644 --- a/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/StackFrameList.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/StackFrameList.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" @@ -27,6 +23,7 @@ #include "lldb/Target/Thread.h" #include "lldb/Target/Unwind.h" #include "lldb/Utility/Log.h" +#include "llvm/ADT/SmallPtrSet.h" //#define DEBUG_STACK_FRAMES 1 @@ -81,127 +78,119 @@ uint32_t StackFrameList::GetCurrentInlinedDepth() { } void StackFrameList::ResetCurrentInlinedDepth() { + if (!m_show_inlined_frames) + return; + std::lock_guard guard(m_mutex); - if (m_show_inlined_frames) { - GetFramesUpTo(0); - if (m_frames.empty()) - return; - if (!m_frames[0]->IsInlined()) { - m_current_inlined_depth = UINT32_MAX; - m_current_inlined_pc = LLDB_INVALID_ADDRESS; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (log && log->GetVerbose()) - log->Printf( - "ResetCurrentInlinedDepth: Invalidating current inlined depth.\n"); - } else { - // We only need to do something special about inlined blocks when we are - // at the beginning of an inlined function: - // FIXME: We probably also have to do something special if the PC is at - // the END - // of an inlined function, which coincides with the end of either its - // containing function or another inlined function. + GetFramesUpTo(0); + if (m_frames.empty()) + return; + if (!m_frames[0]->IsInlined()) { + m_current_inlined_depth = UINT32_MAX; + m_current_inlined_pc = LLDB_INVALID_ADDRESS; + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + if (log && log->GetVerbose()) + log->Printf( + "ResetCurrentInlinedDepth: Invalidating current inlined depth.\n"); + return; + } - lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC(); - Block *block_ptr = m_frames[0]->GetFrameBlock(); - if (block_ptr) { - Address pc_as_address; - pc_as_address.SetLoadAddress(curr_pc, - &(m_thread.GetProcess()->GetTarget())); - AddressRange containing_range; - if (block_ptr->GetRangeContainingAddress(pc_as_address, - containing_range)) { - if (pc_as_address == containing_range.GetBaseAddress()) { - // If we got here because of a breakpoint hit, then set the inlined - // depth depending on where the breakpoint was set. If we got here - // because of a crash, then set the inlined depth to the deepest - // most block. Otherwise, we stopped here naturally as the result - // of a step, so set ourselves in the containing frame of the whole - // set of nested inlines, so the user can then "virtually" step - // into the frames one by one, or next over the whole mess. Note: - // We don't have to handle being somewhere in the middle of the - // stack here, since ResetCurrentInlinedDepth doesn't get called if - // there is a valid inlined depth set. - StopInfoSP stop_info_sp = m_thread.GetStopInfo(); - if (stop_info_sp) { - switch (stop_info_sp->GetStopReason()) { - case eStopReasonWatchpoint: - case eStopReasonException: - case eStopReasonExec: - case eStopReasonSignal: - // In all these cases we want to stop in the deepest most - // frame. - m_current_inlined_pc = curr_pc; - m_current_inlined_depth = 0; - break; - case eStopReasonBreakpoint: { - // FIXME: Figure out what this break point is doing, and set the - // inline depth - // appropriately. Be careful to take into account breakpoints - // that implement step over prologue, since that should do the - // default calculation. For now, if the breakpoints - // corresponding to this hit are all internal, - // I set the stop location to the top of the inlined stack, - // since that will make - // things like stepping over prologues work right. But if - // there are any non-internal breakpoints I do to the bottom of - // the stack, since that was the old behavior. - uint32_t bp_site_id = stop_info_sp->GetValue(); - BreakpointSiteSP bp_site_sp( - m_thread.GetProcess()->GetBreakpointSiteList().FindByID( - bp_site_id)); - bool all_internal = true; - if (bp_site_sp) { - uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); - for (uint32_t i = 0; i < num_owners; i++) { - Breakpoint &bp_ref = - bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); - if (!bp_ref.IsInternal()) { - all_internal = false; - } - } - } - if (!all_internal) { - m_current_inlined_pc = curr_pc; - m_current_inlined_depth = 0; - break; - } - } - LLVM_FALLTHROUGH; - default: { - // Otherwise, we should set ourselves at the container of the - // inlining, so that the user can descend into them. So first - // we check whether we have more than one inlined block sharing - // this PC: - int num_inlined_functions = 0; + // We only need to do something special about inlined blocks when we are + // at the beginning of an inlined function: + // FIXME: We probably also have to do something special if the PC is at + // the END of an inlined function, which coincides with the end of either + // its containing function or another inlined function. - for (Block *container_ptr = block_ptr->GetInlinedParent(); - container_ptr != nullptr; - container_ptr = container_ptr->GetInlinedParent()) { - if (!container_ptr->GetRangeContainingAddress( - pc_as_address, containing_range)) - break; - if (pc_as_address != containing_range.GetBaseAddress()) - break; + Block *block_ptr = m_frames[0]->GetFrameBlock(); + if (!block_ptr) + return; - num_inlined_functions++; - } - m_current_inlined_pc = curr_pc; - m_current_inlined_depth = num_inlined_functions + 1; - Log *log( - lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); - if (log && log->GetVerbose()) - log->Printf("ResetCurrentInlinedDepth: setting inlined " - "depth: %d 0x%" PRIx64 ".\n", - m_current_inlined_depth, curr_pc); + Address pc_as_address; + lldb::addr_t curr_pc = m_thread.GetRegisterContext()->GetPC(); + pc_as_address.SetLoadAddress(curr_pc, &(m_thread.GetProcess()->GetTarget())); + AddressRange containing_range; + if (!block_ptr->GetRangeContainingAddress(pc_as_address, containing_range) || + pc_as_address != containing_range.GetBaseAddress()) + return; - } break; - } - } - } + // If we got here because of a breakpoint hit, then set the inlined depth + // depending on where the breakpoint was set. If we got here because of a + // crash, then set the inlined depth to the deepest most block. Otherwise, + // we stopped here naturally as the result of a step, so set ourselves in the + // containing frame of the whole set of nested inlines, so the user can then + // "virtually" step into the frames one by one, or next over the whole mess. + // Note: We don't have to handle being somewhere in the middle of the stack + // here, since ResetCurrentInlinedDepth doesn't get called if there is a + // valid inlined depth set. + StopInfoSP stop_info_sp = m_thread.GetStopInfo(); + if (!stop_info_sp) + return; + switch (stop_info_sp->GetStopReason()) { + case eStopReasonWatchpoint: + case eStopReasonException: + case eStopReasonExec: + case eStopReasonSignal: + // In all these cases we want to stop in the deepest frame. + m_current_inlined_pc = curr_pc; + m_current_inlined_depth = 0; + break; + case eStopReasonBreakpoint: { + // FIXME: Figure out what this break point is doing, and set the inline + // depth appropriately. Be careful to take into account breakpoints that + // implement step over prologue, since that should do the default + // calculation. For now, if the breakpoints corresponding to this hit are + // all internal, I set the stop location to the top of the inlined stack, + // since that will make things like stepping over prologues work right. + // But if there are any non-internal breakpoints I do to the bottom of the + // stack, since that was the old behavior. + uint32_t bp_site_id = stop_info_sp->GetValue(); + BreakpointSiteSP bp_site_sp( + m_thread.GetProcess()->GetBreakpointSiteList().FindByID(bp_site_id)); + bool all_internal = true; + if (bp_site_sp) { + uint32_t num_owners = bp_site_sp->GetNumberOfOwners(); + for (uint32_t i = 0; i < num_owners; i++) { + Breakpoint &bp_ref = bp_site_sp->GetOwnerAtIndex(i)->GetBreakpoint(); + if (!bp_ref.IsInternal()) { + all_internal = false; } } } + if (!all_internal) { + m_current_inlined_pc = curr_pc; + m_current_inlined_depth = 0; + break; + } + } + LLVM_FALLTHROUGH; + default: { + // Otherwise, we should set ourselves at the container of the inlining, so + // that the user can descend into them. So first we check whether we have + // more than one inlined block sharing this PC: + int num_inlined_functions = 0; + + for (Block *container_ptr = block_ptr->GetInlinedParent(); + container_ptr != nullptr; + container_ptr = container_ptr->GetInlinedParent()) { + if (!container_ptr->GetRangeContainingAddress(pc_as_address, + containing_range)) + break; + if (pc_as_address != containing_range.GetBaseAddress()) + break; + + num_inlined_functions++; + } + m_current_inlined_pc = curr_pc; + m_current_inlined_depth = num_inlined_functions + 1; + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + if (log && log->GetVerbose()) + log->Printf("ResetCurrentInlinedDepth: setting inlined " + "depth: %d 0x%" PRIx64 ".\n", + m_current_inlined_depth, curr_pc); + + break; + } } } @@ -226,8 +215,202 @@ void StackFrameList::SetCurrentInlinedDepth(uint32_t new_depth) { m_current_inlined_pc = m_thread.GetRegisterContext()->GetPC(); } +void StackFrameList::GetOnlyConcreteFramesUpTo(uint32_t end_idx, + Unwind *unwinder) { + assert(m_thread.IsValid() && "Expected valid thread"); + assert(m_frames.size() <= end_idx && "Expected there to be frames to fill"); + + if (end_idx < m_concrete_frames_fetched) + return; + + if (!unwinder) + return; + + uint32_t num_frames = unwinder->GetFramesUpTo(end_idx); + if (num_frames <= end_idx + 1) { + // Done unwinding. + m_concrete_frames_fetched = UINT32_MAX; + } + + // Don't create the frames eagerly. Defer this work to GetFrameAtIndex, + // which can lazily query the unwinder to create frames. + m_frames.resize(num_frames); +} + +/// Find the unique path through the call graph from \p begin (with return PC +/// \p return_pc) to \p end. On success this path is stored into \p path, and +/// on failure \p path is unchanged. +static void FindInterveningFrames(Function &begin, Function &end, + Target &target, addr_t return_pc, + std::vector &path, + ModuleList &images, Log *log) { + LLDB_LOG(log, "Finding frames between {0} and {1}, retn-pc={2:x}", + begin.GetDisplayName(), end.GetDisplayName(), return_pc); + + // Find a non-tail calling edge with the correct return PC. + auto first_level_edges = begin.GetCallEdges(); + if (log) + for (const CallEdge &edge : first_level_edges) + LLDB_LOG(log, "FindInterveningFrames: found call with retn-PC = {0:x}", + edge.GetReturnPCAddress(begin, target)); + auto first_edge_it = std::lower_bound( + first_level_edges.begin(), first_level_edges.end(), return_pc, + [&](const CallEdge &edge, addr_t target_pc) { + return edge.GetReturnPCAddress(begin, target) < target_pc; + }); + if (first_edge_it == first_level_edges.end() || + first_edge_it->GetReturnPCAddress(begin, target) != return_pc) { + LLDB_LOG(log, "No call edge outgoing from {0} with retn-PC == {1:x}", + begin.GetDisplayName(), return_pc); + return; + } + CallEdge &first_edge = const_cast(*first_edge_it); + + // The first callee may not be resolved, or there may be nothing to fill in. + Function *first_callee = first_edge.GetCallee(images); + if (!first_callee) { + LLDB_LOG(log, "Could not resolve callee"); + return; + } + if (first_callee == &end) { + LLDB_LOG(log, "Not searching further, first callee is {0} (retn-PC: {1:x})", + end.GetDisplayName(), return_pc); + return; + } + + // Run DFS on the tail-calling edges out of the first callee to find \p end. + // Fully explore the set of functions reachable from the first edge via tail + // calls in order to detect ambiguous executions. + struct DFS { + std::vector active_path = {}; + std::vector solution_path = {}; + llvm::SmallPtrSet visited_nodes = {}; + bool ambiguous = false; + Function *end; + ModuleList &images; + + DFS(Function *end, ModuleList &images) : end(end), images(images) {} + + void search(Function *first_callee, std::vector &path) { + dfs(first_callee); + if (!ambiguous) + path = std::move(solution_path); + } + + void dfs(Function *callee) { + // Found a path to the target function. + if (callee == end) { + if (solution_path.empty()) + solution_path = active_path; + else + ambiguous = true; + return; + } + + // Terminate the search if tail recursion is found, or more generally if + // there's more than one way to reach a target. This errs on the side of + // caution: it conservatively stops searching when some solutions are + // still possible to save time in the average case. + if (!visited_nodes.insert(callee).second) { + ambiguous = true; + return; + } + + // Search the calls made from this callee. + active_path.push_back(callee); + for (CallEdge &edge : callee->GetTailCallingEdges()) { + Function *next_callee = edge.GetCallee(images); + if (!next_callee) + continue; + + dfs(next_callee); + if (ambiguous) + return; + } + active_path.pop_back(); + } + }; + + DFS(&end, images).search(first_callee, path); +} + +/// Given that \p next_frame will be appended to the frame list, synthesize +/// tail call frames between the current end of the list and \p next_frame. +/// If any frames are added, adjust the frame index of \p next_frame. +/// +/// -------------- +/// | ... | <- Completed frames. +/// -------------- +/// | prev_frame | +/// -------------- +/// | ... | <- Artificial frames inserted here. +/// -------------- +/// | next_frame | +/// -------------- +/// | ... | <- Not-yet-visited frames. +/// -------------- +void StackFrameList::SynthesizeTailCallFrames(StackFrame &next_frame) { + TargetSP target_sp = next_frame.CalculateTarget(); + if (!target_sp) + return; + + lldb::RegisterContextSP next_reg_ctx_sp = next_frame.GetRegisterContext(); + if (!next_reg_ctx_sp) + return; + + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + + assert(!m_frames.empty() && "Cannot synthesize frames in an empty stack"); + StackFrame &prev_frame = *m_frames.back().get(); + + // Find the functions prev_frame and next_frame are stopped in. The function + // objects are needed to search the lazy call graph for intervening frames. + Function *prev_func = + prev_frame.GetSymbolContext(eSymbolContextFunction).function; + if (!prev_func) { + LLDB_LOG(log, "SynthesizeTailCallFrames: can't find previous function"); + return; + } + Function *next_func = + next_frame.GetSymbolContext(eSymbolContextFunction).function; + if (!next_func) { + LLDB_LOG(log, "SynthesizeTailCallFrames: can't find next function"); + return; + } + + // Try to find the unique sequence of (tail) calls which led from next_frame + // to prev_frame. + std::vector path; + addr_t return_pc = next_reg_ctx_sp->GetPC(); + Target &target = *target_sp.get(); + ModuleList &images = next_frame.CalculateTarget()->GetImages(); + FindInterveningFrames(*next_func, *prev_func, target, return_pc, path, images, + log); + + // Push synthetic tail call frames. + for (Function *callee : llvm::reverse(path)) { + uint32_t frame_idx = m_frames.size(); + uint32_t concrete_frame_idx = next_frame.GetConcreteFrameIndex(); + addr_t cfa = LLDB_INVALID_ADDRESS; + bool cfa_is_valid = false; + addr_t pc = + callee->GetAddressRange().GetBaseAddress().GetLoadAddress(&target); + SymbolContext sc; + callee->CalculateSymbolContext(&sc); + auto synth_frame = std::make_shared( + m_thread.shared_from_this(), frame_idx, concrete_frame_idx, cfa, + cfa_is_valid, pc, StackFrame::Kind::Artificial, &sc); + m_frames.push_back(synth_frame); + LLDB_LOG(log, "Pushed frame {0}", callee->GetDisplayName()); + } + + // If any frames were created, adjust next_frame's index. + if (!path.empty()) + next_frame.SetFrameIndex(m_frames.size()); +} + void StackFrameList::GetFramesUpTo(uint32_t end_idx) { - // this makes sure we do not fetch frames for an invalid thread + // Do not fetch frames for an invalid thread. if (!m_thread.IsValid()) return; @@ -238,201 +421,189 @@ void StackFrameList::GetFramesUpTo(uint32_t end_idx) { Unwind *unwinder = m_thread.GetUnwinder(); - if (m_show_inlined_frames) { -#if defined(DEBUG_STACK_FRAMES) - StreamFile s(stdout, false); -#endif - // If we are hiding some frames from the outside world, we need to add - // those onto the total count of frames to fetch. However, we don't need - // to do that if end_idx is 0 since in that case we always get the first - // concrete frame and all the inlined frames below it... And of course, if - // end_idx is UINT32_MAX that means get all, so just do that... - - uint32_t inlined_depth = 0; - if (end_idx > 0 && end_idx != UINT32_MAX) { - inlined_depth = GetCurrentInlinedDepth(); - if (inlined_depth != UINT32_MAX) { - if (end_idx > 0) - end_idx += inlined_depth; - } - } - - StackFrameSP unwind_frame_sp; - do { - uint32_t idx = m_concrete_frames_fetched++; - lldb::addr_t pc = LLDB_INVALID_ADDRESS; - lldb::addr_t cfa = LLDB_INVALID_ADDRESS; - if (idx == 0) { - // We might have already created frame zero, only create it if we need - // to - if (m_frames.empty()) { - RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext()); - - if (reg_ctx_sp) { - const bool success = - unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); - // There shouldn't be any way not to get the frame info for frame - // 0. But if the unwinder can't make one, lets make one by hand - // with the - // SP as the CFA and see if that gets any further. - if (!success) { - cfa = reg_ctx_sp->GetSP(); - pc = reg_ctx_sp->GetPC(); - } - - unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(), - m_frames.size(), idx, - reg_ctx_sp, cfa, pc, nullptr)); - m_frames.push_back(unwind_frame_sp); - } - } else { - unwind_frame_sp = m_frames.front(); - cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); - } - } else { - const bool success = - unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); - if (!success) { - // We've gotten to the end of the stack. - SetAllFramesFetched(); - break; - } - const bool cfa_is_valid = true; - const bool stop_id_is_valid = false; - const bool is_history_frame = false; - unwind_frame_sp.reset(new StackFrame( - m_thread.shared_from_this(), m_frames.size(), idx, cfa, - cfa_is_valid, pc, 0, stop_id_is_valid, is_history_frame, nullptr)); - m_frames.push_back(unwind_frame_sp); - } - - assert(unwind_frame_sp); - SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext( - eSymbolContextBlock | eSymbolContextFunction); - Block *unwind_block = unwind_sc.block; - if (unwind_block) { - Address curr_frame_address(unwind_frame_sp->GetFrameCodeAddress()); - TargetSP target_sp = m_thread.CalculateTarget(); - // Be sure to adjust the frame address to match the address that was - // used to lookup the symbol context above. If we are in the first - // concrete frame, then we lookup using the current address, else we - // decrement the address by one to get the correct location. - if (idx > 0) { - if (curr_frame_address.GetOffset() == 0) { - // If curr_frame_address points to the first address in a section - // then after adjustment it will point to an other section. In that - // case resolve the address again to the correct section plus - // offset form. - addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress( - target_sp.get(), AddressClass::eCode); - curr_frame_address.SetOpcodeLoadAddress( - load_addr - 1, target_sp.get(), AddressClass::eCode); - } else { - curr_frame_address.Slide(-1); - } - } - - SymbolContext next_frame_sc; - Address next_frame_address; - - while (unwind_sc.GetParentOfInlinedScope( - curr_frame_address, next_frame_sc, next_frame_address)) { - next_frame_sc.line_entry.ApplyFileMappings(target_sp); - StackFrameSP frame_sp( - new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, - unwind_frame_sp->GetRegisterContextSP(), cfa, - next_frame_address, &next_frame_sc)); - - m_frames.push_back(frame_sp); - unwind_sc = next_frame_sc; - curr_frame_address = next_frame_address; - } - } - } while (m_frames.size() - 1 < end_idx); - - // Don't try to merge till you've calculated all the frames in this stack. - if (GetAllFramesFetched() && m_prev_frames_sp) { - StackFrameList *prev_frames = m_prev_frames_sp.get(); - StackFrameList *curr_frames = this; - -// curr_frames->m_current_inlined_depth = prev_frames->m_current_inlined_depth; -// curr_frames->m_current_inlined_pc = prev_frames->m_current_inlined_pc; -// printf ("GetFramesUpTo: Copying current inlined depth: %d 0x%" PRIx64 ".\n", -// curr_frames->m_current_inlined_depth, curr_frames->m_current_inlined_pc); + if (!m_show_inlined_frames) { + GetOnlyConcreteFramesUpTo(end_idx, unwinder); + return; + } #if defined(DEBUG_STACK_FRAMES) - s.PutCString("\nprev_frames:\n"); - prev_frames->Dump(&s); - s.PutCString("\ncurr_frames:\n"); - curr_frames->Dump(&s); - s.EOL(); + StreamFile s(stdout, false); #endif - size_t curr_frame_num, prev_frame_num; + // If we are hiding some frames from the outside world, we need to add + // those onto the total count of frames to fetch. However, we don't need + // to do that if end_idx is 0 since in that case we always get the first + // concrete frame and all the inlined frames below it... And of course, if + // end_idx is UINT32_MAX that means get all, so just do that... - for (curr_frame_num = curr_frames->m_frames.size(), - prev_frame_num = prev_frames->m_frames.size(); - curr_frame_num > 0 && prev_frame_num > 0; - --curr_frame_num, --prev_frame_num) { - const size_t curr_frame_idx = curr_frame_num - 1; - const size_t prev_frame_idx = prev_frame_num - 1; - StackFrameSP curr_frame_sp(curr_frames->m_frames[curr_frame_idx]); - StackFrameSP prev_frame_sp(prev_frames->m_frames[prev_frame_idx]); - -#if defined(DEBUG_STACK_FRAMES) - s.Printf("\n\nCurr frame #%u ", curr_frame_idx); - if (curr_frame_sp) - curr_frame_sp->Dump(&s, true, false); - else - s.PutCString("NULL"); - s.Printf("\nPrev frame #%u ", prev_frame_idx); - if (prev_frame_sp) - prev_frame_sp->Dump(&s, true, false); - else - s.PutCString("NULL"); -#endif - - StackFrame *curr_frame = curr_frame_sp.get(); - StackFrame *prev_frame = prev_frame_sp.get(); - - if (curr_frame == nullptr || prev_frame == nullptr) - break; - - // Check the stack ID to make sure they are equal - if (curr_frame->GetStackID() != prev_frame->GetStackID()) - break; - - prev_frame->UpdatePreviousFrameFromCurrentFrame(*curr_frame); - // Now copy the fixed up previous frame into the current frames so the - // pointer doesn't change - m_frames[curr_frame_idx] = prev_frame_sp; -// curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame); - -#if defined(DEBUG_STACK_FRAMES) - s.Printf("\n Copying previous frame to current frame"); -#endif - } - // We are done with the old stack frame list, we can release it now - m_prev_frames_sp.reset(); - } - -#if defined(DEBUG_STACK_FRAMES) - s.PutCString("\n\nNew frames:\n"); - Dump(&s); - s.EOL(); -#endif - } else { - if (end_idx < m_concrete_frames_fetched) - return; - - if (unwinder) { - uint32_t num_frames = unwinder->GetFramesUpTo(end_idx); - if (num_frames <= end_idx + 1) { - // Done unwinding. - m_concrete_frames_fetched = UINT32_MAX; - } - m_frames.resize(num_frames); + uint32_t inlined_depth = 0; + if (end_idx > 0 && end_idx != UINT32_MAX) { + inlined_depth = GetCurrentInlinedDepth(); + if (inlined_depth != UINT32_MAX) { + if (end_idx > 0) + end_idx += inlined_depth; } } + + StackFrameSP unwind_frame_sp; + do { + uint32_t idx = m_concrete_frames_fetched++; + lldb::addr_t pc = LLDB_INVALID_ADDRESS; + lldb::addr_t cfa = LLDB_INVALID_ADDRESS; + if (idx == 0) { + // We might have already created frame zero, only create it if we need + // to. + if (m_frames.empty()) { + RegisterContextSP reg_ctx_sp(m_thread.GetRegisterContext()); + + if (reg_ctx_sp) { + const bool success = + unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); + // There shouldn't be any way not to get the frame info for frame + // 0. But if the unwinder can't make one, lets make one by hand + // with the SP as the CFA and see if that gets any further. + if (!success) { + cfa = reg_ctx_sp->GetSP(); + pc = reg_ctx_sp->GetPC(); + } + + unwind_frame_sp.reset(new StackFrame(m_thread.shared_from_this(), + m_frames.size(), idx, reg_ctx_sp, + cfa, pc, nullptr)); + m_frames.push_back(unwind_frame_sp); + } + } else { + unwind_frame_sp = m_frames.front(); + cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); + } + } else { + const bool success = + unwinder && unwinder->GetFrameInfoAtIndex(idx, cfa, pc); + if (!success) { + // We've gotten to the end of the stack. + SetAllFramesFetched(); + break; + } + const bool cfa_is_valid = true; + unwind_frame_sp.reset( + new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, cfa, + cfa_is_valid, pc, StackFrame::Kind::Regular, nullptr)); + + // Create synthetic tail call frames between the previous frame and the + // newly-found frame. The new frame's index may change after this call, + // although its concrete index will stay the same. + SynthesizeTailCallFrames(*unwind_frame_sp.get()); + + m_frames.push_back(unwind_frame_sp); + } + + assert(unwind_frame_sp); + SymbolContext unwind_sc = unwind_frame_sp->GetSymbolContext( + eSymbolContextBlock | eSymbolContextFunction); + Block *unwind_block = unwind_sc.block; + if (unwind_block) { + Address curr_frame_address(unwind_frame_sp->GetFrameCodeAddress()); + TargetSP target_sp = m_thread.CalculateTarget(); + // Be sure to adjust the frame address to match the address that was + // used to lookup the symbol context above. If we are in the first + // concrete frame, then we lookup using the current address, else we + // decrement the address by one to get the correct location. + if (idx > 0) { + if (curr_frame_address.GetOffset() == 0) { + // If curr_frame_address points to the first address in a section + // then after adjustment it will point to an other section. In that + // case resolve the address again to the correct section plus + // offset form. + addr_t load_addr = curr_frame_address.GetOpcodeLoadAddress( + target_sp.get(), AddressClass::eCode); + curr_frame_address.SetOpcodeLoadAddress( + load_addr - 1, target_sp.get(), AddressClass::eCode); + } else { + curr_frame_address.Slide(-1); + } + } + + SymbolContext next_frame_sc; + Address next_frame_address; + + while (unwind_sc.GetParentOfInlinedScope( + curr_frame_address, next_frame_sc, next_frame_address)) { + next_frame_sc.line_entry.ApplyFileMappings(target_sp); + StackFrameSP frame_sp( + new StackFrame(m_thread.shared_from_this(), m_frames.size(), idx, + unwind_frame_sp->GetRegisterContextSP(), cfa, + next_frame_address, &next_frame_sc)); + + m_frames.push_back(frame_sp); + unwind_sc = next_frame_sc; + curr_frame_address = next_frame_address; + } + } + } while (m_frames.size() - 1 < end_idx); + + // Don't try to merge till you've calculated all the frames in this stack. + if (GetAllFramesFetched() && m_prev_frames_sp) { + StackFrameList *prev_frames = m_prev_frames_sp.get(); + StackFrameList *curr_frames = this; + +#if defined(DEBUG_STACK_FRAMES) + s.PutCString("\nprev_frames:\n"); + prev_frames->Dump(&s); + s.PutCString("\ncurr_frames:\n"); + curr_frames->Dump(&s); + s.EOL(); +#endif + size_t curr_frame_num, prev_frame_num; + + for (curr_frame_num = curr_frames->m_frames.size(), + prev_frame_num = prev_frames->m_frames.size(); + curr_frame_num > 0 && prev_frame_num > 0; + --curr_frame_num, --prev_frame_num) { + const size_t curr_frame_idx = curr_frame_num - 1; + const size_t prev_frame_idx = prev_frame_num - 1; + StackFrameSP curr_frame_sp(curr_frames->m_frames[curr_frame_idx]); + StackFrameSP prev_frame_sp(prev_frames->m_frames[prev_frame_idx]); + +#if defined(DEBUG_STACK_FRAMES) + s.Printf("\n\nCurr frame #%u ", curr_frame_idx); + if (curr_frame_sp) + curr_frame_sp->Dump(&s, true, false); + else + s.PutCString("NULL"); + s.Printf("\nPrev frame #%u ", prev_frame_idx); + if (prev_frame_sp) + prev_frame_sp->Dump(&s, true, false); + else + s.PutCString("NULL"); +#endif + + StackFrame *curr_frame = curr_frame_sp.get(); + StackFrame *prev_frame = prev_frame_sp.get(); + + if (curr_frame == nullptr || prev_frame == nullptr) + break; + + // Check the stack ID to make sure they are equal. + if (curr_frame->GetStackID() != prev_frame->GetStackID()) + break; + + prev_frame->UpdatePreviousFrameFromCurrentFrame(*curr_frame); + // Now copy the fixed up previous frame into the current frames so the + // pointer doesn't change. + m_frames[curr_frame_idx] = prev_frame_sp; + +#if defined(DEBUG_STACK_FRAMES) + s.Printf("\n Copying previous frame to current frame"); +#endif + } + // We are done with the old stack frame list, we can release it now. + m_prev_frames_sp.reset(); + } + +#if defined(DEBUG_STACK_FRAMES) + s.PutCString("\n\nNew frames:\n"); + Dump(&s); + s.EOL(); +#endif } uint32_t StackFrameList::GetNumFrames(bool can_create) { @@ -441,11 +612,7 @@ uint32_t StackFrameList::GetNumFrames(bool can_create) { if (can_create) GetFramesUpTo(UINT32_MAX); - uint32_t inlined_depth = GetCurrentInlinedDepth(); - if (inlined_depth == UINT32_MAX) - return m_frames.size(); - else - return m_frames.size() - inlined_depth; + return GetVisibleStackFrameIndex(m_frames.size()); } void StackFrameList::Dump(Stream *s) { @@ -497,11 +664,9 @@ StackFrameSP StackFrameList::GetFrameAtIndex(uint32_t idx) { addr_t pc, cfa; if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) { const bool cfa_is_valid = true; - const bool stop_id_is_valid = false; - const bool is_history_frame = false; - frame_sp.reset(new StackFrame( - m_thread.shared_from_this(), idx, idx, cfa, cfa_is_valid, pc, 0, - stop_id_is_valid, is_history_frame, nullptr)); + frame_sp.reset(new StackFrame(m_thread.shared_from_this(), idx, idx, + cfa, cfa_is_valid, pc, + StackFrame::Kind::Regular, nullptr)); Function *function = frame_sp->GetSymbolContext(eSymbolContextFunction).function; @@ -576,9 +741,6 @@ StackFrameSP StackFrameList::GetFrameWithStackID(const StackID &stack_id) { if ((*pos)->GetStackID() == stack_id) return *pos; } - - // if (m_frames.back()->GetStackID() < stack_id) - // frame_idx = m_frames.size(); } do { frame_sp = GetFrameAtIndex(frame_idx); @@ -625,7 +787,6 @@ uint32_t StackFrameList::SetSelectedFrame(lldb_private::StackFrame *frame) { return m_selected_frame_idx; } -// Mark a stack frame as the current frame using the frame index bool StackFrameList::SetSelectedFrameByIndex(uint32_t idx) { std::lock_guard guard(m_mutex); StackFrameSP frame_sp(GetFrameAtIndex(idx)); @@ -657,19 +818,6 @@ void StackFrameList::Clear() { m_concrete_frames_fetched = 0; } -void StackFrameList::InvalidateFrames(uint32_t start_idx) { - std::lock_guard guard(m_mutex); - if (m_show_inlined_frames) { - Clear(); - } else { - const size_t num_frames = m_frames.size(); - while (start_idx < num_frames) { - m_frames[start_idx].reset(); - ++start_idx; - } - } -} - void StackFrameList::Merge(std::unique_ptr &curr_ap, lldb::StackFrameListSP &prev_sp) { std::unique_lock current_lock, previous_lock; diff --git a/contrib/llvm/tools/lldb/source/Target/StackFrameRecognizer.cpp b/contrib/llvm/tools/lldb/source/Target/StackFrameRecognizer.cpp new file mode 100644 index 000000000000..152f4a198e20 --- /dev/null +++ b/contrib/llvm/tools/lldb/source/Target/StackFrameRecognizer.cpp @@ -0,0 +1,191 @@ +//===-- StackFrameRecognizer.cpp --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include +#include "lldb/Core/Module.h" +#include "lldb/Interpreter/ScriptInterpreter.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Target/StackFrame.h" +#include "lldb/Target/StackFrameRecognizer.h" +#include "lldb/Utility/RegularExpression.h" + +using namespace lldb; +using namespace lldb_private; + +#ifndef LLDB_DISABLE_PYTHON + +class ScriptedRecognizedStackFrame : public RecognizedStackFrame { +public: + ScriptedRecognizedStackFrame(ValueObjectListSP args) { + m_arguments = args; + } +}; + +ScriptedStackFrameRecognizer::ScriptedStackFrameRecognizer( + ScriptInterpreter *interpreter, const char *pclass) + : m_interpreter(interpreter), m_python_class(pclass) { + m_python_object_sp = + m_interpreter->CreateFrameRecognizer(m_python_class.c_str()); +} + +RecognizedStackFrameSP +ScriptedStackFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame) { + if (!m_python_object_sp || !m_interpreter) + return RecognizedStackFrameSP(); + + ValueObjectListSP args = + m_interpreter->GetRecognizedArguments(m_python_object_sp, frame); + + return RecognizedStackFrameSP(new ScriptedRecognizedStackFrame(args)); +} + +#endif + +class StackFrameRecognizerManagerImpl { +public: + void AddRecognizer(StackFrameRecognizerSP recognizer, + const ConstString &module, const ConstString &symbol, + bool first_instruction_only) { + m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, false, module, RegularExpressionSP(), + symbol, RegularExpressionSP(), + first_instruction_only}); + } + + void AddRecognizer(StackFrameRecognizerSP recognizer, + RegularExpressionSP module, RegularExpressionSP symbol, + bool first_instruction_only) { + m_recognizers.push_front({(uint32_t)m_recognizers.size(), false, recognizer, true, ConstString(), module, + ConstString(), symbol, first_instruction_only}); + } + + void ForEach( + std::function const &callback) { + for (auto entry : m_recognizers) { + if (entry.is_regexp) { + callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module_regexp->GetText(), + entry.symbol_regexp->GetText(), true); + } else { + callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(), + entry.symbol.GetCString(), false); + } + } + } + + bool RemoveRecognizerWithID(uint32_t recognizer_id) { + if (recognizer_id >= m_recognizers.size()) return false; + if (m_recognizers[recognizer_id].deleted) return false; + m_recognizers[recognizer_id].deleted = true; + return true; + } + + void RemoveAllRecognizers() { + m_recognizers.clear(); + } + + StackFrameRecognizerSP GetRecognizerForFrame(StackFrameSP frame) { + const SymbolContext &symctx = + frame->GetSymbolContext(eSymbolContextModule | eSymbolContextFunction); + ConstString function_name = symctx.GetFunctionName(); + ModuleSP module_sp = symctx.module_sp; + if (!module_sp) return StackFrameRecognizerSP(); + ConstString module_name = module_sp->GetFileSpec().GetFilename(); + Symbol *symbol = symctx.symbol; + if (!symbol) return StackFrameRecognizerSP(); + Address start_addr = symbol->GetAddress(); + Address current_addr = frame->GetFrameCodeAddress(); + + for (auto entry : m_recognizers) { + if (entry.deleted) continue; + if (entry.module) + if (entry.module != module_name) continue; + + if (entry.module_regexp) + if (!entry.module_regexp->Execute(module_name.GetStringRef())) continue; + + if (entry.symbol) + if (entry.symbol != function_name) continue; + + if (entry.symbol_regexp) + if (!entry.symbol_regexp->Execute(function_name.GetStringRef())) + continue; + + if (entry.first_instruction_only) + if (start_addr != current_addr) continue; + + return entry.recognizer; + } + return StackFrameRecognizerSP(); + } + + RecognizedStackFrameSP RecognizeFrame(StackFrameSP frame) { + auto recognizer = GetRecognizerForFrame(frame); + if (!recognizer) return RecognizedStackFrameSP(); + return recognizer->RecognizeFrame(frame); + } + + private: + struct RegisteredEntry { + uint32_t recognizer_id; + bool deleted; + StackFrameRecognizerSP recognizer; + bool is_regexp; + ConstString module; + RegularExpressionSP module_regexp; + ConstString symbol; + RegularExpressionSP symbol_regexp; + bool first_instruction_only; + }; + + std::deque m_recognizers; +}; + +StackFrameRecognizerManagerImpl &GetStackFrameRecognizerManagerImpl() { + static StackFrameRecognizerManagerImpl instance = + StackFrameRecognizerManagerImpl(); + return instance; +} + +void StackFrameRecognizerManager::AddRecognizer( + StackFrameRecognizerSP recognizer, const ConstString &module, + const ConstString &symbol, bool first_instruction_only) { + GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol, + first_instruction_only); +} + +void StackFrameRecognizerManager::AddRecognizer( + StackFrameRecognizerSP recognizer, RegularExpressionSP module, + RegularExpressionSP symbol, bool first_instruction_only) { + GetStackFrameRecognizerManagerImpl().AddRecognizer(recognizer, module, symbol, + first_instruction_only); +} + +void StackFrameRecognizerManager::ForEach( + std::function const &callback) { + GetStackFrameRecognizerManagerImpl().ForEach(callback); +} + +void StackFrameRecognizerManager::RemoveAllRecognizers() { + GetStackFrameRecognizerManagerImpl().RemoveAllRecognizers(); +} + +bool StackFrameRecognizerManager::RemoveRecognizerWithID(uint32_t recognizer_id) { + return GetStackFrameRecognizerManagerImpl().RemoveRecognizerWithID(recognizer_id); +} + +RecognizedStackFrameSP StackFrameRecognizerManager::RecognizeFrame( + StackFrameSP frame) { + return GetStackFrameRecognizerManagerImpl().RecognizeFrame(frame); +} + +StackFrameRecognizerSP StackFrameRecognizerManager::GetRecognizerForFrame( + lldb::StackFrameSP frame) { + return GetStackFrameRecognizerManagerImpl().GetRecognizerForFrame(frame); +} diff --git a/contrib/llvm/tools/lldb/source/Target/StackID.cpp b/contrib/llvm/tools/lldb/source/Target/StackID.cpp index 341c902af995..d6640b24ad5c 100644 --- a/contrib/llvm/tools/lldb/source/Target/StackID.cpp +++ b/contrib/llvm/tools/lldb/source/Target/StackID.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/StackID.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Symbol.h" diff --git a/contrib/llvm/tools/lldb/source/Target/StopInfo.cpp b/contrib/llvm/tools/lldb/source/Target/StopInfo.cpp index f8b17dc10eca..4e13c588b484 100644 --- a/contrib/llvm/tools/lldb/source/Target/StopInfo.cpp +++ b/contrib/llvm/tools/lldb/source/Target/StopInfo.cpp @@ -7,12 +7,8 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/StoppointCallbackContext.h" @@ -333,6 +329,19 @@ protected: // commands when we see the same breakpoint hit a second time. m_should_stop_is_valid = true; + + // It is possible that the user has a breakpoint at the same site + // as the completed plan had (e.g. user has a breakpoint + // on a module entry point, and `ThreadPlanCallFunction` ends + // also there). We can't find an internal breakpoint in the loop + // later because it was already removed on the plan completion. + // So check if the plan was completed, and stop if so. + if (thread_sp->CompletedPlanOverridesBreakpoint()) { + m_should_stop = true; + thread_sp->ResetStopInfo(); + return; + } + if (log) log->Printf("StopInfoBreakpoint::PerformAction - Hit a " "breakpoint while running an expression," @@ -358,9 +367,8 @@ protected: "continuing: %s.", m_should_stop ? "true" : "false"); process->GetTarget().GetDebugger().GetAsyncOutputStream()->Printf( - "Warning: hit breakpoint while " - "running function, skipping commands and conditions to prevent " - "recursion."); + "Warning: hit breakpoint while running function, skipping " + "commands and conditions to prevent recursion.\n"); return; } @@ -534,9 +542,9 @@ protected: __FUNCTION__, m_value); } - if ((m_should_stop == false || internal_breakpoint) - && thread_sp->CompletedPlanOverridesBreakpoint()) { - + if ((!m_should_stop || internal_breakpoint) && + thread_sp->CompletedPlanOverridesBreakpoint()) { + // Override should_stop decision when we have completed step plan // additionally to the breakpoint m_should_stop = true; @@ -720,14 +728,18 @@ protected: StopInfoSP stored_stop_info_sp = thread_sp->GetStopInfo(); assert(stored_stop_info_sp.get() == this); + Status new_plan_status; ThreadPlanSP new_plan_sp( thread_sp->QueueThreadPlanForStepSingleInstruction( - false, // step-over - false, // abort_other_plans - true)); // stop_other_threads - new_plan_sp->SetIsMasterPlan(true); - new_plan_sp->SetOkayToDiscard(false); - new_plan_sp->SetPrivate(true); + false, // step-over + false, // abort_other_plans + true, // stop_other_threads + new_plan_status)); + if (new_plan_sp && new_plan_status.Success()) { + new_plan_sp->SetIsMasterPlan(true); + new_plan_sp->SetOkayToDiscard(false); + new_plan_sp->SetPrivate(true); + } process_sp->GetThreadList().SetSelectedThreadByID( thread_sp->GetID()); process_sp->ResumeSynchronous(nullptr); diff --git a/contrib/llvm/tools/lldb/source/Target/SystemRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/SystemRuntime.cpp index 3fdf6daa6afa..574c01cb5ae1 100644 --- a/contrib/llvm/tools/lldb/source/Target/SystemRuntime.cpp +++ b/contrib/llvm/tools/lldb/source/Target/SystemRuntime.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/SystemRuntime.h" #include "lldb/Core/PluginManager.h" #include "lldb/Target/Process.h" diff --git a/contrib/llvm/tools/lldb/source/Target/Target.cpp b/contrib/llvm/tools/lldb/source/Target/Target.cpp index 3f70741713fb..437f92abdab3 100644 --- a/contrib/llvm/tools/lldb/source/Target/Target.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Target.cpp @@ -7,11 +7,7 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -#include -// Other libraries and framework includes -// Project includes +#include "lldb/Target/Target.h" #include "Plugins/ExpressionParser/Clang/ClangASTSource.h" #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" @@ -21,16 +17,17 @@ #include "lldb/Breakpoint/BreakpointResolverFileLine.h" #include "lldb/Breakpoint/BreakpointResolverFileRegex.h" #include "lldb/Breakpoint/BreakpointResolverName.h" +#include "lldb/Breakpoint/BreakpointResolverScripted.h" #include "lldb/Breakpoint/Watchpoint.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Event.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" +#include "lldb/Core/SearchFilter.h" #include "lldb/Core/Section.h" #include "lldb/Core/SourceManager.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" +#include "lldb/Core/StructuredDataImpl.h" #include "lldb/Core/ValueObject.h" #include "lldb/Expression/REPL.h" #include "lldb/Expression/UserExpression.h" @@ -52,14 +49,16 @@ #include "lldb/Target/SectionLoadList.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/SystemRuntime.h" -#include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Utility/Event.h" #include "lldb/Utility/FileSpec.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" +#include using namespace lldb; using namespace lldb_private; @@ -195,6 +194,8 @@ void Target::DeleteCurrentProcess() { const lldb::ProcessSP &Target::CreateProcess(ListenerSP listener_sp, llvm::StringRef plugin_name, const FileSpec *crash_file) { + if (!listener_sp) + listener_sp = GetDebugger().GetListener(); DeleteCurrentProcess(); m_process_sp = Process::FindPlugin(shared_from_this(), plugin_name, listener_sp, crash_file); @@ -322,7 +323,7 @@ BreakpointSP Target::CreateSourceRegexBreakpoint( BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, - lldb::addr_t offset, + uint32_t column, lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, bool hardware, @@ -366,8 +367,8 @@ BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules, move_to_nearest_code = GetMoveToNearestCode() ? eLazyBoolYes : eLazyBoolNo; BreakpointResolverSP resolver_sp(new BreakpointResolverFileLine( - nullptr, remapped_file, line_no, offset, check_inlines, skip_prologue, - !static_cast(move_to_nearest_code))); + nullptr, remapped_file, line_no, column, offset, check_inlines, + skip_prologue, !static_cast(move_to_nearest_code))); return CreateBreakpoint(filter_sp, resolver_sp, internal, hardware, true); } @@ -412,12 +413,11 @@ Target::CreateAddressInModuleBreakpoint(lldb::addr_t file_addr, bool internal, false); } -BreakpointSP -Target::CreateBreakpoint(const FileSpecList *containingModules, - const FileSpecList *containingSourceFiles, - const char *func_name, uint32_t func_name_type_mask, - LanguageType language, lldb::addr_t offset, - LazyBool skip_prologue, bool internal, bool hardware) { +BreakpointSP Target::CreateBreakpoint( + const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, const char *func_name, + FunctionNameType func_name_type_mask, LanguageType language, + lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) { BreakpointSP bp_sp; if (func_name) { SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList( @@ -440,9 +440,9 @@ lldb::BreakpointSP Target::CreateBreakpoint(const FileSpecList *containingModules, const FileSpecList *containingSourceFiles, const std::vector &func_names, - uint32_t func_name_type_mask, LanguageType language, - lldb::addr_t offset, LazyBool skip_prologue, - bool internal, bool hardware) { + FunctionNameType func_name_type_mask, + LanguageType language, lldb::addr_t offset, + LazyBool skip_prologue, bool internal, bool hardware) { BreakpointSP bp_sp; size_t num_names = func_names.size(); if (num_names > 0) { @@ -462,11 +462,13 @@ Target::CreateBreakpoint(const FileSpecList *containingModules, return bp_sp; } -BreakpointSP Target::CreateBreakpoint( - const FileSpecList *containingModules, - const FileSpecList *containingSourceFiles, const char *func_names[], - size_t num_names, uint32_t func_name_type_mask, LanguageType language, - lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool hardware) { +BreakpointSP +Target::CreateBreakpoint(const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, + const char *func_names[], size_t num_names, + FunctionNameType func_name_type_mask, + LanguageType language, lldb::addr_t offset, + LazyBool skip_prologue, bool internal, bool hardware) { BreakpointSP bp_sp; if (num_names > 0) { SearchFilterSP filter_sp(GetSearchFilterForModuleAndCUList( @@ -579,13 +581,56 @@ Target::CreateExceptionBreakpoint(enum lldb::LanguageType language, return exc_bkpt_sp; } +lldb::BreakpointSP +Target::CreateScriptedBreakpoint(const llvm::StringRef class_name, + const FileSpecList *containingModules, + const FileSpecList *containingSourceFiles, + bool internal, + bool request_hardware, + StructuredData::ObjectSP extra_args_sp, + Status *creation_error) +{ + SearchFilterSP filter_sp; + + lldb::SearchDepth depth = lldb::eSearchDepthTarget; + bool has_files = containingSourceFiles && containingSourceFiles->GetSize() > 0; + bool has_modules = containingModules && containingModules->GetSize() > 0; + + if (has_files && has_modules) { + filter_sp = GetSearchFilterForModuleAndCUList( + containingModules, containingSourceFiles); + } else if (has_files) { + filter_sp = GetSearchFilterForModuleAndCUList( + nullptr, containingSourceFiles); + } else if (has_modules) { + filter_sp = GetSearchFilterForModuleList(containingModules); + } else { + filter_sp.reset(new SearchFilterForUnconstrainedSearches(shared_from_this())); + } + + StructuredDataImpl *extra_args_impl = new StructuredDataImpl(); + if (extra_args_sp) + extra_args_impl->SetObjectSP(extra_args_sp); + + BreakpointResolverSP resolver_sp(new + BreakpointResolverScripted(nullptr, class_name, + depth, + extra_args_impl, + *GetDebugger().GetCommandInterpreter() + .GetScriptInterpreter())); + return CreateBreakpoint(filter_sp, resolver_sp, internal, false, true); + +} + + BreakpointSP Target::CreateBreakpoint(SearchFilterSP &filter_sp, BreakpointResolverSP &resolver_sp, bool internal, bool request_hardware, bool resolve_indirect_symbols) { BreakpointSP bp_sp; if (filter_sp && resolver_sp) { - bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, request_hardware, + const bool hardware = request_hardware || GetRequireHardwareBreakpoints(); + bp_sp.reset(new Breakpoint(*this, filter_sp, resolver_sp, hardware, resolve_indirect_symbols)); resolver_sp->SetBreakpoint(bp_sp.get()); AddBreakpoint(bp_sp, internal); @@ -719,17 +764,23 @@ void Target::GetBreakpointNames(std::vector &names) for (auto bp_name : m_breakpoint_names) { names.push_back(bp_name.first.AsCString()); } - std::sort(names.begin(), names.end()); + llvm::sort(names.begin(), names.end()); } bool Target::ProcessIsValid() { return (m_process_sp && m_process_sp->IsAlive()); } -static bool CheckIfWatchpointsExhausted(Target *target, Status &error) { +static bool CheckIfWatchpointsSupported(Target *target, Status &error) { uint32_t num_supported_hardware_watchpoints; Status rc = target->GetProcessSP()->GetWatchpointSupportInfo( num_supported_hardware_watchpoints); + + // If unable to determine the # of watchpoints available, + // assume they are supported. + if (rc.Fail()) + return true; + if (num_supported_hardware_watchpoints == 0) { error.SetErrorStringWithFormat( "Target supports (%u) hardware watchpoint slots.\n", @@ -768,7 +819,7 @@ WatchpointSP Target::CreateWatchpoint(lldb::addr_t addr, size_t size, error.SetErrorStringWithFormat("invalid watchpoint type: %d", kind); } - if (!CheckIfWatchpointsExhausted(this, error)) + if (!CheckIfWatchpointsSupported(this, error)) return wp_sp; // Currently we only support one watchpoint per address, with total number of @@ -1377,7 +1428,7 @@ void Target::DidExec() { } void Target::SetExecutableModule(ModuleSP &executable_sp, - bool get_dependent_files) { + LoadDependentFiles load_dependent_files) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); ClearModules(false); @@ -1401,8 +1452,20 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, FileSpecList dependent_files; ObjectFile *executable_objfile = executable_sp->GetObjectFile(); + bool load_dependents = true; + switch (load_dependent_files) { + case eLoadDependentsDefault: + load_dependents = executable_sp->IsExecutable(); + break; + case eLoadDependentsYes: + load_dependents = true; + break; + case eLoadDependentsNo: + load_dependents = false; + break; + } - if (executable_objfile && get_dependent_files) { + if (executable_objfile && load_dependents) { executable_objfile->GetDependentModules(dependent_files); for (uint32_t i = 0; i < dependent_files.GetSize(); i++) { FileSpec dependent_file_spec( @@ -1426,13 +1489,33 @@ void Target::SetExecutableModule(ModuleSP &executable_sp, } } -bool Target::SetArchitecture(const ArchSpec &arch_spec) { +bool Target::SetArchitecture(const ArchSpec &arch_spec, bool set_platform) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); bool missing_local_arch = !m_arch.GetSpec().IsValid(); bool replace_local_arch = true; bool compatible_local_arch = false; ArchSpec other(arch_spec); + // Changing the architecture might mean that the currently selected platform + // isn't compatible. Set the platform correctly if we are asked to do so, + // otherwise assume the user will set the platform manually. + if (set_platform) { + if (other.IsValid()) { + auto platform_sp = GetPlatform(); + if (!platform_sp || + !platform_sp->IsCompatibleArchitecture(other, false, nullptr)) { + ArchSpec platform_arch; + auto arch_platform_sp = + Platform::GetPlatformForArchitecture(other, &platform_arch); + if (arch_platform_sp) { + SetPlatform(arch_platform_sp); + if (platform_arch.IsValid()) + other = platform_arch; + } + } + } + } + if (!missing_local_arch) { if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) { other.MergeFrom(m_arch.GetSpec()); @@ -1487,7 +1570,7 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec) { nullptr, nullptr); if (!error.Fail() && executable_sp) { - SetExecutableModule(executable_sp, true); + SetExecutableModule(executable_sp, eLoadDependentsYes); return true; } } @@ -1495,11 +1578,18 @@ bool Target::SetArchitecture(const ArchSpec &arch_spec) { } bool Target::MergeArchitecture(const ArchSpec &arch_spec) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET)); if (arch_spec.IsValid()) { if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) { // The current target arch is compatible with "arch_spec", see if we can // improve our current architecture using bits from "arch_spec" + if (log) + log->Printf("Target::MergeArchitecture target has arch %s, merging with " + "arch %s", + m_arch.GetSpec().GetTriple().getTriple().c_str(), + arch_spec.GetTriple().getTriple().c_str()); + // Merge bits from arch_spec into "merged_arch" and set our architecture ArchSpec merged_arch(m_arch.GetSpec()); merged_arch.MergeFrom(arch_spec); @@ -2057,7 +2147,7 @@ void Target::ImageSearchPathsChanged(const PathMappingList &path_list, Target *target = (Target *)baton; ModuleSP exe_module_sp(target->GetExecutableModule()); if (exe_module_sp) - target->SetExecutableModule(exe_module_sp, true); + target->SetExecutableModule(exe_module_sp, eLoadDependentsYes); } TypeSystem *Target::GetScratchTypeSystemForLanguage(Status *error, @@ -2351,249 +2441,22 @@ lldb::addr_t Target::GetPersistentSymbol(const ConstString &name) { lldb::addr_t Target::GetCallableLoadAddress(lldb::addr_t load_addr, AddressClass addr_class) const { - addr_t code_addr = load_addr; - switch (m_arch.GetSpec().GetMachine()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - switch (addr_class) { - case AddressClass::eData: - case AddressClass::eDebug: - return LLDB_INVALID_ADDRESS; - - case AddressClass::eUnknown: - case AddressClass::eInvalid: - case AddressClass::eCode: - case AddressClass::eCodeAlternateISA: - case AddressClass::eRuntime: - if ((code_addr & 2ull) || (addr_class == AddressClass::eCodeAlternateISA)) - code_addr |= 1ull; - break; - } - break; - - case llvm::Triple::arm: - case llvm::Triple::thumb: - switch (addr_class) { - case AddressClass::eData: - case AddressClass::eDebug: - return LLDB_INVALID_ADDRESS; - - case AddressClass::eUnknown: - case AddressClass::eInvalid: - case AddressClass::eCode: - case AddressClass::eCodeAlternateISA: - case AddressClass::eRuntime: - // Check if bit zero it no set? - if ((code_addr & 1ull) == 0) { - // Bit zero isn't set, check if the address is a multiple of 2? - if (code_addr & 2ull) { - // The address is a multiple of 2 so it must be thumb, set bit zero - code_addr |= 1ull; - } else if (addr_class == AddressClass::eCodeAlternateISA) { - // We checked the address and the address claims to be the alternate - // ISA which means thumb, so set bit zero. - code_addr |= 1ull; - } - } - break; - } - break; - - default: - break; - } - return code_addr; + auto arch_plugin = GetArchitecturePlugin(); + return arch_plugin ? + arch_plugin->GetCallableLoadAddress(load_addr, addr_class) : load_addr; } lldb::addr_t Target::GetOpcodeLoadAddress(lldb::addr_t load_addr, AddressClass addr_class) const { - addr_t opcode_addr = load_addr; - switch (m_arch.GetSpec().GetMachine()) { - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: - case llvm::Triple::arm: - case llvm::Triple::thumb: - switch (addr_class) { - case AddressClass::eData: - case AddressClass::eDebug: - return LLDB_INVALID_ADDRESS; - - case AddressClass::eInvalid: - case AddressClass::eUnknown: - case AddressClass::eCode: - case AddressClass::eCodeAlternateISA: - case AddressClass::eRuntime: - opcode_addr &= ~(1ull); - break; - } - break; - - default: - break; - } - return opcode_addr; + auto arch_plugin = GetArchitecturePlugin(); + return arch_plugin ? + arch_plugin->GetOpcodeLoadAddress(load_addr, addr_class) : load_addr; } lldb::addr_t Target::GetBreakableLoadAddress(lldb::addr_t addr) { - addr_t breakable_addr = addr; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS)); - - switch (m_arch.GetSpec().GetMachine()) { - default: - break; - case llvm::Triple::mips: - case llvm::Triple::mipsel: - case llvm::Triple::mips64: - case llvm::Triple::mips64el: { - addr_t function_start = 0; - addr_t current_offset = 0; - uint32_t loop_count = 0; - Address resolved_addr; - uint32_t arch_flags = m_arch.GetSpec().GetFlags(); - bool IsMips16 = arch_flags & ArchSpec::eMIPSAse_mips16; - bool IsMicromips = arch_flags & ArchSpec::eMIPSAse_micromips; - SectionLoadList §ion_load_list = GetSectionLoadList(); - - if (section_load_list.IsEmpty()) - // No sections are loaded, so we must assume we are not running yet and - // need to operate only on file address. - m_images.ResolveFileAddress(addr, resolved_addr); - else - section_load_list.ResolveLoadAddress(addr, resolved_addr); - - // Get the function boundaries to make sure we don't scan back before the - // beginning of the current function. - ModuleSP temp_addr_module_sp(resolved_addr.GetModule()); - if (temp_addr_module_sp) { - SymbolContext sc; - uint32_t resolve_scope = eSymbolContextFunction | eSymbolContextSymbol; - temp_addr_module_sp->ResolveSymbolContextForAddress(resolved_addr, - resolve_scope, sc); - Address sym_addr; - if (sc.function) - sym_addr = sc.function->GetAddressRange().GetBaseAddress(); - else if (sc.symbol) - sym_addr = sc.symbol->GetAddress(); - - function_start = sym_addr.GetLoadAddress(this); - if (function_start == LLDB_INVALID_ADDRESS) - function_start = sym_addr.GetFileAddress(); - - if (function_start) - current_offset = addr - function_start; - } - - // If breakpoint address is start of function then we dont have to do - // anything. - if (current_offset == 0) - return breakable_addr; - else - loop_count = current_offset / 2; - - if (loop_count > 3) { - // Scan previous 6 bytes - if (IsMips16 | IsMicromips) - loop_count = 3; - // For mips-only, instructions are always 4 bytes, so scan previous 4 - // bytes only. - else - loop_count = 2; - } - - // Create Disassembler Instance - lldb::DisassemblerSP disasm_sp( - Disassembler::FindPlugin(m_arch.GetSpec(), nullptr, nullptr)); - - ExecutionContext exe_ctx; - CalculateExecutionContext(exe_ctx); - InstructionList instruction_list; - InstructionSP prev_insn; - bool prefer_file_cache = true; // Read from file - uint32_t inst_to_choose = 0; - - for (uint32_t i = 1; i <= loop_count; i++) { - // Adjust the address to read from. - resolved_addr.Slide(-2); - AddressRange range(resolved_addr, i * 2); - uint32_t insn_size = 0; - - disasm_sp->ParseInstructions(&exe_ctx, range, nullptr, prefer_file_cache); - - uint32_t num_insns = disasm_sp->GetInstructionList().GetSize(); - if (num_insns) { - prev_insn = disasm_sp->GetInstructionList().GetInstructionAtIndex(0); - insn_size = prev_insn->GetOpcode().GetByteSize(); - if (i == 1 && insn_size == 2) { - // This looks like a valid 2-byte instruction (but it could be a part - // of upper 4 byte instruction). - instruction_list.Append(prev_insn); - inst_to_choose = 1; - } else if (i == 2) { - // Here we may get one 4-byte instruction or two 2-byte instructions. - if (num_insns == 2) { - // Looks like there are two 2-byte instructions above our - // breakpoint target address. Now the upper 2-byte instruction is - // either a valid 2-byte instruction or could be a part of it's - // upper 4-byte instruction. In both cases we don't care because in - // this case lower 2-byte instruction is definitely a valid - // instruction and whatever i=1 iteration has found out is true. - inst_to_choose = 1; - break; - } else if (insn_size == 4) { - // This instruction claims its a valid 4-byte instruction. But it - // could be a part of it's upper 4-byte instruction. Lets try - // scanning upper 2 bytes to verify this. - instruction_list.Append(prev_insn); - inst_to_choose = 2; - } - } else if (i == 3) { - if (insn_size == 4) - // FIXME: We reached here that means instruction at [target - 4] has - // already claimed to be a 4-byte instruction, and now instruction - // at [target - 6] is also claiming that it's a 4-byte instruction. - // This can not be true. In this case we can not decide the valid - // previous instruction so we let lldb set the breakpoint at the - // address given by user. - inst_to_choose = 0; - else - // This is straight-forward - inst_to_choose = 2; - break; - } - } else { - // Decode failed, bytes do not form a valid instruction. So whatever - // previous iteration has found out is true. - if (i > 1) { - inst_to_choose = i - 1; - break; - } - } - } - - // Check if we are able to find any valid instruction. - if (inst_to_choose) { - if (inst_to_choose > instruction_list.GetSize()) - inst_to_choose--; - prev_insn = instruction_list.GetInstructionAtIndex(inst_to_choose - 1); - - if (prev_insn->HasDelaySlot()) { - uint32_t shift_size = prev_insn->GetOpcode().GetByteSize(); - // Adjust the breakable address - breakable_addr = addr - shift_size; - if (log) - log->Printf("Target::%s Breakpoint at 0x%8.8" PRIx64 - " is adjusted to 0x%8.8" PRIx64 " due to delay slot\n", - __FUNCTION__, addr, breakable_addr); - } - } - break; - } - } - return breakable_addr; + auto arch_plugin = GetArchitecturePlugin(); + return arch_plugin ? + arch_plugin->GetBreakableLoadAddress(addr, *this) : addr; } SourceManager &Target::GetSourceManager() { @@ -2971,18 +2834,7 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { PlatformSP platform_sp(GetPlatform()); - // Finalize the file actions, and if none were given, default to opening up a - // pseudo terminal - const bool default_to_use_pty = platform_sp ? platform_sp->IsHost() : false; - if (log) - log->Printf("Target::%s have platform=%s, platform_sp->IsHost()=%s, " - "default_to_use_pty=%s", - __FUNCTION__, platform_sp ? "true" : "false", - platform_sp ? (platform_sp->IsHost() ? "true" : "false") - : "n/a", - default_to_use_pty ? "true" : "false"); - - launch_info.FinalizeFileActions(this, default_to_use_pty); + FinalizeFileActions(launch_info); if (state == eStateConnected) { if (launch_info.GetFlags().Test(eLaunchFlagLaunchInTTY)) { @@ -3003,22 +2855,15 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { log->Printf("Target::%s asking the platform to debug the process", __FUNCTION__); - // Get a weak pointer to the previous process if we have one - ProcessWP process_wp; - if (m_process_sp) - process_wp = m_process_sp; + // If there was a previous process, delete it before we make the new one. + // One subtle point, we delete the process before we release the reference + // to m_process_sp. That way even if we are the last owner, the process + // will get Finalized before it gets destroyed. + DeleteCurrentProcess(); + m_process_sp = GetPlatform()->DebugProcess(launch_info, debugger, this, error); - // Cleanup the old process since someone might still have a strong - // reference to this process and we would like to allow it to cleanup as - // much as it can without the object being destroyed. We try to lock the - // shared pointer and if that works, then someone else still has a strong - // reference to the process. - - ProcessSP old_process_sp(process_wp.lock()); - if (old_process_sp) - old_process_sp->Finalize(); } else { if (log) log->Printf("Target::%s the platform doesn't know how to debug a " @@ -3030,8 +2875,7 @@ Status Target::Launch(ProcessLaunchInfo &launch_info, Stream *stream) { } else { // Use a Process plugin to construct the process. const char *plugin_name = launch_info.GetProcessPluginName(); - CreateProcess(launch_info.GetListenerForProcess(debugger), plugin_name, - nullptr); + CreateProcess(launch_info.GetListener(), plugin_name, nullptr); } // Since we didn't have a platform launch the process, launch it here. @@ -3206,6 +3050,86 @@ Status Target::Attach(ProcessAttachInfo &attach_info, Stream *stream) { return error; } +void Target::FinalizeFileActions(ProcessLaunchInfo &info) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS)); + + // Finalize the file actions, and if none were given, default to opening up a + // pseudo terminal + PlatformSP platform_sp = GetPlatform(); + const bool default_to_use_pty = + m_platform_sp ? m_platform_sp->IsHost() : false; + LLDB_LOG( + log, + "have platform={0}, platform_sp->IsHost()={1}, default_to_use_pty={2}", + bool(platform_sp), + platform_sp ? (platform_sp->IsHost() ? "true" : "false") : "n/a", + default_to_use_pty); + + // If nothing for stdin or stdout or stderr was specified, then check the + // process for any default settings that were set with "settings set" + if (info.GetFileActionForFD(STDIN_FILENO) == nullptr || + info.GetFileActionForFD(STDOUT_FILENO) == nullptr || + info.GetFileActionForFD(STDERR_FILENO) == nullptr) { + LLDB_LOG(log, "at least one of stdin/stdout/stderr was not set, evaluating " + "default handling"); + + if (info.GetFlags().Test(eLaunchFlagLaunchInTTY)) { + // Do nothing, if we are launching in a remote terminal no file actions + // should be done at all. + return; + } + + if (info.GetFlags().Test(eLaunchFlagDisableSTDIO)) { + LLDB_LOG(log, "eLaunchFlagDisableSTDIO set, adding suppression action " + "for stdin, stdout and stderr"); + info.AppendSuppressFileAction(STDIN_FILENO, true, false); + info.AppendSuppressFileAction(STDOUT_FILENO, false, true); + info.AppendSuppressFileAction(STDERR_FILENO, false, true); + } else { + // Check for any values that might have gotten set with any of: (lldb) + // settings set target.input-path (lldb) settings set target.output-path + // (lldb) settings set target.error-path + FileSpec in_file_spec; + FileSpec out_file_spec; + FileSpec err_file_spec; + // Only override with the target settings if we don't already have an + // action for in, out or error + if (info.GetFileActionForFD(STDIN_FILENO) == nullptr) + in_file_spec = GetStandardInputPath(); + if (info.GetFileActionForFD(STDOUT_FILENO) == nullptr) + out_file_spec = GetStandardOutputPath(); + if (info.GetFileActionForFD(STDERR_FILENO) == nullptr) + err_file_spec = GetStandardErrorPath(); + + LLDB_LOG(log, "target stdin='{0}', target stdout='{1}', stderr='{1}'", + in_file_spec, out_file_spec, err_file_spec); + + if (in_file_spec) { + info.AppendOpenFileAction(STDIN_FILENO, in_file_spec, true, false); + LLDB_LOG(log, "appended stdin open file action for {0}", in_file_spec); + } + + if (out_file_spec) { + info.AppendOpenFileAction(STDOUT_FILENO, out_file_spec, false, true); + LLDB_LOG(log, "appended stdout open file action for {0}", + out_file_spec); + } + + if (err_file_spec) { + info.AppendOpenFileAction(STDERR_FILENO, err_file_spec, false, true); + LLDB_LOG(log, "appended stderr open file action for {0}", + err_file_spec); + } + + if (default_to_use_pty && + (!in_file_spec || !out_file_spec || !err_file_spec)) { + llvm::Error Err = info.SetUpPtyRedirection(); + LLDB_LOG_ERROR(log, std::move(Err), "SetUpPtyRedirection failed: {0}"); + } + } + } +} + //-------------------------------------------------------------- // Target::StopHook //-------------------------------------------------------------- @@ -3275,16 +3199,20 @@ void Target::StopHook::GetDescription(Stream *s, // class TargetProperties //-------------------------------------------------------------- -OptionEnumValueElement lldb_private::g_dynamic_value_types[] = { +// clang-format off +static constexpr OptionEnumValueElement g_dynamic_value_types[] = { {eNoDynamicValues, "no-dynamic-values", "Don't calculate the dynamic type of values"}, {eDynamicCanRunTarget, "run-target", "Calculate the dynamic type of values " "even if you have to run the target."}, {eDynamicDontRunTarget, "no-run-target", - "Calculate the dynamic type of values, but don't run the target."}, - {0, nullptr, nullptr}}; + "Calculate the dynamic type of values, but don't run the target."} }; -static OptionEnumValueElement g_inline_breakpoint_enums[] = { +OptionEnumValues lldb_private::GetDynamicValueTypes() { + return OptionEnumValues(g_dynamic_value_types); +} + +static constexpr OptionEnumValueElement g_inline_breakpoint_enums[] = { {eInlineBreakpointsNever, "never", "Never look for inline breakpoint " "locations (fastest). This setting " "should only be used if you know that " @@ -3295,8 +3223,7 @@ static OptionEnumValueElement g_inline_breakpoint_enums[] = { "files (default)."}, {eInlineBreakpointsAlways, "always", "Always look for inline breakpoint locations when setting file and line " - "breakpoints (slower but most accurate)."}, - {0, nullptr, nullptr}}; + "breakpoints (slower but most accurate)."} }; typedef enum x86DisassemblyFlavor { eX86DisFlavorDefault, @@ -3304,36 +3231,33 @@ typedef enum x86DisassemblyFlavor { eX86DisFlavorATT } x86DisassemblyFlavor; -static OptionEnumValueElement g_x86_dis_flavor_value_types[] = { +static constexpr OptionEnumValueElement g_x86_dis_flavor_value_types[] = { {eX86DisFlavorDefault, "default", "Disassembler default (currently att)."}, {eX86DisFlavorIntel, "intel", "Intel disassembler flavor."}, - {eX86DisFlavorATT, "att", "AT&T disassembler flavor."}, - {0, nullptr, nullptr}}; + {eX86DisFlavorATT, "att", "AT&T disassembler flavor."} }; -static OptionEnumValueElement g_hex_immediate_style_values[] = { +static constexpr OptionEnumValueElement g_hex_immediate_style_values[] = { {Disassembler::eHexStyleC, "c", "C-style (0xffff)."}, - {Disassembler::eHexStyleAsm, "asm", "Asm-style (0ffffh)."}, - {0, nullptr, nullptr}}; + {Disassembler::eHexStyleAsm, "asm", "Asm-style (0ffffh)."} }; -static OptionEnumValueElement g_load_script_from_sym_file_values[] = { +static constexpr OptionEnumValueElement g_load_script_from_sym_file_values[] = { {eLoadScriptFromSymFileTrue, "true", "Load debug scripts inside symbol files"}, {eLoadScriptFromSymFileFalse, "false", "Do not load debug scripts inside symbol files."}, {eLoadScriptFromSymFileWarn, "warn", - "Warn about debug scripts inside symbol files but do not load them."}, - {0, nullptr, nullptr}}; + "Warn about debug scripts inside symbol files but do not load them."} }; -static OptionEnumValueElement g_load_current_working_dir_lldbinit_values[] = { +static constexpr +OptionEnumValueElement g_load_current_working_dir_lldbinit_values[] = { {eLoadCWDlldbinitTrue, "true", "Load .lldbinit files from current directory"}, {eLoadCWDlldbinitFalse, "false", "Do not load .lldbinit files from current directory"}, {eLoadCWDlldbinitWarn, "warn", - "Warn about loading .lldbinit files from current directory"}, - {0, nullptr, nullptr}}; + "Warn about loading .lldbinit files from current directory"} }; -static OptionEnumValueElement g_memory_module_load_level_values[] = { +static constexpr OptionEnumValueElement g_memory_module_load_level_values[] = { {eMemoryModuleLoadLevelMinimal, "minimal", "Load minimal information when loading modules from memory. Currently " "this setting loads sections only."}, @@ -3342,28 +3266,27 @@ static OptionEnumValueElement g_memory_module_load_level_values[] = { "this setting loads sections and function bounds."}, {eMemoryModuleLoadLevelComplete, "complete", "Load complete information when loading modules from memory. Currently " - "this setting loads sections and all symbols."}, - {0, nullptr, nullptr}}; + "this setting loads sections and all symbols."} }; -static PropertyDefinition g_properties[] = { - {"default-arch", OptionValue::eTypeArch, true, 0, nullptr, nullptr, +static constexpr PropertyDefinition g_properties[] = { + {"default-arch", OptionValue::eTypeArch, true, 0, nullptr, {}, "Default architecture to choose, when there's a choice."}, {"move-to-nearest-code", OptionValue::eTypeBoolean, false, true, nullptr, - nullptr, "Move breakpoints to nearest code."}, + {}, "Move breakpoints to nearest code."}, {"language", OptionValue::eTypeLanguage, false, eLanguageTypeUnknown, - nullptr, nullptr, + nullptr, {}, "The language to use when interpreting expressions entered in commands."}, - {"expr-prefix", OptionValue::eTypeFileSpec, false, 0, nullptr, nullptr, + {"expr-prefix", OptionValue::eTypeFileSpec, false, 0, nullptr, {}, "Path to a file containing expressions to be prepended to all " "expressions."}, {"prefer-dynamic-value", OptionValue::eTypeEnum, false, - eDynamicDontRunTarget, nullptr, g_dynamic_value_types, + eDynamicDontRunTarget, nullptr, OptionEnumValues(g_dynamic_value_types), "Should printed values be shown as their dynamic value."}, {"enable-synthetic-value", OptionValue::eTypeBoolean, false, true, nullptr, - nullptr, "Should synthetic values be used by default whenever available."}, - {"skip-prologue", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, + {}, "Should synthetic values be used by default whenever available."}, + {"skip-prologue", OptionValue::eTypeBoolean, false, true, nullptr, {}, "Skip function prologues when setting breakpoints by name."}, - {"source-map", OptionValue::eTypePathMap, false, 0, nullptr, nullptr, + {"source-map", OptionValue::eTypePathMap, false, 0, nullptr, {}, "Source path remappings are used to track the change of location between " "a source file when built, and " "where it exists on the current system. It consists of an array of " @@ -3375,66 +3298,68 @@ static PropertyDefinition g_properties[] = { "Each element of the array is checked in order and the first one that " "results in a match wins."}, {"exec-search-paths", OptionValue::eTypeFileSpecList, false, 0, nullptr, - nullptr, "Executable search paths to use when locating executable files " - "whose paths don't match the local file system."}, + {}, "Executable search paths to use when locating executable files " + "whose paths don't match the local file system."}, {"debug-file-search-paths", OptionValue::eTypeFileSpecList, false, 0, - nullptr, nullptr, - "List of directories to be searched when locating debug symbol files."}, + nullptr, {}, + "List of directories to be searched when locating debug symbol files. " + "See also symbols.enable-external-lookup."}, {"clang-module-search-paths", OptionValue::eTypeFileSpecList, false, 0, - nullptr, nullptr, + nullptr, {}, "List of directories to be searched when locating modules for Clang."}, {"auto-import-clang-modules", OptionValue::eTypeBoolean, false, true, - nullptr, nullptr, + nullptr, {}, "Automatically load Clang modules referred to by the program."}, {"auto-apply-fixits", OptionValue::eTypeBoolean, false, true, nullptr, - nullptr, "Automatically apply fix-it hints to expressions."}, + {}, "Automatically apply fix-it hints to expressions."}, {"notify-about-fixits", OptionValue::eTypeBoolean, false, true, nullptr, - nullptr, "Print the fixed expression text."}, + {}, "Print the fixed expression text."}, {"save-jit-objects", OptionValue::eTypeBoolean, false, false, nullptr, - nullptr, "Save intermediate object files generated by the LLVM JIT"}, + {}, "Save intermediate object files generated by the LLVM JIT"}, {"max-children-count", OptionValue::eTypeSInt64, false, 256, nullptr, - nullptr, "Maximum number of children to expand in any level of depth."}, + {}, "Maximum number of children to expand in any level of depth."}, {"max-string-summary-length", OptionValue::eTypeSInt64, false, 1024, - nullptr, nullptr, + nullptr, {}, "Maximum number of characters to show when using %s in summary strings."}, {"max-memory-read-size", OptionValue::eTypeSInt64, false, 1024, nullptr, - nullptr, "Maximum number of bytes that 'memory read' will fetch before " - "--force must be specified."}, + {}, "Maximum number of bytes that 'memory read' will fetch before " + "--force must be specified."}, {"breakpoints-use-platform-avoid-list", OptionValue::eTypeBoolean, false, - true, nullptr, nullptr, "Consult the platform module avoid list when " - "setting non-module specific breakpoints."}, - {"arg0", OptionValue::eTypeString, false, 0, nullptr, nullptr, + true, nullptr, {}, "Consult the platform module avoid list when " + "setting non-module specific breakpoints."}, + {"arg0", OptionValue::eTypeString, false, 0, nullptr, {}, "The first argument passed to the program in the argument array which can " "be different from the executable itself."}, - {"run-args", OptionValue::eTypeArgs, false, 0, nullptr, nullptr, + {"run-args", OptionValue::eTypeArgs, false, 0, nullptr, {}, "A list containing all the arguments to be passed to the executable when " "it is run. Note that this does NOT include the argv[0] which is in " "target.arg0."}, {"env-vars", OptionValue::eTypeDictionary, false, OptionValue::eTypeString, - nullptr, nullptr, "A list of all the environment variables to be passed " - "to the executable's environment, and their values."}, - {"inherit-env", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, + nullptr, {}, "A list of all the environment variables to be passed " + "to the executable's environment, and their values."}, + {"inherit-env", OptionValue::eTypeBoolean, false, true, nullptr, {}, "Inherit the environment from the process that is running LLDB."}, - {"input-path", OptionValue::eTypeFileSpec, false, 0, nullptr, nullptr, + {"input-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {}, "The file/path to be used by the executable program for reading its " "standard input."}, - {"output-path", OptionValue::eTypeFileSpec, false, 0, nullptr, nullptr, + {"output-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {}, "The file/path to be used by the executable program for writing its " "standard output."}, - {"error-path", OptionValue::eTypeFileSpec, false, 0, nullptr, nullptr, + {"error-path", OptionValue::eTypeFileSpec, false, 0, nullptr, {}, "The file/path to be used by the executable program for writing its " "standard error."}, {"detach-on-error", OptionValue::eTypeBoolean, false, true, nullptr, - nullptr, "debugserver will detach (rather than killing) a process if it " + {}, "debugserver will detach (rather than killing) a process if it " "loses connection with lldb."}, - {"preload-symbols", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, + {"preload-symbols", OptionValue::eTypeBoolean, false, true, nullptr, {}, "Enable loading of symbol tables before they are needed."}, - {"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, nullptr, + {"disable-aslr", OptionValue::eTypeBoolean, false, true, nullptr, {}, "Disable Address Space Layout Randomization (ASLR)"}, - {"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, nullptr, + {"disable-stdio", OptionValue::eTypeBoolean, false, false, nullptr, {}, "Disable stdin/stdout for process (e.g. for a GUI application)"}, {"inline-breakpoint-strategy", OptionValue::eTypeEnum, false, - eInlineBreakpointsAlways, nullptr, g_inline_breakpoint_enums, + eInlineBreakpointsAlways, nullptr, + OptionEnumValues(g_inline_breakpoint_enums), "The strategy to use when settings breakpoints by file and line. " "Breakpoint locations can end up being inlined by the compiler, so that a " "compile unit 'a.c' might contain an inlined function from another source " @@ -3454,25 +3379,29 @@ static PropertyDefinition g_properties[] = { // FIXME: This is the wrong way to do per-architecture settings, but we // don't have a general per architecture settings system in place yet. {"x86-disassembly-flavor", OptionValue::eTypeEnum, false, - eX86DisFlavorDefault, nullptr, g_x86_dis_flavor_value_types, + eX86DisFlavorDefault, nullptr, + OptionEnumValues(g_x86_dis_flavor_value_types), "The default disassembly flavor to use for x86 or x86-64 targets."}, {"use-hex-immediates", OptionValue::eTypeBoolean, false, true, nullptr, - nullptr, "Show immediates in disassembly as hexadecimal."}, + {}, "Show immediates in disassembly as hexadecimal."}, {"hex-immediate-style", OptionValue::eTypeEnum, false, - Disassembler::eHexStyleC, nullptr, g_hex_immediate_style_values, + Disassembler::eHexStyleC, nullptr, + OptionEnumValues(g_hex_immediate_style_values), "Which style to use for printing hexadecimal disassembly values."}, {"use-fast-stepping", OptionValue::eTypeBoolean, false, true, nullptr, - nullptr, "Use a fast stepping algorithm based on running from branch to " - "branch rather than instruction single-stepping."}, + {}, "Use a fast stepping algorithm based on running from branch to " + "branch rather than instruction single-stepping."}, {"load-script-from-symbol-file", OptionValue::eTypeEnum, false, - eLoadScriptFromSymFileWarn, nullptr, g_load_script_from_sym_file_values, + eLoadScriptFromSymFileWarn, nullptr, + OptionEnumValues(g_load_script_from_sym_file_values), "Allow LLDB to load scripting resources embedded in symbol files when " "available."}, {"load-cwd-lldbinit", OptionValue::eTypeEnum, false, eLoadCWDlldbinitWarn, - nullptr, g_load_current_working_dir_lldbinit_values, + nullptr, OptionEnumValues(g_load_current_working_dir_lldbinit_values), "Allow LLDB to .lldbinit files from the current directory automatically."}, {"memory-module-load-level", OptionValue::eTypeEnum, false, - eMemoryModuleLoadLevelComplete, nullptr, g_memory_module_load_level_values, + eMemoryModuleLoadLevelComplete, nullptr, + OptionEnumValues(g_memory_module_load_level_values), "Loading modules from memory can be slow as reading the symbol tables and " "other data can take a long time depending on your connection to the " "debug target. " @@ -3488,20 +3417,23 @@ static PropertyDefinition g_properties[] = { "symbols, but should rarely be used as stack frames in these memory " "regions will be inaccurate and not provide any context (fastest). "}, {"display-expression-in-crashlogs", OptionValue::eTypeBoolean, false, false, - nullptr, nullptr, "Expressions that crash will show up in crash logs if " - "the host system supports executable specific crash log " - "strings and this setting is set to true."}, + nullptr, {}, "Expressions that crash will show up in crash logs if " + "the host system supports executable specific crash log " + "strings and this setting is set to true."}, {"trap-handler-names", OptionValue::eTypeArray, true, - OptionValue::eTypeString, nullptr, nullptr, + OptionValue::eTypeString, nullptr, {}, "A list of trap handler function names, e.g. a common Unix user process " "one is _sigtramp."}, {"display-runtime-support-values", OptionValue::eTypeBoolean, false, false, - nullptr, nullptr, "If true, LLDB will show variables that are meant to " - "support the operation of a language's runtime " - "support."}, - {"non-stop-mode", OptionValue::eTypeBoolean, false, 0, nullptr, nullptr, + nullptr, {}, "If true, LLDB will show variables that are meant to " + "support the operation of a language's runtime support."}, + {"display-recognized-arguments", OptionValue::eTypeBoolean, false, false, + nullptr, {}, "Show recognized arguments in variable listings by default."}, + {"non-stop-mode", OptionValue::eTypeBoolean, false, 0, nullptr, {}, "Disable lock-step debugging, instead control threads independently."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + {"require-hardware-breakpoint", OptionValue::eTypeBoolean, false, 0, + nullptr, {}, "Require all breakpoints to be hardware breakpoints."}}; +// clang-format on enum { ePropertyDefaultArch, @@ -3545,8 +3477,10 @@ enum { ePropertyDisplayExpressionsInCrashlogs, ePropertyTrapHandlerNames, ePropertyDisplayRuntimeSupportValues, + ePropertyDisplayRecognizedArguments, ePropertyNonStopModeEnabled, - ePropertyExperimental + ePropertyRequireHardwareBreakpoints, + ePropertyExperimental, }; class TargetOptionValueProperties : public OptionValueProperties { @@ -3623,16 +3557,15 @@ protected: //---------------------------------------------------------------------- // TargetProperties //---------------------------------------------------------------------- -static PropertyDefinition g_experimental_properties[]{ +static constexpr PropertyDefinition g_experimental_properties[]{ {"inject-local-vars", OptionValue::eTypeBoolean, true, true, nullptr, - nullptr, + {}, "If true, inject local variables explicitly into the expression text. " "This will fix symbol resolution when there are name collisions between " "ivars and local variables. " "But it can make expressions run much more slowly."}, {"use-modern-type-lookup", OptionValue::eTypeBoolean, true, false, nullptr, - nullptr, "If true, use Clang's modern type lookup infrastructure."}, - {nullptr, OptionValue::eTypeInvalid, true, 0, nullptr, nullptr, nullptr}}; + {}, "If true, use Clang's modern type lookup infrastructure."}}; enum { ePropertyInjectLocalVars = 0, ePropertyUseModernTypeLookup }; @@ -4104,6 +4037,16 @@ void TargetProperties::SetDisplayRuntimeSupportValues(bool b) { m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); } +bool TargetProperties::GetDisplayRecognizedArguments() const { + const uint32_t idx = ePropertyDisplayRecognizedArguments; + return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false); +} + +void TargetProperties::SetDisplayRecognizedArguments(bool b) { + const uint32_t idx = ePropertyDisplayRecognizedArguments; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); +} + bool TargetProperties::GetNonStopModeEnabled() const { const uint32_t idx = ePropertyNonStopModeEnabled; return m_collection_sp->GetPropertyAtIndexAsBoolean(nullptr, idx, false); @@ -4145,6 +4088,17 @@ void TargetProperties::SetProcessLaunchInfo( SetDisableSTDIO(launch_info.GetFlags().Test(lldb::eLaunchFlagDisableSTDIO)); } +bool TargetProperties::GetRequireHardwareBreakpoints() const { + const uint32_t idx = ePropertyRequireHardwareBreakpoints; + return m_collection_sp->GetPropertyAtIndexAsBoolean( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + +void TargetProperties::SetRequireHardwareBreakpoints(bool b) { + const uint32_t idx = ePropertyRequireHardwareBreakpoints; + m_collection_sp->SetPropertyAtIndexAsBoolean(nullptr, idx, b); +} + void TargetProperties::Arg0ValueChangedCallback(void *target_property_ptr, OptionValue *) { TargetProperties *this_ = diff --git a/contrib/llvm/tools/lldb/source/Target/TargetList.cpp b/contrib/llvm/tools/lldb/source/Target/TargetList.cpp index b9c852b414e2..5b262509cae7 100644 --- a/contrib/llvm/tools/lldb/source/Target/TargetList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/TargetList.cpp @@ -7,14 +7,10 @@ // //===----------------------------------------------------------------------===// -// Project includes #include "lldb/Target/TargetList.h" -#include "lldb/Core/Broadcaster.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/Event.h" #include "lldb/Core/Module.h" #include "lldb/Core/ModuleSpec.h" -#include "lldb/Core/State.h" #include "lldb/Host/Host.h" #include "lldb/Host/HostInfo.h" #include "lldb/Interpreter/CommandInterpreter.h" @@ -22,10 +18,12 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Target/Platform.h" #include "lldb/Target/Process.h" +#include "lldb/Utility/Broadcaster.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/TildeExpressionResolver.h" #include "lldb/Utility/Timer.h" -// Other libraries and framework includes #include "llvm/ADT/SmallString.h" #include "llvm/Support/FileSystem.h" @@ -58,27 +56,27 @@ TargetList::~TargetList() { Status TargetList::CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, llvm::StringRef triple_str, - bool get_dependent_files, + LoadDependentFiles load_dependent_files, const OptionGroupPlatform *platform_options, TargetSP &target_sp) { return CreateTargetInternal(debugger, user_exe_path, triple_str, - get_dependent_files, platform_options, target_sp, + load_dependent_files, platform_options, target_sp, false); } Status TargetList::CreateTarget(Debugger &debugger, llvm::StringRef user_exe_path, const ArchSpec &specified_arch, - bool get_dependent_files, + LoadDependentFiles load_dependent_files, PlatformSP &platform_sp, TargetSP &target_sp) { return CreateTargetInternal(debugger, user_exe_path, specified_arch, - get_dependent_files, platform_sp, target_sp, + load_dependent_files, platform_sp, target_sp, false); } Status TargetList::CreateTargetInternal( Debugger &debugger, llvm::StringRef user_exe_path, - llvm::StringRef triple_str, bool get_dependent_files, + llvm::StringRef triple_str, LoadDependentFiles load_dependent_files, const OptionGroupPlatform *platform_options, TargetSP &target_sp, bool is_dummy_target) { Status error; @@ -120,8 +118,8 @@ Status TargetList::CreateTargetInternal( if (!user_exe_path.empty()) { ModuleSpecList module_specs; ModuleSpec module_spec; - module_spec.GetFileSpec().SetFile(user_exe_path, true, - FileSpec::Style::native); + module_spec.GetFileSpec().SetFile(user_exe_path, FileSpec::Style::native); + FileSystem::Instance().Resolve(module_spec.GetFileSpec()); // Resolve the executable in case we are given a path to a application // bundle like a .app bundle on MacOSX @@ -236,7 +234,7 @@ Status TargetList::CreateTargetInternal( // All platforms for all modules in the executable match, so we can // select this platform platform_sp = platforms.front(); - } else if (more_than_one_platforms == false) { + } else if (!more_than_one_platforms) { // No platforms claim to support this file error.SetErrorString("No matching platforms found for this file, " "specify one with the --platform option"); @@ -292,7 +290,7 @@ Status TargetList::CreateTargetInternal( platform_arch = arch; error = TargetList::CreateTargetInternal( - debugger, user_exe_path, platform_arch, get_dependent_files, platform_sp, + debugger, user_exe_path, platform_arch, load_dependent_files, platform_sp, target_sp, is_dummy_target); return error; } @@ -315,14 +313,14 @@ Status TargetList::CreateDummyTarget(Debugger &debugger, lldb::TargetSP &target_sp) { PlatformSP host_platform_sp(Platform::GetHostPlatform()); return CreateTargetInternal( - debugger, (const char *)nullptr, specified_arch_name, false, + debugger, (const char *)nullptr, specified_arch_name, eLoadDependentsNo, (const OptionGroupPlatform *)nullptr, target_sp, true); } Status TargetList::CreateTargetInternal(Debugger &debugger, llvm::StringRef user_exe_path, const ArchSpec &specified_arch, - bool get_dependent_files, + LoadDependentFiles load_dependent_files, lldb::PlatformSP &platform_sp, lldb::TargetSP &target_sp, bool is_dummy_target) { @@ -346,8 +344,8 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, if (!arch.IsValid()) arch = specified_arch; - FileSpec file(user_exe_path, false); - if (!file.Exists() && user_exe_path.startswith("~")) { + FileSpec file(user_exe_path); + if (!FileSystem::Instance().Exists(file) && user_exe_path.startswith("~")) { // we want to expand the tilde but we don't want to resolve any symbolic // links so we can't use the FileSpec constructor's resolve flag llvm::SmallString<64> unglobbed_path; @@ -355,24 +353,24 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, Resolver.ResolveFullPath(user_exe_path, unglobbed_path); if (unglobbed_path.empty()) - file = FileSpec(user_exe_path, false); + file = FileSpec(user_exe_path); else - file = FileSpec(unglobbed_path.c_str(), false); + file = FileSpec(unglobbed_path.c_str()); } bool user_exe_path_is_bundle = false; char resolved_bundle_exe_path[PATH_MAX]; resolved_bundle_exe_path[0] = '\0'; if (file) { - if (llvm::sys::fs::is_directory(file.GetPath())) + if (FileSystem::Instance().IsDirectory(file)) user_exe_path_is_bundle = true; if (file.IsRelative() && !user_exe_path.empty()) { llvm::SmallString<64> cwd; if (! llvm::sys::fs::current_path(cwd)) { - FileSpec cwd_file(cwd.c_str(), false); + FileSpec cwd_file(cwd.c_str()); cwd_file.AppendPathComponent(file); - if (cwd_file.Exists()) + if (FileSystem::Instance().Exists(cwd_file)) file = cwd_file; } } @@ -401,7 +399,7 @@ Status TargetList::CreateTargetInternal(Debugger &debugger, return error; } target_sp.reset(new Target(debugger, arch, platform_sp, is_dummy_target)); - target_sp->SetExecutableModule(exe_module_sp, get_dependent_files); + target_sp->SetExecutableModule(exe_module_sp, load_dependent_files); if (user_exe_path_is_bundle) exe_module_sp->GetFileSpec().GetPath(resolved_bundle_exe_path, sizeof(resolved_bundle_exe_path)); diff --git a/contrib/llvm/tools/lldb/source/Target/Thread.cpp b/contrib/llvm/tools/lldb/source/Target/Thread.cpp index 5ac1de7ae01b..569d7a0a0f9e 100644 --- a/contrib/llvm/tools/lldb/source/Target/Thread.cpp +++ b/contrib/llvm/tools/lldb/source/Target/Thread.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Thread.h" #include "Plugins/Process/Utility/UnwindLLDB.h" #include "Plugins/Process/Utility/UnwindMacOSXFrameBackchain.h" @@ -18,7 +14,6 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/FormatEntity.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/ValueObject.h" #include "lldb/Host/Host.h" #include "lldb/Interpreter/OptionValueFileSpecList.h" @@ -28,8 +23,10 @@ #include "lldb/Target/ABI.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ExecutionContext.h" +#include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" +#include "lldb/Target/StackFrameRecognizer.h" #include "lldb/Target/StopInfo.h" #include "lldb/Target/SystemRuntime.h" #include "lldb/Target/Target.h" @@ -49,6 +46,7 @@ #include "lldb/Target/Unwind.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" +#include "lldb/Utility/State.h" #include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" #include "lldb/lldb-enumerations.h" @@ -64,30 +62,31 @@ const ThreadPropertiesSP &Thread::GetGlobalProperties() { return *g_settings_sp_ptr; } -static PropertyDefinition g_properties[] = { +static constexpr PropertyDefinition g_properties[] = { {"step-in-avoid-nodebug", OptionValue::eTypeBoolean, true, true, nullptr, - nullptr, + {}, "If true, step-in will not stop in functions with no debug information."}, {"step-out-avoid-nodebug", OptionValue::eTypeBoolean, true, false, nullptr, - nullptr, "If true, when step-in/step-out/step-over leave the current " - "frame, they will continue to step out till they come to a " - "function with " - "debug information. Passing a frame argument to step-out will " - "override this option."}, - {"step-avoid-regexp", OptionValue::eTypeRegex, true, 0, "^std::", nullptr, + {}, "If true, when step-in/step-out/step-over leave the current frame, " + "they will continue to step out till they come to a function with " + "debug information. Passing a frame argument to step-out will " + "override this option."}, + {"step-avoid-regexp", OptionValue::eTypeRegex, true, 0, "^std::", {}, "A regular expression defining functions step-in won't stop in."}, {"step-avoid-libraries", OptionValue::eTypeFileSpecList, true, 0, nullptr, - nullptr, "A list of libraries that source stepping won't stop in."}, - {"trace-thread", OptionValue::eTypeBoolean, false, false, nullptr, nullptr, + {}, "A list of libraries that source stepping won't stop in."}, + {"trace-thread", OptionValue::eTypeBoolean, false, false, nullptr, {}, "If true, this thread will single-step and log execution."}, - {nullptr, OptionValue::eTypeInvalid, false, 0, nullptr, nullptr, nullptr}}; + {"max-backtrace-depth", OptionValue::eTypeUInt64, false, 300000, nullptr, + {}, "Maximum number of frames to backtrace."}}; enum { ePropertyStepInAvoidsNoDebug, ePropertyStepOutAvoidsNoDebug, ePropertyStepAvoidRegex, ePropertyStepAvoidLibraries, - ePropertyEnableThreadTrace + ePropertyEnableThreadTrace, + ePropertyMaxBacktraceDepth }; class ThreadOptionValueProperties : public OptionValueProperties { @@ -165,6 +164,12 @@ bool ThreadProperties::GetStepOutAvoidsNoDebug() const { nullptr, idx, g_properties[idx].default_uint_value != 0); } +uint64_t ThreadProperties::GetMaxBacktraceDepth() const { + const uint32_t idx = ePropertyMaxBacktraceDepth; + return m_collection_sp->GetPropertyAtIndexAsUInt64( + nullptr, idx, g_properties[idx].default_uint_value != 0); +} + //------------------------------------------------------------------ // Thread Event Data //------------------------------------------------------------------ @@ -259,6 +264,7 @@ Thread::Thread(Process &process, lldb::tid_t tid, bool use_invalid_index_id) static_cast(this), GetID()); CheckInWithManager(); + QueueFundamentalPlan(true); } @@ -392,13 +398,14 @@ lldb::StopInfoSP Thread::GetStopInfo() { m_stop_info_sp ->IsValid() && m_stop_info_stop_id == stop_id; bool have_valid_completed_plan = completed_plan_sp && completed_plan_sp->PlanSucceeded(); + bool plan_failed = completed_plan_sp && !completed_plan_sp->PlanSucceeded(); bool plan_overrides_trace = have_valid_stop_info && have_valid_completed_plan && (m_stop_info_sp->GetStopReason() == eStopReasonTrace); - if (have_valid_stop_info && !plan_overrides_trace) { + if (have_valid_stop_info && !plan_overrides_trace && !plan_failed) { return m_stop_info_sp; - } else if (have_valid_completed_plan) { + } else if (completed_plan_sp) { return StopInfo::CreateStopReasonWithPlan( completed_plan_sp, GetReturnValueObject(), GetExpressionVariable()); } else { @@ -1031,9 +1038,11 @@ void Thread::PushPlan(ThreadPlanSP &thread_plan_sp) { if (thread_plan_sp) { // If the thread plan doesn't already have a tracer, give it its parent's // tracer: - if (!thread_plan_sp->GetThreadPlanTracer()) + if (!thread_plan_sp->GetThreadPlanTracer()) { + assert(!m_plan_stack.empty()); thread_plan_sp->SetThreadPlanTracer( m_plan_stack.back()->GetThreadPlanTracer()); + } m_plan_stack.push_back(thread_plan_sp); thread_plan_sp->DidPush(); @@ -1170,12 +1179,34 @@ ThreadPlan *Thread::GetPreviousPlan(ThreadPlan *current_plan) { return nullptr; } -void Thread::QueueThreadPlan(ThreadPlanSP &thread_plan_sp, - bool abort_other_plans) { +Status Thread::QueueThreadPlan(ThreadPlanSP &thread_plan_sp, + bool abort_other_plans) { + Status status; + StreamString s; + if (!thread_plan_sp->ValidatePlan(&s)) { + DiscardThreadPlansUpToPlan(thread_plan_sp); + thread_plan_sp.reset(); + status.SetErrorString(s.GetString()); + return status; + } + if (abort_other_plans) DiscardThreadPlans(true); PushPlan(thread_plan_sp); + + // This seems a little funny, but I don't want to have to split up the + // constructor and the DidPush in the scripted plan, that seems annoying. + // That means the constructor has to be in DidPush. So I have to validate the + // plan AFTER pushing it, and then take it off again... + if (!thread_plan_sp->ValidatePlan(&s)) { + DiscardThreadPlansUpToPlan(thread_plan_sp); + thread_plan_sp.reset(); + status.SetErrorString(s.GetString()); + return status; + } + + return status; } void Thread::EnableTracer(bool value, bool single_stepping) { @@ -1340,23 +1371,24 @@ ThreadPlanSP Thread::QueueFundamentalPlan(bool abort_other_plans) { } ThreadPlanSP Thread::QueueThreadPlanForStepSingleInstruction( - bool step_over, bool abort_other_plans, bool stop_other_threads) { + bool step_over, bool abort_other_plans, bool stop_other_threads, + Status &status) { ThreadPlanSP thread_plan_sp(new ThreadPlanStepInstruction( *this, step_over, stop_other_threads, eVoteNoOpinion, eVoteNoOpinion)); - QueueThreadPlan(thread_plan_sp, abort_other_plans); + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; } ThreadPlanSP Thread::QueueThreadPlanForStepOverRange( bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, lldb::RunMode stop_other_threads, - LazyBool step_out_avoids_code_withoug_debug_info) { + Status &status, LazyBool step_out_avoids_code_withoug_debug_info) { ThreadPlanSP thread_plan_sp; thread_plan_sp.reset(new ThreadPlanStepOverRange( *this, range, addr_context, stop_other_threads, step_out_avoids_code_withoug_debug_info)); - QueueThreadPlan(thread_plan_sp, abort_other_plans); + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; } @@ -1365,17 +1397,17 @@ ThreadPlanSP Thread::QueueThreadPlanForStepOverRange( ThreadPlanSP Thread::QueueThreadPlanForStepOverRange( bool abort_other_plans, const LineEntry &line_entry, const SymbolContext &addr_context, lldb::RunMode stop_other_threads, - LazyBool step_out_avoids_code_withoug_debug_info) { + Status &status, LazyBool step_out_avoids_code_withoug_debug_info) { return QueueThreadPlanForStepOverRange( abort_other_plans, line_entry.GetSameLineContiguousAddressRange(), - addr_context, stop_other_threads, + addr_context, stop_other_threads, status, step_out_avoids_code_withoug_debug_info); } ThreadPlanSP Thread::QueueThreadPlanForStepInRange( bool abort_other_plans, const AddressRange &range, const SymbolContext &addr_context, const char *step_in_target, - lldb::RunMode stop_other_threads, + lldb::RunMode stop_other_threads, Status &status, LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info) { ThreadPlanSP thread_plan_sp( @@ -1388,7 +1420,7 @@ ThreadPlanSP Thread::QueueThreadPlanForStepInRange( if (step_in_target) plan->SetStepInTarget(step_in_target); - QueueThreadPlan(thread_plan_sp, abort_other_plans); + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; } @@ -1396,12 +1428,12 @@ ThreadPlanSP Thread::QueueThreadPlanForStepInRange( ThreadPlanSP Thread::QueueThreadPlanForStepInRange( bool abort_other_plans, const LineEntry &line_entry, const SymbolContext &addr_context, const char *step_in_target, - lldb::RunMode stop_other_threads, + lldb::RunMode stop_other_threads, Status &status, LazyBool step_in_avoids_code_without_debug_info, LazyBool step_out_avoids_code_without_debug_info) { return QueueThreadPlanForStepInRange( abort_other_plans, line_entry.GetSameLineContiguousAddressRange(), - addr_context, step_in_target, stop_other_threads, + addr_context, step_in_target, stop_other_threads, status, step_in_avoids_code_without_debug_info, step_out_avoids_code_without_debug_info); } @@ -1409,23 +1441,19 @@ ThreadPlanSP Thread::QueueThreadPlanForStepInRange( ThreadPlanSP Thread::QueueThreadPlanForStepOut( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, bool stop_other_threads, Vote stop_vote, Vote run_vote, uint32_t frame_idx, - LazyBool step_out_avoids_code_without_debug_info) { + Status &status, LazyBool step_out_avoids_code_without_debug_info) { ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut( *this, addr_context, first_insn, stop_other_threads, stop_vote, run_vote, frame_idx, step_out_avoids_code_without_debug_info)); - if (thread_plan_sp->ValidatePlan(nullptr)) { - QueueThreadPlan(thread_plan_sp, abort_other_plans); - return thread_plan_sp; - } else { - return ThreadPlanSP(); - } + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); + return thread_plan_sp; } ThreadPlanSP Thread::QueueThreadPlanForStepOutNoShouldStop( bool abort_other_plans, SymbolContext *addr_context, bool first_insn, bool stop_other_threads, Vote stop_vote, Vote run_vote, uint32_t frame_idx, - bool continue_to_next_branch) { + Status &status, bool continue_to_next_branch) { const bool calculate_return_value = false; // No need to calculate the return value here. ThreadPlanSP thread_plan_sp(new ThreadPlanStepOut( @@ -1436,59 +1464,51 @@ ThreadPlanSP Thread::QueueThreadPlanForStepOutNoShouldStop( static_cast(thread_plan_sp.get()); new_plan->ClearShouldStopHereCallbacks(); - if (thread_plan_sp->ValidatePlan(nullptr)) { - QueueThreadPlan(thread_plan_sp, abort_other_plans); - return thread_plan_sp; - } else { - return ThreadPlanSP(); - } + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); + return thread_plan_sp; } ThreadPlanSP Thread::QueueThreadPlanForStepThrough(StackID &return_stack_id, bool abort_other_plans, - bool stop_other_threads) { + bool stop_other_threads, + Status &status) { ThreadPlanSP thread_plan_sp( new ThreadPlanStepThrough(*this, return_stack_id, stop_other_threads)); if (!thread_plan_sp || !thread_plan_sp->ValidatePlan(nullptr)) return ThreadPlanSP(); - QueueThreadPlan(thread_plan_sp, abort_other_plans); + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; } ThreadPlanSP Thread::QueueThreadPlanForRunToAddress(bool abort_other_plans, Address &target_addr, - bool stop_other_threads) { + bool stop_other_threads, + Status &status) { ThreadPlanSP thread_plan_sp( new ThreadPlanRunToAddress(*this, target_addr, stop_other_threads)); - QueueThreadPlan(thread_plan_sp, abort_other_plans); + + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; } -ThreadPlanSP Thread::QueueThreadPlanForStepUntil(bool abort_other_plans, - lldb::addr_t *address_list, - size_t num_addresses, - bool stop_other_threads, - uint32_t frame_idx) { +ThreadPlanSP Thread::QueueThreadPlanForStepUntil( + bool abort_other_plans, lldb::addr_t *address_list, size_t num_addresses, + bool stop_other_threads, uint32_t frame_idx, Status &status) { ThreadPlanSP thread_plan_sp(new ThreadPlanStepUntil( *this, address_list, num_addresses, stop_other_threads, frame_idx)); - QueueThreadPlan(thread_plan_sp, abort_other_plans); + + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); return thread_plan_sp; } lldb::ThreadPlanSP Thread::QueueThreadPlanForStepScripted( - bool abort_other_plans, const char *class_name, bool stop_other_threads) { + bool abort_other_plans, const char *class_name, bool stop_other_threads, + Status &status) { ThreadPlanSP thread_plan_sp(new ThreadPlanPython(*this, class_name)); - QueueThreadPlan(thread_plan_sp, abort_other_plans); - // This seems a little funny, but I don't want to have to split up the - // constructor and the DidPush in the scripted plan, that seems annoying. - // That means the constructor has to be in DidPush. So I have to validate the - // plan AFTER pushing it, and then take it off again... - if (!thread_plan_sp->ValidatePlan(nullptr)) { - DiscardThreadPlansUpToPlan(thread_plan_sp); - return ThreadPlanSP(); - } else - return thread_plan_sp; + + status = QueueThreadPlan(thread_plan_sp, abort_other_plans); + return thread_plan_sp; } uint32_t Thread::GetIndexID() const { return m_index_id; } @@ -2107,12 +2127,12 @@ Status Thread::StepIn(bool source_step, if (source_step && frame_sp && frame_sp->HasDebugInformation()) { SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); new_plan_sp = QueueThreadPlanForStepInRange( - abort_other_plans, sc.line_entry, sc, nullptr, run_mode, + abort_other_plans, sc.line_entry, sc, nullptr, run_mode, error, step_in_avoids_code_without_debug_info, step_out_avoids_code_without_debug_info); } else { new_plan_sp = QueueThreadPlanForStepSingleInstruction( - false, abort_other_plans, run_mode); + false, abort_other_plans, run_mode, error); } new_plan_sp->SetIsMasterPlan(true); @@ -2141,11 +2161,11 @@ Status Thread::StepOver(bool source_step, if (source_step && frame_sp && frame_sp->HasDebugInformation()) { SymbolContext sc(frame_sp->GetSymbolContext(eSymbolContextEverything)); new_plan_sp = QueueThreadPlanForStepOverRange( - abort_other_plans, sc.line_entry, sc, run_mode, + abort_other_plans, sc.line_entry, sc, run_mode, error, step_out_avoids_code_without_debug_info); } else { new_plan_sp = QueueThreadPlanForStepSingleInstruction( - true, abort_other_plans, run_mode); + true, abort_other_plans, run_mode, error); } new_plan_sp->SetIsMasterPlan(true); @@ -2170,7 +2190,7 @@ Status Thread::StepOut() { ThreadPlanSP new_plan_sp(QueueThreadPlanForStepOut( abort_other_plans, nullptr, first_instruction, stop_other_threads, - eVoteYes, eVoteNoOpinion, 0)); + eVoteYes, eVoteNoOpinion, 0, error)); new_plan_sp->SetIsMasterPlan(true); new_plan_sp->SetOkayToDiscard(false); @@ -2183,3 +2203,32 @@ Status Thread::StepOut() { } return error; } + +ValueObjectSP Thread::GetCurrentException() { + if (auto frame_sp = GetStackFrameAtIndex(0)) + if (auto recognized_frame = frame_sp->GetRecognizedFrame()) + if (auto e = recognized_frame->GetExceptionObject()) + return e; + + // FIXME: For now, only ObjC exceptions are supported. This should really + // iterate over all language runtimes and ask them all to give us the current + // exception. + if (auto runtime = GetProcess()->GetObjCLanguageRuntime()) + if (auto e = runtime->GetExceptionObjectForThread(shared_from_this())) + return e; + + return ValueObjectSP(); +} + +ThreadSP Thread::GetCurrentExceptionBacktrace() { + ValueObjectSP exception = GetCurrentException(); + if (!exception) return ThreadSP(); + + // FIXME: For now, only ObjC exceptions are supported. This should really + // iterate over all language runtimes and ask them all to give us the current + // exception. + auto runtime = GetProcess()->GetObjCLanguageRuntime(); + if (!runtime) return ThreadSP(); + + return runtime->GetBacktraceThreadFromException(exception); +} diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp index ee57a401f742..20c285963882 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadList.cpp @@ -7,15 +7,10 @@ // //===----------------------------------------------------------------------===// -// C Includes #include -// C++ Includes #include -// Other libraries and framework includes -// Project includes -#include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Thread.h" @@ -23,6 +18,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlan.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlan.cpp index 31ee1e922494..1f2c69c6e8a6 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlan.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlan.cpp @@ -7,18 +7,14 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlan.h" #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; @@ -29,6 +25,7 @@ using namespace lldb_private; ThreadPlan::ThreadPlan(ThreadPlanKind kind, const char *name, Thread &thread, Vote stop_vote, Vote run_vote) : m_thread(thread), m_stop_vote(stop_vote), m_run_vote(run_vote), + m_takes_iteration_count(false), m_could_not_resolve_hw_bp(false), m_kind(kind), m_name(name), m_plan_complete_mutex(), m_cached_plan_explains_stop(eLazyBoolCalculate), m_plan_complete(false), m_plan_private(false), m_okay_to_discard(true), m_is_master_plan(false), diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanBase.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanBase.cpp index 65b114584177..058d1468e241 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanBase.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanBase.cpp @@ -9,10 +9,6 @@ #include "lldb/Target/ThreadPlanBase.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes // #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" @@ -61,10 +57,7 @@ bool ThreadPlanBase::ValidatePlan(Stream *error) { return true; } bool ThreadPlanBase::DoPlanExplainsStop(Event *event_ptr) { // The base plan should defer to its tracer, since by default it always // handles the stop. - if (TracerExplainsStop()) - return false; - else - return true; + return !TracerExplainsStop(); } Vote ThreadPlanBase::ShouldReportStop(Event *event_ptr) { diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunction.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunction.cpp index 18beda42fb64..1131ec939b89 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunction.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunction.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanCallFunction.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp index b90fd9edd766..08604d2c411a 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallFunctionUsingABI.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanCallFunctionUsingABI.h" #include "lldb/Core/Address.h" #include "lldb/Target/Process.h" diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp index e8ea73f3c6a0..2ea083dac45e 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallOnFunctionExit.cpp @@ -27,17 +27,18 @@ void ThreadPlanCallOnFunctionExit::DidPush() { // completes. // Set stop vote to eVoteNo. + Status status; m_step_out_threadplan_sp = GetThread().QueueThreadPlanForStepOut( false, // abort other plans nullptr, // addr_context true, // first instruction true, // stop other threads eVoteNo, // do not say "we're stopping" - eVoteNoOpinion, // don't care about - // run state broadcasting + eVoteNoOpinion, // don't care about run state broadcasting 0, // frame_idx + status, // status eLazyBoolCalculate // avoid code w/o debinfo - ); + ); } // ------------------------------------------------------------------------- diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallUserExpression.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallUserExpression.cpp index 7bf0dd39993e..1fbd346feeea 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallUserExpression.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanCallUserExpression.cpp @@ -9,11 +9,7 @@ #include "lldb/Target/ThreadPlanCallUserExpression.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Core/Address.h" diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp index 7796b8a0ab20..84b93bdc6583 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanPython.cpp @@ -9,12 +9,7 @@ #include "lldb/Target/ThreadPlan.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Core/Debugger.h" -#include "lldb/Core/State.h" #include "lldb/Interpreter/CommandInterpreter.h" #include "lldb/Interpreter/ScriptInterpreter.h" #include "lldb/Target/Process.h" @@ -24,6 +19,7 @@ #include "lldb/Target/ThreadPlan.h" #include "lldb/Target/ThreadPlanPython.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; @@ -35,7 +31,7 @@ using namespace lldb_private; ThreadPlanPython::ThreadPlanPython(Thread &thread, const char *class_name) : ThreadPlan(ThreadPlan::eKindPython, "Python based Thread Plan", thread, eVoteNoOpinion, eVoteNoOpinion), - m_class_name(class_name) { + m_class_name(class_name), m_did_push(false) { SetIsMasterPlan(true); SetOkayToDiscard(true); SetPrivate(false); @@ -47,20 +43,22 @@ ThreadPlanPython::~ThreadPlanPython() { } bool ThreadPlanPython::ValidatePlan(Stream *error) { - // I have to postpone setting up the implementation till after the constructor - // because I need to call - // shared_from_this, which you can't do in the constructor. So I'll do it - // here. - if (m_implementation_sp) + if (!m_did_push) return true; - else + + if (!m_implementation_sp) { + if (error) + error->Printf("Python thread plan does not have an implementation"); return false; + } + + return true; } void ThreadPlanPython::DidPush() { // We set up the script side in DidPush, so that it can push other plans in // the constructor, and doesn't have to care about the details of DidPush. - + m_did_push = true; if (!m_class_name.empty()) { ScriptInterpreter *script_interp = m_thread.GetProcess() ->GetTarget() diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp index 6d1a8b5c27ff..bd11f8b82f78 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanRunToAddress.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanRunToAddress.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -73,6 +69,8 @@ void ThreadPlanRunToAddress::SetInitialBreakpoints() { ->CreateBreakpoint(m_addresses[i], true, false) .get(); if (breakpoint != nullptr) { + if (breakpoint->IsHardware() && !breakpoint->HasResolvedLocations()) + m_could_not_resolve_hw_bp = true; m_break_ids[i] = breakpoint->GetID(); breakpoint->SetThreadID(m_thread.GetID()); breakpoint->SetBreakpointKind("run-to-address"); @@ -85,6 +83,7 @@ ThreadPlanRunToAddress::~ThreadPlanRunToAddress() { for (size_t i = 0; i < num_break_ids; i++) { m_thread.CalculateTarget()->RemoveBreakpointByID(m_break_ids[i]); } + m_could_not_resolve_hw_bp = false; } void ThreadPlanRunToAddress::GetDescription(Stream *s, @@ -133,10 +132,15 @@ void ThreadPlanRunToAddress::GetDescription(Stream *s, } bool ThreadPlanRunToAddress::ValidatePlan(Stream *error) { + if (m_could_not_resolve_hw_bp) { + if (error) + error->Printf("Could not set hardware breakpoint(s)"); + return false; + } + // If we couldn't set the breakpoint for some reason, then this won't work. bool all_bps_good = true; size_t num_break_ids = m_break_ids.size(); - for (size_t i = 0; i < num_break_ids; i++) { if (m_break_ids[i] == LLDB_INVALID_BREAK_ID) { all_bps_good = false; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanShouldStopHere.cpp index c7afe0d9a8a7..8062d8059c14 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanShouldStopHere.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanShouldStopHere.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanShouldStopHere.h" #include "lldb/Symbol/Symbol.h" #include "lldb/Target/RegisterContext.h" @@ -43,11 +39,11 @@ ThreadPlanShouldStopHere::ThreadPlanShouldStopHere( ThreadPlanShouldStopHere::~ThreadPlanShouldStopHere() = default; bool ThreadPlanShouldStopHere::InvokeShouldStopHereCallback( - FrameComparison operation) { + FrameComparison operation, Status &status) { bool should_stop_here = true; if (m_callbacks.should_stop_here_callback) { should_stop_here = m_callbacks.should_stop_here_callback( - m_owner, m_flags, operation, m_baton); + m_owner, m_flags, operation, status, m_baton); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); if (log) { lldb::addr_t current_addr = @@ -63,7 +59,7 @@ bool ThreadPlanShouldStopHere::InvokeShouldStopHereCallback( bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback( ThreadPlan *current_plan, Flags &flags, FrameComparison operation, - void *baton) { + Status &status, void *baton) { bool should_stop_here = true; StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); if (!frame) @@ -100,7 +96,7 @@ bool ThreadPlanShouldStopHere::DefaultShouldStopHereCallback( ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback( ThreadPlan *current_plan, Flags &flags, FrameComparison operation, - void *baton) { + Status &status, void *baton) { const bool stop_others = false; const size_t frame_index = 0; ThreadPlanSP return_plan_sp; @@ -137,8 +133,8 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback( "Queueing StepInRange plan to step through line 0 code."); return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepInRange( - false, range, sc, NULL, eOnlyDuringStepping, eLazyBoolCalculate, - eLazyBoolNo); + false, range, sc, NULL, eOnlyDuringStepping, status, + eLazyBoolCalculate, eLazyBoolNo); } } @@ -146,24 +142,25 @@ ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback( return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepOutNoShouldStop( false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, - frame_index, true); + frame_index, status, true); return return_plan_sp; } ThreadPlanSP ThreadPlanShouldStopHere::QueueStepOutFromHerePlan( - lldb_private::Flags &flags, lldb::FrameComparison operation) { + lldb_private::Flags &flags, lldb::FrameComparison operation, + Status &status) { ThreadPlanSP return_plan_sp; if (m_callbacks.step_from_here_callback) { - return_plan_sp = - m_callbacks.step_from_here_callback(m_owner, flags, operation, m_baton); + return_plan_sp = m_callbacks.step_from_here_callback( + m_owner, flags, operation, status, m_baton); } return return_plan_sp; } lldb::ThreadPlanSP ThreadPlanShouldStopHere::CheckShouldStopHereAndQueueStepOut( - lldb::FrameComparison operation) { - if (!InvokeShouldStopHereCallback(operation)) - return QueueStepOutFromHerePlan(m_flags, operation); + lldb::FrameComparison operation, Status &status) { + if (!InvokeShouldStopHereCallback(operation, status)) + return QueueStepOutFromHerePlan(m_flags, operation, status); else return ThreadPlanSP(); } diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp index 6405c135a33e..8f9889a9d68c 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInRange.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanStepInRange.h" #include "lldb/Core/Architecture.h" #include "lldb/Core/Module.h" @@ -112,8 +108,16 @@ void ThreadPlanStepInRange::SetupAvoidNoDebug( void ThreadPlanStepInRange::GetDescription(Stream *s, lldb::DescriptionLevel level) { + + auto PrintFailureIfAny = [&]() { + if (m_status.Success()) + return; + s->Printf(" failed (%s)", m_status.AsCString()); + }; + if (level == lldb::eDescriptionLevelBrief) { s->Printf("step in"); + PrintFailureIfAny(); return; } @@ -134,6 +138,8 @@ void ThreadPlanStepInRange::GetDescription(Stream *s, DumpRanges(s); } + PrintFailureIfAny(); + s->PutChar('.'); } @@ -166,7 +172,8 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { // ShouldStopHere plan, and otherwise we're done. // FIXME - This can be both a step in and a step out. Probably should // record which in the m_virtual_step. - m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(eFrameCompareYounger); + m_sub_plan_sp = + CheckShouldStopHereAndQueueStepOut(eFrameCompareYounger, m_status); } else { // Stepping through should be done running other threads in general, since // we're setting a breakpoint and continuing. So only stop others if we @@ -185,11 +192,12 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { // I'm going to make the assumption that you wouldn't RETURN to a // trampoline. So if we are in a trampoline we think the frame is older // because the trampoline confused the backtracer. - m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false, - stop_others); + m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough( + m_stack_id, false, stop_others, m_status); if (!m_sub_plan_sp) { // Otherwise check the ShouldStopHere for step out: - m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order); + m_sub_plan_sp = + CheckShouldStopHereAndQueueStepOut(frame_order, m_status); if (log) { if (m_sub_plan_sp) log->Printf("ShouldStopHere found plan to step out of this frame."); @@ -227,8 +235,8 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { // We may have set the plan up above in the FrameIsOlder section: if (!m_sub_plan_sp) - m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false, - stop_others); + m_sub_plan_sp = m_thread.QueueThreadPlanForStepThrough( + m_stack_id, false, stop_others, m_status); if (log) { if (m_sub_plan_sp) @@ -240,7 +248,7 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { // If not, give the "should_stop" callback a chance to push a plan to get // us out of here. But only do that if we actually have stepped in. if (!m_sub_plan_sp && frame_order == eFrameCompareYounger) - m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order); + m_sub_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order, m_status); // If we've stepped in and we are going to stop here, check to see if we // were asked to run past the prologue, and if so do that. @@ -288,7 +296,7 @@ bool ThreadPlanStepInRange::ShouldStop(Event *event_ptr) { log->Printf("Pushing past prologue "); m_sub_plan_sp = m_thread.QueueThreadPlanForRunToAddress( - false, func_start_address, true); + false, func_start_address, true, m_status); } } } @@ -384,7 +392,7 @@ bool ThreadPlanStepInRange::FrameMatchesAvoidCriteria() { bool ThreadPlanStepInRange::DefaultShouldStopHereCallback( ThreadPlan *current_plan, Flags &flags, FrameComparison operation, - void *baton) { + Status &status, void *baton) { bool should_stop_here = true; StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); @@ -392,7 +400,7 @@ bool ThreadPlanStepInRange::DefaultShouldStopHereCallback( // First see if the ThreadPlanShouldStopHere default implementation thinks we // should get out of here: should_stop_here = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback( - current_plan, flags, operation, baton); + current_plan, flags, operation, status, baton); if (!should_stop_here) return should_stop_here; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInstruction.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInstruction.cpp index dd8f129a935b..7707454c9798 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInstruction.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepInstruction.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanStepInstruction.h" #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" @@ -57,11 +53,19 @@ void ThreadPlanStepInstruction::SetUpState() { void ThreadPlanStepInstruction::GetDescription(Stream *s, lldb::DescriptionLevel level) { + auto PrintFailureIfAny = [&]() { + if (m_status.Success()) + return; + s->Printf(" failed (%s)", m_status.AsCString()); + }; + if (level == lldb::eDescriptionLevelBrief) { if (m_step_over) s->Printf("instruction step over"); else s->Printf("instruction step into"); + + PrintFailureIfAny(); } else { s->Printf("Stepping one instruction past "); s->Address(m_instruction_addr, sizeof(addr_t)); @@ -72,6 +76,8 @@ void ThreadPlanStepInstruction::GetDescription(Stream *s, s->Printf(" stepping over calls"); else s->Printf(" stepping into calls"); + + PrintFailureIfAny(); } } @@ -192,7 +198,8 @@ bool ThreadPlanStepInstruction::ShouldStop(Event *event_ptr) { // for now it is safer to run others. const bool stop_others = false; m_thread.QueueThreadPlanForStepOutNoShouldStop( - false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0); + false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0, + m_status); return false; } else { if (log) { diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOut.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOut.cpp index f2db6e4b6f42..378de53fafd7 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOut.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOut.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanStepOut.h" #include "lldb/Breakpoint/Breakpoint.h" #include "lldb/Core/Value.h" @@ -48,18 +44,36 @@ ThreadPlanStepOut::ThreadPlanStepOut( m_return_addr(LLDB_INVALID_ADDRESS), m_stop_others(stop_others), m_immediate_step_from_function(nullptr), m_calculate_return_value(gather_return_value) { + Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); SetFlagsToDefault(); SetupAvoidNoDebug(step_out_avoids_code_without_debug_info); m_step_from_insn = m_thread.GetRegisterContext()->GetPC(0); - StackFrameSP return_frame_sp(m_thread.GetStackFrameAtIndex(frame_idx + 1)); + uint32_t return_frame_index = frame_idx + 1; + StackFrameSP return_frame_sp( + m_thread.GetStackFrameAtIndex(return_frame_index)); StackFrameSP immediate_return_from_sp( m_thread.GetStackFrameAtIndex(frame_idx)); if (!return_frame_sp || !immediate_return_from_sp) return; // we can't do anything here. ValidatePlan() will return false. + // While stepping out, behave as-if artificial frames are not present. + while (return_frame_sp->IsArtificial()) { + m_stepped_past_frames.push_back(return_frame_sp); + + ++return_frame_index; + return_frame_sp = m_thread.GetStackFrameAtIndex(return_frame_index); + + // We never expect to see an artificial frame without a regular ancestor. + // If this happens, log the issue and defensively refuse to step out. + if (!return_frame_sp) { + LLDB_LOG(log, "Can't step out of frame with artificial ancestors"); + return; + } + } + m_step_out_to_id = return_frame_sp->GetStackID(); m_immediate_step_from_id = immediate_return_from_sp->GetStackID(); @@ -67,7 +81,7 @@ ThreadPlanStepOut::ThreadPlanStepOut( // have to be a little more careful. It is non-trivial to determine the real // "return code address" for an inlined frame, so we have to work our way to // that frame and then step out. - if (immediate_return_from_sp && immediate_return_from_sp->IsInlined()) { + if (immediate_return_from_sp->IsInlined()) { if (frame_idx > 0) { // First queue a plan that gets us to this inlined frame, and when we get // there we'll queue a second plan that walks us out of this frame. @@ -82,7 +96,7 @@ ThreadPlanStepOut::ThreadPlanStepOut( // just do that now. QueueInlinedStepPlan(false); } - } else if (return_frame_sp) { + } else { // Find the return address and set a breakpoint there: // FIXME - can we do this more securely if we know first_insn? @@ -115,7 +129,10 @@ ThreadPlanStepOut::ThreadPlanStepOut( Breakpoint *return_bp = m_thread.CalculateTarget() ->CreateBreakpoint(m_return_addr, true, false) .get(); + if (return_bp != nullptr) { + if (return_bp->IsHardware() && !return_bp->HasResolvedLocations()) + m_could_not_resolve_hw_bp = true; return_bp->SetThreadID(m_thread.GetID()); m_return_bp_id = return_bp->GetID(); return_bp->SetBreakpointKind("step-out"); @@ -198,19 +215,35 @@ void ThreadPlanStepOut::GetDescription(Stream *s, s->Printf(" using breakpoint site %d", m_return_bp_id); } } + + s->Printf("\n"); + for (StackFrameSP frame_sp : m_stepped_past_frames) { + s->Printf("Stepped out past: "); + frame_sp->DumpUsingSettingsFormat(s); + } } bool ThreadPlanStepOut::ValidatePlan(Stream *error) { if (m_step_out_to_inline_plan_sp) return m_step_out_to_inline_plan_sp->ValidatePlan(error); - else if (m_step_through_inline_plan_sp) + + if (m_step_through_inline_plan_sp) return m_step_through_inline_plan_sp->ValidatePlan(error); - else if (m_return_bp_id == LLDB_INVALID_BREAK_ID) { + + if (m_could_not_resolve_hw_bp) { + if (error) + error->PutCString( + "Could not create hardware breakpoint for thread plan."); + return false; + } + + if (m_return_bp_id == LLDB_INVALID_BREAK_ID) { if (error) error->PutCString("Could not create return address breakpoint."); return false; - } else - return true; + } + + return true; } bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) { @@ -257,7 +290,7 @@ bool ThreadPlanStepOut::DoPlanExplainsStop(Event *event_ptr) { } if (done) { - if (InvokeShouldStopHereCallback(eFrameCompareOlder)) { + if (InvokeShouldStopHereCallback(eFrameCompareOlder, m_status)) { CalculateReturnValue(); SetPlanComplete(); } @@ -319,12 +352,12 @@ bool ThreadPlanStepOut::ShouldStop(Event *event_ptr) { // is consult the ShouldStopHere, and we are done. if (done) { - if (InvokeShouldStopHereCallback(eFrameCompareOlder)) { + if (InvokeShouldStopHereCallback(eFrameCompareOlder, m_status)) { CalculateReturnValue(); SetPlanComplete(); } else { m_step_out_further_plan_sp = - QueueStepOutFromHerePlan(m_flags, eFrameCompareOlder); + QueueStepOutFromHerePlan(m_flags, eFrameCompareOlder, m_status); done = false; } } diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp index 7497dbff1729..8b24bf94973b 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverBreakpoint.cpp @@ -9,10 +9,6 @@ #include "lldb/Target/ThreadPlanStepOverBreakpoint.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/Process.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Utility/Log.h" diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverRange.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverRange.cpp index b88d25b707eb..129f30371f8d 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverRange.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepOverRange.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanStepOverRange.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/CompileUnit.h" @@ -51,10 +47,18 @@ ThreadPlanStepOverRange::~ThreadPlanStepOverRange() = default; void ThreadPlanStepOverRange::GetDescription(Stream *s, lldb::DescriptionLevel level) { + auto PrintFailureIfAny = [&]() { + if (m_status.Success()) + return; + s->Printf(" failed (%s)", m_status.AsCString()); + }; + if (level == lldb::eDescriptionLevelBrief) { s->Printf("step over"); + PrintFailureIfAny(); return; } + s->Printf("Stepping over"); bool printed_line_info = false; if (m_addr_context.line_entry.IsValid()) { @@ -68,6 +72,8 @@ void ThreadPlanStepOverRange::GetDescription(Stream *s, DumpRanges(s); } + PrintFailureIfAny(); + s->PutChar('.'); } @@ -117,10 +123,7 @@ bool ThreadPlanStepOverRange::IsEquivalentContext( } } // Fall back to symbol if we have no decision from comp_unit/function/block. - if (m_addr_context.symbol && m_addr_context.symbol == context.symbol) { - return true; - } - return false; + return m_addr_context.symbol && m_addr_context.symbol == context.symbol; } bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { @@ -151,8 +154,8 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { // because the trampoline confused the backtracer. As below, we step // through first, and then try to figure out how to get back out again. - new_plan_sp = - m_thread.QueueThreadPlanForStepThrough(m_stack_id, false, stop_others); + new_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false, + stop_others, m_status); if (new_plan_sp && log) log->Printf( @@ -173,11 +176,11 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { if (IsEquivalentContext(older_context)) { new_plan_sp = m_thread.QueueThreadPlanForStepOutNoShouldStop( false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion, 0, - true); + m_status, true); break; } else { - new_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false, - stop_others); + new_plan_sp = m_thread.QueueThreadPlanForStepThrough( + m_stack_id, false, stop_others, m_status); // If we found a way through, then we should stop recursing. if (new_plan_sp) break; @@ -196,8 +199,8 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { // we are in a stub then it's likely going to be hard to get out from // here. It is probably easiest to step into the stub, and then it will // be straight-forward to step out. - new_plan_sp = m_thread.QueueThreadPlanForStepThrough(m_stack_id, false, - stop_others); + new_plan_sp = m_thread.QueueThreadPlanForStepThrough( + m_stack_id, false, stop_others, m_status); } else { // The current clang (at least through 424) doesn't always get the // address range for the DW_TAG_inlined_subroutines right, so that when @@ -287,8 +290,8 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { cur_pc); new_plan_sp = m_thread.QueueThreadPlanForStepOverRange( - abort_other_plans, step_range, sc, - stop_other_threads); + abort_other_plans, step_range, sc, stop_other_threads, + m_status); break; } look_ahead_step++; @@ -309,7 +312,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { // If we haven't figured out something to do yet, then ask the ShouldStopHere // callback: if (!new_plan_sp) { - new_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order); + new_plan_sp = CheckShouldStopHereAndQueueStepOut(frame_order, m_status); } if (!new_plan_sp) @@ -323,7 +326,7 @@ bool ThreadPlanStepOverRange::ShouldStop(Event *event_ptr) { if (!new_plan_sp) { // For efficiencies sake, we know we're done here so we don't have to do // this calculation again in MischiefManaged. - SetPlanComplete(); + SetPlanComplete(m_status.Success()); return true; } else return false; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepRange.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepRange.cpp index 5a71119015eb..7ba68ee84981 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepRange.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepRange.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanStepRange.h" #include "lldb/Breakpoint/BreakpointLocation.h" #include "lldb/Breakpoint/BreakpointSite.h" @@ -61,7 +57,15 @@ void ThreadPlanStepRange::DidPush() { SetNextBranchBreakpoint(); } -bool ThreadPlanStepRange::ValidatePlan(Stream *error) { return true; } +bool ThreadPlanStepRange::ValidatePlan(Stream *error) { + if (m_could_not_resolve_hw_bp) { + if (error) + error->PutCString( + "Could not create hardware breakpoint for thread plan."); + return false; + } + return true; +} Vote ThreadPlanStepRange::ShouldReportStop(Event *event_ptr) { Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); @@ -285,6 +289,7 @@ void ThreadPlanStepRange::ClearNextBranchBreakpoint() { m_next_branch_bp_sp->GetID()); GetTarget().RemoveBreakpointByID(m_next_branch_bp_sp->GetID()); m_next_branch_bp_sp.reset(); + m_could_not_resolve_hw_bp = false; } } @@ -335,6 +340,11 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { m_next_branch_bp_sp = GetTarget().CreateBreakpoint(run_to_address, is_internal, false); if (m_next_branch_bp_sp) { + + if (m_next_branch_bp_sp->IsHardware() && + !m_next_branch_bp_sp->HasResolvedLocations()) + m_could_not_resolve_hw_bp = true; + if (log) { lldb::break_id_t bp_site_id = LLDB_INVALID_BREAK_ID; BreakpointLocationSP bp_loc = @@ -351,8 +361,10 @@ bool ThreadPlanStepRange::SetNextBranchBreakpoint() { run_to_address.GetLoadAddress( &m_thread.GetProcess()->GetTarget())); } + m_next_branch_bp_sp->SetThreadID(m_thread.GetID()); m_next_branch_bp_sp->SetBreakpointKind("next-branch-location"); + return true; } else return false; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepThrough.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepThrough.cpp index c039a32f5515..d1f3c2219f6d 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepThrough.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepThrough.cpp @@ -7,12 +7,9 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanStepThrough.h" #include "lldb/Breakpoint/Breakpoint.h" +#include "lldb/Target/CPPLanguageRuntime.h" #include "lldb/Target/DynamicLoader.h" #include "lldb/Target/ObjCLanguageRuntime.h" #include "lldb/Target/Process.h" @@ -61,7 +58,10 @@ ThreadPlanStepThrough::ThreadPlanStepThrough(Thread &thread, ->GetTarget() .CreateBreakpoint(m_backstop_addr, true, false) .get(); + if (return_bp != nullptr) { + if (return_bp->IsHardware() && !return_bp->HasResolvedLocations()) + m_could_not_resolve_hw_bp = true; return_bp->SetThreadID(m_thread.GetID()); m_backstop_bkpt_id = return_bp->GetID(); return_bp->SetBreakpointKind("step-through-backstop"); @@ -95,6 +95,15 @@ void ThreadPlanStepThrough::LookForPlanToStepThroughFromCurrentPC() { if (objc_runtime) m_sub_plan_sp = objc_runtime->GetStepThroughTrampolinePlan(m_thread, m_stop_others); + + CPPLanguageRuntime *cpp_runtime = + m_thread.GetProcess()->GetCPPLanguageRuntime(); + + // If the ObjC runtime did not provide us with a step though plan then if we + // have it check the C++ runtime for a step though plan. + if (!m_sub_plan_sp.get() && cpp_runtime) + m_sub_plan_sp = + cpp_runtime->GetStepThroughTrampolinePlan(m_thread, m_stop_others); } Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); @@ -129,7 +138,26 @@ void ThreadPlanStepThrough::GetDescription(Stream *s, } bool ThreadPlanStepThrough::ValidatePlan(Stream *error) { - return m_sub_plan_sp.get() != nullptr; + if (m_could_not_resolve_hw_bp) { + if (error) + error->PutCString( + "Could not create hardware breakpoint for thread plan."); + return false; + } + + if (m_backstop_bkpt_id == LLDB_INVALID_BREAK_ID) { + if (error) + error->PutCString("Could not create backstop breakpoint."); + return false; + } + + if (!m_sub_plan_sp.get()) { + if (error) + error->PutCString("Does not have a subplan."); + return false; + } + + return true; } bool ThreadPlanStepThrough::DoPlanExplainsStop(Event *event_ptr) { @@ -205,6 +233,7 @@ void ThreadPlanStepThrough::ClearBackstopBreakpoint() { if (m_backstop_bkpt_id != LLDB_INVALID_BREAK_ID) { m_thread.GetProcess()->GetTarget().RemoveBreakpointByID(m_backstop_bkpt_id); m_backstop_bkpt_id = LLDB_INVALID_BREAK_ID; + m_could_not_resolve_hw_bp = false; } } diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepUntil.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepUntil.cpp index 9984ee925c86..1335c62ba94c 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepUntil.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanStepUntil.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadPlanStepUntil.h" #include "lldb/Breakpoint/Breakpoint.h" @@ -57,7 +53,10 @@ ThreadPlanStepUntil::ThreadPlanStepUntil(Thread &thread, m_return_addr = return_frame_sp->GetStackID().GetPC(); Breakpoint *return_bp = target_sp->CreateBreakpoint(m_return_addr, true, false).get(); + if (return_bp != nullptr) { + if (return_bp->IsHardware() && !return_bp->HasResolvedLocations()) + m_could_not_resolve_hw_bp = true; return_bp->SetThreadID(thread_id); m_return_bp_id = return_bp->GetID(); return_bp->SetBreakpointKind("until-return-backstop"); @@ -97,6 +96,7 @@ void ThreadPlanStepUntil::Clear() { } } m_until_points.clear(); + m_could_not_resolve_hw_bp = false; } void ThreadPlanStepUntil::GetDescription(Stream *s, @@ -127,9 +127,16 @@ void ThreadPlanStepUntil::GetDescription(Stream *s, } bool ThreadPlanStepUntil::ValidatePlan(Stream *error) { - if (m_return_bp_id == LLDB_INVALID_BREAK_ID) + if (m_could_not_resolve_hw_bp) { + if (error) + error->PutCString( + "Could not create hardware breakpoint for thread plan."); return false; - else { + } else if (m_return_bp_id == LLDB_INVALID_BREAK_ID) { + if (error) + error->PutCString("Could not create return breakpoint."); + return false; + } else { until_collection::iterator pos, end = m_until_points.end(); for (pos = m_until_points.begin(); pos != end; pos++) { if (!LLDB_BREAK_ID_IS_VALID((*pos).second)) diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadPlanTracer.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadPlanTracer.cpp index acbbd4d8bcc2..04e29fd26080 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadPlanTracer.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadPlanTracer.cpp @@ -7,15 +7,12 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes #include #include "lldb/Core/Debugger.h" #include "lldb/Core/Disassembler.h" #include "lldb/Core/DumpRegisterValue.h" #include "lldb/Core/Module.h" -#include "lldb/Core/State.h" #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Symbol/TypeList.h" @@ -30,6 +27,7 @@ #include "lldb/Utility/DataBufferHeap.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Log.h" +#include "lldb/Utility/State.h" using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Target/ThreadSpec.cpp b/contrib/llvm/tools/lldb/source/Target/ThreadSpec.cpp index 444a5a5b262a..bae3d0b2238f 100644 --- a/contrib/llvm/tools/lldb/source/Target/ThreadSpec.cpp +++ b/contrib/llvm/tools/lldb/source/Target/ThreadSpec.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/ThreadSpec.h" #include "lldb/Target/Thread.h" #include "lldb/Utility/StructuredData.h" diff --git a/contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp b/contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp index 9cfb1b74adee..1448535b8be4 100644 --- a/contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp +++ b/contrib/llvm/tools/lldb/source/Target/UnixSignals.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/UnixSignals.h" #include "Plugins/Process/Utility/FreeBSDSignals.h" #include "Plugins/Process/Utility/LinuxSignals.h" @@ -88,7 +84,7 @@ void UnixSignals::Reset() { AddSignal(10, "SIGBUS", false, true, true, "bus error"); AddSignal(11, "SIGSEGV", false, true, true, "segmentation violation"); AddSignal(12, "SIGSYS", false, true, true, "bad argument to system call"); - AddSignal(13, "SIGPIPE", false, true, true, + AddSignal(13, "SIGPIPE", false, false, false, "write on a pipe with no one to read it"); AddSignal(14, "SIGALRM", false, false, false, "alarm clock"); AddSignal(15, "SIGTERM", false, true, true, diff --git a/contrib/llvm/tools/lldb/source/Target/UnwindAssembly.cpp b/contrib/llvm/tools/lldb/source/Target/UnwindAssembly.cpp index 3b2b7bf17025..06b6aef28da7 100644 --- a/contrib/llvm/tools/lldb/source/Target/UnwindAssembly.cpp +++ b/contrib/llvm/tools/lldb/source/Target/UnwindAssembly.cpp @@ -7,10 +7,6 @@ // //===----------------------------------------------------------------------===// -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes #include "lldb/Target/UnwindAssembly.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Core/PluginManager.h" diff --git a/contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp b/contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp index 1c50c313e0d1..752fb182d79a 100644 --- a/contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/ArchSpec.cpp @@ -11,15 +11,15 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/NameMatches.h" -#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/Stream.h" #include "lldb/Utility/StringList.h" -#include "lldb/lldb-defines.h" // for LLDB_INVALID_C... +#include "lldb/lldb-defines.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/Twine.h" // for Twine +#include "llvm/ADT/Twine.h" #include "llvm/BinaryFormat/COFF.h" #include "llvm/BinaryFormat/ELF.h" -#include "llvm/BinaryFormat/MachO.h" // for CPUType::CPU_T... -#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH +#include "llvm/BinaryFormat/MachO.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/Host.h" using namespace lldb; @@ -610,10 +610,8 @@ const char *ArchSpec::GetArchitectureName() const { bool ArchSpec::IsMIPS() const { const llvm::Triple::ArchType machine = GetMachine(); - if (machine == llvm::Triple::mips || machine == llvm::Triple::mipsel || - machine == llvm::Triple::mips64 || machine == llvm::Triple::mips64el) - return true; - return false; + return machine == llvm::Triple::mips || machine == llvm::Triple::mipsel || + machine == llvm::Triple::mips64 || machine == llvm::Triple::mips64el; } std::string ArchSpec::GetTargetABI() const { @@ -815,6 +813,7 @@ bool ArchSpec::CharIsSignedByDefault() const { case llvm::Triple::ppc64le: case llvm::Triple::systemz: case llvm::Triple::xcore: + case llvm::Triple::arc: return false; } } @@ -946,13 +945,13 @@ bool ArchSpec::SetArchitecture(ArchitectureType arch_type, uint32_t cpu, m_triple.setVendor(llvm::Triple::Apple); // Don't set the OS. It could be simulator, macosx, ios, watchos, - // tvos. We could get close with the cpu type - but we can't get it - // right all of the time. Better to leave this unset so other - // sections of code will set it when they have more information. - // NB: don't call m_triple.setOS (llvm::Triple::UnknownOS). That sets - // the OSName to - // "unknown" and the ArchSpec::TripleVendorWasSpecified() method says - // that any OSName setting means it was specified. + // tvos, bridgeos. We could get close with the cpu type - but we + // can't get it right all of the time. Better to leave this unset + // so other sections of code will set it when they have more + // information. NB: don't call m_triple.setOS (llvm::Triple::UnknownOS). + // That sets the OSName to "unknown" and the + // ArchSpec::TripleVendorWasSpecified() method says that any OSName + // setting means it was specified. } else if (arch_type == eArchTypeELF) { switch (os) { case llvm::ELF::ELFOSABI_AIX: @@ -1018,7 +1017,7 @@ bool ArchSpec::IsCompatibleMatch(const ArchSpec &rhs) const { return IsEqualTo(rhs, false); } -static bool isCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, +static bool IsCompatibleEnvironment(llvm::Triple::EnvironmentType lhs, llvm::Triple::EnvironmentType rhs) { if (lhs == rhs) return true; @@ -1095,9 +1094,7 @@ bool ArchSpec::IsEqualTo(const ArchSpec &rhs, bool exact_match) const { const llvm::Triple::EnvironmentType rhs_triple_env = rhs_triple.getEnvironment(); - if (!isCompatibleEnvironment(lhs_triple_env, rhs_triple_env)) - return false; - return true; + return IsCompatibleEnvironment(lhs_triple_env, rhs_triple_env); } return false; } @@ -1477,7 +1474,10 @@ bool ArchSpec::IsAlwaysThumbInstructions() const { if (GetCore() == ArchSpec::Core::eCore_arm_armv7m || GetCore() == ArchSpec::Core::eCore_arm_armv7em || - GetCore() == ArchSpec::Core::eCore_arm_armv6m) { + GetCore() == ArchSpec::Core::eCore_arm_armv6m || + GetCore() == ArchSpec::Core::eCore_thumbv7m || + GetCore() == ArchSpec::Core::eCore_thumbv7em || + GetCore() == ArchSpec::Core::eCore_thumbv6m) { return true; } } diff --git a/contrib/llvm/tools/lldb/source/Core/Broadcaster.cpp b/contrib/llvm/tools/lldb/source/Utility/Broadcaster.cpp similarity index 97% rename from contrib/llvm/tools/lldb/source/Core/Broadcaster.cpp rename to contrib/llvm/tools/lldb/source/Utility/Broadcaster.cpp index 198434b46c29..5b9b99801b22 100644 --- a/contrib/llvm/tools/lldb/source/Core/Broadcaster.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/Broadcaster.cpp @@ -7,21 +7,21 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/Broadcaster.h" +#include "lldb/Utility/Broadcaster.h" -#include "lldb/Core/Event.h" -#include "lldb/Core/Listener.h" +#include "lldb/Utility/Event.h" +#include "lldb/Utility/Listener.h" #include "lldb/Utility/Log.h" -#include "lldb/Utility/Logging.h" // for GetLogIfAnyCategoriesSet, Get... -#include "lldb/Utility/Stream.h" // for Stream +#include "lldb/Utility/Logging.h" +#include "lldb/Utility/Stream.h" #include "lldb/Utility/StreamString.h" -#include // for find_if -#include // for make_shared -#include // for move +#include +#include +#include -#include // for assert -#include // for size_t +#include +#include using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp b/contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp index c88747e2abe3..096661b7e99f 100644 --- a/contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/CompletionRequest.cpp @@ -16,11 +16,10 @@ CompletionRequest::CompletionRequest(llvm::StringRef command_line, unsigned raw_cursor_pos, int match_start_point, int max_return_elements, - StringList &matches) + CompletionResult &result) : m_command(command_line), m_raw_cursor_pos(raw_cursor_pos), m_match_start_point(match_start_point), - m_max_return_elements(max_return_elements), m_matches(&matches) { - matches.Clear(); + m_max_return_elements(max_return_elements), m_result(result) { // We parse the argument up to the cursor, so the last argument in // parsed_line is the one containing the cursor, and the cursor is after the @@ -36,8 +35,6 @@ CompletionRequest::CompletionRequest(llvm::StringRef command_line, m_cursor_char_position = strlen(m_partial_parsed_line.GetArgumentAtIndex(m_cursor_index)); - matches.Clear(); - const char *cursor = command_line.data() + raw_cursor_pos; if (raw_cursor_pos > 0 && cursor[-1] == ' ') { // We are just after a space. If we are in an argument, then we will @@ -58,3 +55,39 @@ CompletionRequest::CompletionRequest(llvm::StringRef command_line, } } } + +std::string CompletionResult::Completion::GetUniqueKey() const { + + // We build a unique key for this pair of completion:description. We + // prefix the key with the length of the completion string. This prevents + // that we could get any collisions from completions pairs such as these: + // "foo:", "bar" would be "foo:bar", but will now be: "4foo:bar" + // "foo", ":bar" would be "foo:bar", but will now be: "3foo:bar" + + std::string result; + result.append(std::to_string(m_completion.size())); + result.append(m_completion); + result.append(m_descripton); + return result; +} + +void CompletionResult::AddResult(llvm::StringRef completion, + llvm::StringRef description) { + Completion r(completion, description); + + // Add the completion if we haven't seen the same value before. + if (m_added_values.insert(r.GetUniqueKey()).second) + m_results.push_back(r); +} + +void CompletionResult::GetMatches(StringList &matches) const { + matches.Clear(); + for (const Completion &completion : m_results) + matches.AppendString(completion.m_completion); +} + +void CompletionResult::GetDescriptions(StringList &descriptions) const { + descriptions.Clear(); + for (const Completion &completion : m_results) + descriptions.AppendString(completion.m_descripton); +} diff --git a/contrib/llvm/tools/lldb/source/Utility/ConstString.cpp b/contrib/llvm/tools/lldb/source/Utility/ConstString.cpp index 5ef4b2faa3b8..9b8bea71e2ad 100644 --- a/contrib/llvm/tools/lldb/source/Utility/ConstString.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/ConstString.cpp @@ -12,20 +12,20 @@ #include "lldb/Utility/Stream.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/iterator.h" // for iterator_facade_base -#include "llvm/Support/Allocator.h" // for BumpPtrAllocator -#include "llvm/Support/DJB.h" // for djbHash -#include "llvm/Support/FormatProviders.h" // for format_provider +#include "llvm/ADT/iterator.h" +#include "llvm/Support/Allocator.h" +#include "llvm/Support/DJB.h" +#include "llvm/Support/FormatProviders.h" #include "llvm/Support/RWMutex.h" #include "llvm/Support/Threading.h" -#include // for min +#include #include -#include // for make_pair, pair +#include -#include // for PRIu64 -#include // for uint8_t, uint32_t, uint64_t -#include // for size_t, strlen +#include +#include +#include using namespace lldb_private; @@ -111,38 +111,34 @@ public: } const char * - GetConstCStringAndSetMangledCounterPart(const char *demangled_cstr, + GetConstCStringAndSetMangledCounterPart(llvm::StringRef demangled, const char *mangled_ccstr) { - if (demangled_cstr != nullptr) { - const char *demangled_ccstr = nullptr; + const char *demangled_ccstr = nullptr; - { - llvm::StringRef string_ref(demangled_cstr); - const uint8_t h = hash(string_ref); - llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); + { + const uint8_t h = hash(demangled); + llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); - // Make string pool entry with the mangled counterpart already set - StringPoolEntryType &entry = - *m_string_pools[h] - .m_string_map.insert(std::make_pair(string_ref, mangled_ccstr)) - .first; + // Make or update string pool entry with the mangled counterpart + StringPool &map = m_string_pools[h].m_string_map; + StringPoolEntryType &entry = *map.try_emplace(demangled).first; - // Extract the const version of the demangled_cstr - demangled_ccstr = entry.getKeyData(); - } + entry.second = mangled_ccstr; - { - // Now assign the demangled const string as the counterpart of the - // mangled const string... - const uint8_t h = hash(llvm::StringRef(mangled_ccstr)); - llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); - GetStringMapEntryFromKeyData(mangled_ccstr).setValue(demangled_ccstr); - } - - // Return the constant demangled C string - return demangled_ccstr; + // Extract the const version of the demangled_cstr + demangled_ccstr = entry.getKeyData(); } - return nullptr; + + { + // Now assign the demangled const string as the counterpart of the + // mangled const string... + const uint8_t h = hash(llvm::StringRef(mangled_ccstr)); + llvm::sys::SmartScopedWriter wlock(m_string_pools[h].m_mutex); + GetStringMapEntryFromKeyData(mangled_ccstr).setValue(demangled_ccstr); + } + + // Return the constant demangled C string + return demangled_ccstr; } const char *GetConstTrimmedCStringWithLength(const char *cstr, @@ -306,7 +302,7 @@ void ConstString::SetString(const llvm::StringRef &s) { m_string = StringPool().GetConstCStringWithLength(s.data(), s.size()); } -void ConstString::SetCStringWithMangledCounterpart(const char *demangled, +void ConstString::SetStringWithMangledCounterpart(llvm::StringRef demangled, const ConstString &mangled) { m_string = StringPool().GetConstCStringAndSetMangledCounterPart( demangled, mangled.m_string); diff --git a/contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp b/contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp index e686ee8d35e5..36cac0079ac0 100644 --- a/contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/DataBufferHeap.cpp @@ -9,10 +9,6 @@ #include "lldb/Utility/DataBufferHeap.h" -// C Includes -// C++ Includes -// Other libraries and framework includes -// Project includes using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp b/contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp index 713c3c2814ea..0ab3fe5afd46 100644 --- a/contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/DataBufferLLVM.cpp @@ -13,8 +13,8 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" -#include // for assert -#include // for move +#include +#include using namespace lldb_private; @@ -27,34 +27,6 @@ DataBufferLLVM::DataBufferLLVM( DataBufferLLVM::~DataBufferLLVM() {} -std::shared_ptr -DataBufferLLVM::CreateSliceFromPath(const llvm::Twine &Path, uint64_t Size, - uint64_t Offset) { - // If the file resides non-locally, pass the volatile flag so that we don't - // mmap it. - bool IsVolatile = !llvm::sys::fs::is_local(Path); - - auto Buffer = - llvm::WritableMemoryBuffer::getFileSlice(Path, Size, Offset, IsVolatile); - if (!Buffer) - return nullptr; - return std::shared_ptr( - new DataBufferLLVM(std::move(*Buffer))); -} - -std::shared_ptr -DataBufferLLVM::CreateFromPath(const llvm::Twine &Path) { - // If the file resides non-locally, pass the volatile flag so that we don't - // mmap it. - bool IsVolatile = !llvm::sys::fs::is_local(Path); - - auto Buffer = llvm::WritableMemoryBuffer::getFile(Path, -1, IsVolatile); - if (!Buffer) - return nullptr; - return std::shared_ptr( - new DataBufferLLVM(std::move(*Buffer))); -} - uint8_t *DataBufferLLVM::GetBytes() { return reinterpret_cast(Buffer->getBufferStart()); } diff --git a/contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp b/contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp index 7edee3c2f279..c26c0fa63ab3 100644 --- a/contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/DataEncoder.cpp @@ -13,7 +13,7 @@ #include "lldb/Utility/Endian.h" #include "llvm/Support/Endian.h" -#include "llvm/Support/ErrorHandling.h" // for llvm_unreachable +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include diff --git a/contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp b/contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp index 947232943aa7..ae5a3f9b7d8f 100644 --- a/contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/DataExtractor.cpp @@ -9,10 +9,10 @@ #include "lldb/Utility/DataExtractor.h" -#include "lldb/lldb-defines.h" // for LLDB_INVALID_ADDRESS -#include "lldb/lldb-enumerations.h" // for ByteOrder::eByteOrderBig -#include "lldb/lldb-forward.h" // for DataBufferSP -#include "lldb/lldb-types.h" // for offset_t +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-types.h" #include "lldb/Utility/DataBuffer.h" #include "lldb/Utility/DataBufferHeap.h" @@ -28,15 +28,15 @@ #include "llvm/Support/MD5.h" #include "llvm/Support/MathExtras.h" -#include // for min -#include // for array +#include +#include #include -#include // for uint8_t, uint32_t, uint64_t +#include #include -#include // for isprint -#include // for PRIx64, PRId64 -#include // for memcpy, memset, memchr +#include +#include +#include using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Core/Event.cpp b/contrib/llvm/tools/lldb/source/Utility/Event.cpp similarity index 97% rename from contrib/llvm/tools/lldb/source/Core/Event.cpp rename to contrib/llvm/tools/lldb/source/Utility/Event.cpp index 3ebad7acdef7..ad9f6e340f8c 100644 --- a/contrib/llvm/tools/lldb/source/Core/Event.cpp +++ b/contrib/llvm/tools/lldb/source/Utility/Event.cpp @@ -7,18 +7,18 @@ // //===----------------------------------------------------------------------===// -#include "lldb/Core/Event.h" +#include "lldb/Utility/Event.h" -#include "lldb/Core/Broadcaster.h" +#include "lldb/Utility/Broadcaster.h" #include "lldb/Utility/DataExtractor.h" #include "lldb/Utility/Endian.h" #include "lldb/Utility/Stream.h" -#include "lldb/Utility/StreamString.h" // for StreamString -#include "lldb/lldb-enumerations.h" // for Format::eFormatBytes +#include "lldb/Utility/StreamString.h" +#include "lldb/lldb-enumerations.h" #include -#include // for isprint +#include using namespace lldb; using namespace lldb_private; diff --git a/contrib/llvm/tools/lldb/source/Utility/FastDemangle.cpp b/contrib/llvm/tools/lldb/source/Utility/FastDemangle.cpp deleted file mode 100644 index d92670a9199b..000000000000 --- a/contrib/llvm/tools/lldb/source/Utility/FastDemangle.cpp +++ /dev/null @@ -1,2393 +0,0 @@ -//===-- FastDemangle.cpp ----------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Utility/FastDemangle.h" - -#include "llvm/Support/Compiler.h" // for LLVM_FALLTHROUGH - -#include - -#include -#include -#include - -//#define DEBUG_FAILURES 1 -//#define DEBUG_SUBSTITUTIONS 1 -//#define DEBUG_TEMPLATE_ARGS 1 -//#define DEBUG_HIGHWATER 1 -//#define DEBUG_REORDERING 1 - -namespace { - -/// Represents the collection of qualifiers on a type - -enum Qualifiers { - QualifierNone = 0, - QualifierConst = 1, - QualifierRestrict = 2, - QualifierVolatile = 4, - QualifierReference = 8, - QualifierRValueReference = 16, - QualifierPointer = 32 -}; - -/// Categorizes the recognized operators - -enum class OperatorKind { - Unary, - Postfix, - Binary, - Ternary, - Other, - ConversionOperator, - Vendor, - NoMatch -}; - -/// Represents one of the recognized two-character operator abbreviations used -/// when parsing operators as names and expressions - -struct Operator { - const char *name; - OperatorKind kind; -}; - -/// Represents a range of characters in the output buffer, typically for use -/// with RewriteRange() - -struct BufferRange { - int offset; - int length; -}; - -/// Transient state required while parsing a name - -struct NameState { - bool parse_function_params; - bool is_last_generic; - bool has_no_return_type; - BufferRange last_name_range; -}; - -/// LLDB's fast C++ demangler -/// -/// This is an incomplete implementation designed to speed up the demangling -/// process that is often a bottleneck when LLDB stops a process for the first -/// time. Where the implementation doesn't know how to demangle a symbol it -/// fails gracefully to allow the caller to fall back to the existing -/// demangler. -/// -/// Over time the full mangling spec should be supported without compromising -/// performance for the most common cases. - -class SymbolDemangler { -public: - //---------------------------------------------------- - // Public API - //---------------------------------------------------- - - /// Create a SymbolDemangler - /// - /// The newly created demangler allocates and owns scratch memory sufficient - /// for demangling typical symbols. Additional memory will be allocated if - /// needed and managed by the demangler instance. - - SymbolDemangler() { - m_buffer = (char *)malloc(8192); - m_buffer_end = m_buffer + 8192; - m_owns_buffer = true; - - m_rewrite_ranges = (BufferRange *)malloc(128 * sizeof(BufferRange)); - m_rewrite_ranges_size = 128; - m_owns_m_rewrite_ranges = true; - } - - /// Create a SymbolDemangler that uses provided scratch memory - /// - /// The provided memory is not owned by the demangler. It will be - /// overwritten during calls to GetDemangledCopy() but can be used for other - /// purposes between calls. The provided memory will not be freed when this - /// instance is destroyed. - /// - /// If demangling a symbol requires additional space it will be allocated - /// and managed by the demangler instance. - /// - /// @param storage_ptr Valid pointer to at least storage_size bytes of space - /// that the SymbolDemangler can use during demangling - /// - /// @param storage_size Number of bytes of space available scratch memory - /// referenced by storage_ptr - - SymbolDemangler(void *storage_ptr, size_t storage_size, - std::function builtins_hook = nullptr) - : m_builtins_hook(builtins_hook) { - // Use up to 1/8th of the provided space for rewrite ranges - m_rewrite_ranges_size = (storage_size >> 3) / sizeof(BufferRange); - m_rewrite_ranges = (BufferRange *)storage_ptr; - m_owns_m_rewrite_ranges = false; - - // Use the rest for the character buffer - m_buffer = - (char *)storage_ptr + m_rewrite_ranges_size * sizeof(BufferRange); - m_buffer_end = (const char *)storage_ptr + storage_size; - m_owns_buffer = false; - } - - /// Destroys the SymbolDemangler and deallocates any scratch memory that it - /// owns - - ~SymbolDemangler() { - if (m_owns_buffer) - free(m_buffer); - if (m_owns_m_rewrite_ranges) - free(m_rewrite_ranges); - } - -#ifdef DEBUG_HIGHWATER - int highwater_store = 0; - int highwater_buffer = 0; -#endif - - /// Parses the provided mangled name and returns a newly allocated - /// demangling - /// - /// @param mangled_name Valid null-terminated C++ mangled name following the - /// Itanium C++ ABI mangling specification as implemented by Clang - /// - /// @result Newly allocated null-terminated demangled name when demangling - /// is successful, and nullptr when demangling fails. The caller is - /// responsible for freeing the allocated memory. - - char *GetDemangledCopy(const char *mangled_name, - long mangled_name_length = 0) { - if (!ParseMangling(mangled_name, mangled_name_length)) - return nullptr; - -#ifdef DEBUG_HIGHWATER - int rewrite_count = m_next_substitute_index + - (m_rewrite_ranges_size - 1 - m_next_template_arg_index); - int buffer_size = (int)(m_write_ptr - m_buffer); - if (rewrite_count > highwater_store) - highwater_store = rewrite_count; - if (buffer_size > highwater_buffer) - highwater_buffer = buffer_size; -#endif - - int length = (int)(m_write_ptr - m_buffer); - char *copy = (char *)malloc(length + 1); - memcpy(copy, m_buffer, length); - copy[length] = '\0'; - return copy; - } - -private: - //---------------------------------------------------- - // Grow methods - // - // Manage the storage used during demangling - //---------------------------------------------------- - - void GrowBuffer(long min_growth = 0) { - // By default, double the size of the buffer - long growth = m_buffer_end - m_buffer; - - // Avoid growing by more than 1MB at a time - if (growth > 1 << 20) - growth = 1 << 20; - - // ... but never grow by less than requested, or 1K, whichever is greater - if (min_growth < 1024) - min_growth = 1024; - if (growth < min_growth) - growth = min_growth; - - // Allocate the new m_buffer and migrate content - long new_size = (m_buffer_end - m_buffer) + growth; - char *new_buffer = (char *)malloc(new_size); - memcpy(new_buffer, m_buffer, m_write_ptr - m_buffer); - if (m_owns_buffer) - free(m_buffer); - m_owns_buffer = true; - - // Update references to the new buffer - m_write_ptr = new_buffer + (m_write_ptr - m_buffer); - m_buffer = new_buffer; - m_buffer_end = m_buffer + new_size; - } - - void GrowRewriteRanges() { - // By default, double the size of the array - int growth = m_rewrite_ranges_size; - - // Apply reasonable minimum and maximum sizes for growth - if (growth > 128) - growth = 128; - if (growth < 16) - growth = 16; - - // Allocate the new array and migrate content - int bytes = (m_rewrite_ranges_size + growth) * sizeof(BufferRange); - BufferRange *new_ranges = (BufferRange *)malloc(bytes); - for (int index = 0; index < m_next_substitute_index; index++) { - new_ranges[index] = m_rewrite_ranges[index]; - } - for (int index = m_rewrite_ranges_size - 1; - index > m_next_template_arg_index; index--) { - new_ranges[index + growth] = m_rewrite_ranges[index]; - } - if (m_owns_m_rewrite_ranges) - free(m_rewrite_ranges); - m_owns_m_rewrite_ranges = true; - - // Update references to the new array - m_rewrite_ranges = new_ranges; - m_rewrite_ranges_size += growth; - m_next_template_arg_index += growth; - } - - //---------------------------------------------------- - // Range and state management - //---------------------------------------------------- - - int GetStartCookie() { return (int)(m_write_ptr - m_buffer); } - - BufferRange EndRange(int start_cookie) { - return {start_cookie, (int)(m_write_ptr - (m_buffer + start_cookie))}; - } - - void ReorderRange(BufferRange source_range, int insertion_point_cookie) { - // Ensure there's room the preserve the source range - if (m_write_ptr + source_range.length > m_buffer_end) { - GrowBuffer(m_write_ptr + source_range.length - m_buffer_end); - } - - // Reorder the content - memcpy(m_write_ptr, m_buffer + source_range.offset, source_range.length); - memmove(m_buffer + insertion_point_cookie + source_range.length, - m_buffer + insertion_point_cookie, - source_range.offset - insertion_point_cookie); - memcpy(m_buffer + insertion_point_cookie, m_write_ptr, source_range.length); - - // Fix up rewritable ranges, covering both substitutions and templates - int index = 0; - while (true) { - if (index == m_next_substitute_index) - index = m_next_template_arg_index + 1; - if (index == m_rewrite_ranges_size) - break; - - // Affected ranges are either shuffled forward when after the insertion - // but before the source, or backward when inside the source - int candidate_offset = m_rewrite_ranges[index].offset; - if (candidate_offset >= insertion_point_cookie) { - if (candidate_offset < source_range.offset) { - m_rewrite_ranges[index].offset += source_range.length; - } else if (candidate_offset >= source_range.offset) { - m_rewrite_ranges[index].offset -= - (source_range.offset - insertion_point_cookie); - } - } - ++index; - } - } - - void EndSubstitution(int start_cookie) { - if (m_next_substitute_index == m_next_template_arg_index) - GrowRewriteRanges(); - - int index = m_next_substitute_index++; - m_rewrite_ranges[index] = EndRange(start_cookie); -#ifdef DEBUG_SUBSTITUTIONS - printf("Saved substitution # %d = %.*s\n", index, - m_rewrite_ranges[index].length, m_buffer + start_cookie); -#endif - } - - void EndTemplateArg(int start_cookie) { - if (m_next_substitute_index == m_next_template_arg_index) - GrowRewriteRanges(); - - int index = m_next_template_arg_index--; - m_rewrite_ranges[index] = EndRange(start_cookie); -#ifdef DEBUG_TEMPLATE_ARGS - printf("Saved template arg # %d = %.*s\n", - m_rewrite_ranges_size - index - 1, m_rewrite_ranges[index].length, - m_buffer + start_cookie); -#endif - } - - void ResetTemplateArgs() { - // TODO: this works, but is it the right thing to do? - // Should we push/pop somehow at the call sites? - m_next_template_arg_index = m_rewrite_ranges_size - 1; - } - - //---------------------------------------------------- - // Write methods - // - // Appends content to the existing output buffer - //---------------------------------------------------- - - void Write(char character) { - if (m_write_ptr == m_buffer_end) - GrowBuffer(); - *m_write_ptr++ = character; - } - - void Write(const char *content) { Write(content, strlen(content)); } - - void Write(const char *content, long content_length) { - char *end_m_write_ptr = m_write_ptr + content_length; - if (end_m_write_ptr > m_buffer_end) { - if (content >= m_buffer && content < m_buffer_end) { - long offset = content - m_buffer; - GrowBuffer(end_m_write_ptr - m_buffer_end); - content = m_buffer + offset; - } else { - GrowBuffer(end_m_write_ptr - m_buffer_end); - } - end_m_write_ptr = m_write_ptr + content_length; - } - memcpy(m_write_ptr, content, content_length); - m_write_ptr = end_m_write_ptr; - } -#define WRITE(x) Write(x, sizeof(x) - 1) - - void WriteTemplateStart() { Write('<'); } - - void WriteTemplateEnd() { - // Put a space between terminal > characters when nesting templates - if (m_write_ptr != m_buffer && *(m_write_ptr - 1) == '>') - WRITE(" >"); - else - Write('>'); - } - - void WriteCommaSpace() { WRITE(", "); } - - void WriteNamespaceSeparator() { WRITE("::"); } - - void WriteStdPrefix() { WRITE("std::"); } - - void WriteQualifiers(int qualifiers, bool space_before_reference = true) { - if (qualifiers & QualifierPointer) - Write('*'); - if (qualifiers & QualifierConst) - WRITE(" const"); - if (qualifiers & QualifierVolatile) - WRITE(" volatile"); - if (qualifiers & QualifierRestrict) - WRITE(" restrict"); - if (qualifiers & QualifierReference) { - if (space_before_reference) - WRITE(" &"); - else - Write('&'); - } - if (qualifiers & QualifierRValueReference) { - if (space_before_reference) - WRITE(" &&"); - else - WRITE("&&"); - } - } - - //---------------------------------------------------- - // Rewrite methods - // - // Write another copy of content already present earlier in the output buffer - //---------------------------------------------------- - - void RewriteRange(BufferRange range) { - Write(m_buffer + range.offset, range.length); - } - - bool RewriteSubstitution(int index) { - if (index < 0 || index >= m_next_substitute_index) { -#ifdef DEBUG_FAILURES - printf("*** Invalid substitution #%d\n", index); -#endif - return false; - } - RewriteRange(m_rewrite_ranges[index]); - return true; - } - - bool RewriteTemplateArg(int template_index) { - int index = m_rewrite_ranges_size - 1 - template_index; - if (template_index < 0 || index <= m_next_template_arg_index) { -#ifdef DEBUG_FAILURES - printf("*** Invalid template arg reference #%d\n", template_index); -#endif - return false; - } - RewriteRange(m_rewrite_ranges[index]); - return true; - } - - //---------------------------------------------------- - // TryParse methods - // - // Provide information with return values instead of writing to the output - // buffer - // - // Values indicating failure guarantee that the pre- call m_read_ptr is - // unchanged - //---------------------------------------------------- - - int TryParseNumber() { - unsigned char digit = *m_read_ptr - '0'; - if (digit > 9) - return -1; - - int count = digit; - while (true) { - digit = *++m_read_ptr - '0'; - if (digit > 9) - break; - - count = count * 10 + digit; - } - return count; - } - - int TryParseBase36Number() { - char digit = *m_read_ptr; - int count; - if (digit >= '0' && digit <= '9') - count = digit -= '0'; - else if (digit >= 'A' && digit <= 'Z') - count = digit -= ('A' - 10); - else - return -1; - - while (true) { - digit = *++m_read_ptr; - if (digit >= '0' && digit <= '9') - digit -= '0'; - else if (digit >= 'A' && digit <= 'Z') - digit -= ('A' - 10); - else - break; - - count = count * 36 + digit; - } - return count; - } - - // ::= v # void - // ::= w # wchar_t - // ::= b # bool - // ::= c # char - // ::= a # signed char - // ::= h # unsigned char - // ::= s # short - // ::= t # unsigned short - // ::= i # int - // ::= j # unsigned int - // ::= l # long - // ::= m # unsigned long - // ::= x # long long, __int64 - // ::= y # unsigned long long, __int64 - // ::= n # __int128 - // ::= o # unsigned __int128 - // ::= f # float - // ::= d # double - // ::= e # long double, __float80 - // ::= g # __float128 - // ::= z # ellipsis - // ::= Dd # IEEE 754r decimal floating point (64 bits) - // ::= De # IEEE 754r decimal floating point (128 bits) - // ::= Df # IEEE 754r decimal floating point (32 bits) - // ::= Dh # IEEE 754r half-precision floating point (16 bits) - // ::= Di # char32_t - // ::= Ds # char16_t - // ::= Da # auto (in dependent new-expressions) - // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) - // ::= u # vendor extended type - - const char *TryParseBuiltinType() { - if (m_builtins_hook) - m_builtins_hook(m_read_ptr); - - switch (*m_read_ptr++) { - case 'v': - return "void"; - case 'w': - return "wchar_t"; - case 'b': - return "bool"; - case 'c': - return "char"; - case 'a': - return "signed char"; - case 'h': - return "unsigned char"; - case 's': - return "short"; - case 't': - return "unsigned short"; - case 'i': - return "int"; - case 'j': - return "unsigned int"; - case 'l': - return "long"; - case 'm': - return "unsigned long"; - case 'x': - return "long long"; - case 'y': - return "unsigned long long"; - case 'n': - return "__int128"; - case 'o': - return "unsigned __int128"; - case 'f': - return "float"; - case 'd': - return "double"; - case 'e': - return "long double"; - case 'g': - return "__float128"; - case 'z': - return "..."; - case 'D': { - switch (*m_read_ptr++) { - case 'd': - return "decimal64"; - case 'e': - return "decimal128"; - case 'f': - return "decimal32"; - case 'h': - return "decimal16"; - case 'i': - return "char32_t"; - case 's': - return "char16_t"; - case 'a': - return "auto"; - case 'c': - return "decltype(auto)"; - case 'n': - return "std::nullptr_t"; - default: - --m_read_ptr; - } - } - } - --m_read_ptr; - return nullptr; - } - - // - // ::= aa # && - // ::= ad # & (unary) - // ::= an # & - // ::= aN # &= - // ::= aS # = - // ::= cl # () - // ::= cm # , - // ::= co # ~ - // ::= da # delete[] - // ::= de # * (unary) - // ::= dl # delete - // ::= dv # / - // ::= dV # /= - // ::= eo # ^ - // ::= eO # ^= - // ::= eq # == - // ::= ge # >= - // ::= gt # > - // ::= ix # [] - // ::= le # <= - // ::= ls # << - // ::= lS # <<= - // ::= lt # < - // ::= mi # - - // ::= mI # -= - // ::= ml # * - // ::= mL # *= - // ::= mm # -- (postfix in context) - // ::= na # new[] - // ::= ne # != - // ::= ng # - (unary) - // ::= nt # ! - // ::= nw # new - // ::= oo # || - // ::= or # | - // ::= oR # |= - // ::= pm # ->* - // ::= pl # + - // ::= pL # += - // ::= pp # ++ (postfix in context) - // ::= ps # + (unary) - // ::= pt # -> - // ::= qu # ? - // ::= rm # % - // ::= rM # %= - // ::= rs # >> - // ::= rS # >>= - // ::= cv # (cast) - // ::= v # vendor extended - // operator - - Operator TryParseOperator() { - switch (*m_read_ptr++) { - case 'a': - switch (*m_read_ptr++) { - case 'a': - return {"&&", OperatorKind::Binary}; - case 'd': - return {"&", OperatorKind::Unary}; - case 'n': - return {"&", OperatorKind::Binary}; - case 'N': - return {"&=", OperatorKind::Binary}; - case 'S': - return {"=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'c': - switch (*m_read_ptr++) { - case 'l': - return {"()", OperatorKind::Other}; - case 'm': - return {",", OperatorKind::Other}; - case 'o': - return {"~", OperatorKind::Unary}; - case 'v': - return {nullptr, OperatorKind::ConversionOperator}; - } - --m_read_ptr; - break; - case 'd': - switch (*m_read_ptr++) { - case 'a': - return {" delete[]", OperatorKind::Other}; - case 'e': - return {"*", OperatorKind::Unary}; - case 'l': - return {" delete", OperatorKind::Other}; - case 'v': - return {"/", OperatorKind::Binary}; - case 'V': - return {"/=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'e': - switch (*m_read_ptr++) { - case 'o': - return {"^", OperatorKind::Binary}; - case 'O': - return {"^=", OperatorKind::Binary}; - case 'q': - return {"==", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'g': - switch (*m_read_ptr++) { - case 'e': - return {">=", OperatorKind::Binary}; - case 't': - return {">", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'i': - switch (*m_read_ptr++) { - case 'x': - return {"[]", OperatorKind::Other}; - } - --m_read_ptr; - break; - case 'l': - switch (*m_read_ptr++) { - case 'e': - return {"<=", OperatorKind::Binary}; - case 's': - return {"<<", OperatorKind::Binary}; - case 'S': - return {"<<=", OperatorKind::Binary}; - case 't': - return {"<", OperatorKind::Binary}; - // case 'i': return { "?", OperatorKind::Binary }; - } - --m_read_ptr; - break; - case 'm': - switch (*m_read_ptr++) { - case 'i': - return {"-", OperatorKind::Binary}; - case 'I': - return {"-=", OperatorKind::Binary}; - case 'l': - return {"*", OperatorKind::Binary}; - case 'L': - return {"*=", OperatorKind::Binary}; - case 'm': - return {"--", OperatorKind::Postfix}; - } - --m_read_ptr; - break; - case 'n': - switch (*m_read_ptr++) { - case 'a': - return {" new[]", OperatorKind::Other}; - case 'e': - return {"!=", OperatorKind::Binary}; - case 'g': - return {"-", OperatorKind::Unary}; - case 't': - return {"!", OperatorKind::Unary}; - case 'w': - return {" new", OperatorKind::Other}; - } - --m_read_ptr; - break; - case 'o': - switch (*m_read_ptr++) { - case 'o': - return {"||", OperatorKind::Binary}; - case 'r': - return {"|", OperatorKind::Binary}; - case 'R': - return {"|=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'p': - switch (*m_read_ptr++) { - case 'm': - return {"->*", OperatorKind::Binary}; - case 's': - return {"+", OperatorKind::Unary}; - case 'l': - return {"+", OperatorKind::Binary}; - case 'L': - return {"+=", OperatorKind::Binary}; - case 'p': - return {"++", OperatorKind::Postfix}; - case 't': - return {"->", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'q': - switch (*m_read_ptr++) { - case 'u': - return {"?", OperatorKind::Ternary}; - } - --m_read_ptr; - break; - case 'r': - switch (*m_read_ptr++) { - case 'm': - return {"%", OperatorKind::Binary}; - case 'M': - return {"%=", OperatorKind::Binary}; - case 's': - return {">>", OperatorKind::Binary}; - case 'S': - return {">=", OperatorKind::Binary}; - } - --m_read_ptr; - break; - case 'v': - char digit = *m_read_ptr; - if (digit >= '0' && digit <= '9') { - m_read_ptr++; - return {nullptr, OperatorKind::Vendor}; - } - --m_read_ptr; - break; - } - --m_read_ptr; - return {nullptr, OperatorKind::NoMatch}; - } - - // ::= [r] [V] [K] - // ::= R # & ref-qualifier - // ::= O # && ref-qualifier - - int TryParseQualifiers(bool allow_cv, bool allow_ro) { - int qualifiers = QualifierNone; - char next = *m_read_ptr; - if (allow_cv) { - if (next == 'r') // restrict - { - qualifiers |= QualifierRestrict; - next = *++m_read_ptr; - } - if (next == 'V') // volatile - { - qualifiers |= QualifierVolatile; - next = *++m_read_ptr; - } - if (next == 'K') // const - { - qualifiers |= QualifierConst; - next = *++m_read_ptr; - } - } - if (allow_ro) { - if (next == 'R') { - ++m_read_ptr; - qualifiers |= QualifierReference; - } else if (next == 'O') { - ++m_read_ptr; - qualifiers |= QualifierRValueReference; - } - } - return qualifiers; - } - - // := _ # when number < 10 - // := __ _ # when number >= 10 - // extension := decimal-digit+ - - int TryParseDiscriminator() { - const char *discriminator_start = m_read_ptr; - - // Test the extension first, since it's what Clang uses - int discriminator_value = TryParseNumber(); - if (discriminator_value != -1) - return discriminator_value; - - char next = *m_read_ptr; - if (next == '_') { - next = *++m_read_ptr; - if (next == '_') { - ++m_read_ptr; - discriminator_value = TryParseNumber(); - if (discriminator_value != -1 && *m_read_ptr++ != '_') { - return discriminator_value; - } - } else if (next >= '0' && next <= '9') { - ++m_read_ptr; - return next - '0'; - } - } - - // Not a valid discriminator - m_read_ptr = discriminator_start; - return -1; - } - - //---------------------------------------------------- - // Parse methods - // - // Consume input starting from m_read_ptr and produce buffered output at - // m_write_ptr - // - // Failures return false and may leave m_read_ptr in an indeterminate state - //---------------------------------------------------- - - bool Parse(char character) { - if (*m_read_ptr++ == character) - return true; -#ifdef DEBUG_FAILURES - printf("*** Expected '%c'\n", character); -#endif - return false; - } - - // ::= [n] - - bool ParseNumber(bool allow_negative = false) { - if (allow_negative && *m_read_ptr == 'n') { - Write('-'); - ++m_read_ptr; - } - const char *before_digits = m_read_ptr; - while (true) { - unsigned char digit = *m_read_ptr - '0'; - if (digit > 9) - break; - ++m_read_ptr; - } - if (int digit_count = (int)(m_read_ptr - before_digits)) { - Write(before_digits, digit_count); - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Expected number\n"); -#endif - return false; - } - - // ::= S _ - // ::= S_ - // ::= Sa # ::std::allocator ::= Sb # - // ::std::basic_string ::= Ss # ::std::basic_string < char, - // ::std::char_traits, - // ::std::allocator > - // ::= Si # ::std::basic_istream - // > ::= So # ::std::basic_ostream > ::= Sd # - // ::std::basic_iostream > - - bool ParseSubstitution() { - const char *substitution; - switch (*m_read_ptr) { - case 'a': - substitution = "std::allocator"; - break; - case 'b': - substitution = "std::basic_string"; - break; - case 's': - substitution = "std::string"; - break; - case 'i': - substitution = "std::istream"; - break; - case 'o': - substitution = "std::ostream"; - break; - case 'd': - substitution = "std::iostream"; - break; - default: - // A failed attempt to parse a number will return -1 which turns out to be - // perfect here as S_ is the first substitution, S0_ the next and so - // forth - int substitution_index = TryParseBase36Number(); - if (*m_read_ptr++ != '_') { -#ifdef DEBUG_FAILURES - printf("*** Expected terminal _ in substitution\n"); -#endif - return false; - } - return RewriteSubstitution(substitution_index + 1); - } - Write(substitution); - ++m_read_ptr; - return true; - } - - // ::= F [Y] [] E - // - // ::= + # types are possible - // return type, then parameter types - - bool ParseFunctionType(int inner_qualifiers = QualifierNone) { -#ifdef DEBUG_FAILURES - printf("*** Function types not supported\n"); -#endif - // TODO: first steps toward an implementation follow, but they're far - // from complete. Function types tend to bracket other types eg: int (*)() - // when used as the type for "name" becomes int (*name)(). This makes - // substitution et al ... interesting. - return false; - -#if 0 // TODO - if (*m_read_ptr == 'Y') - ++m_read_ptr; - - int return_type_start_cookie = GetStartCookie(); - if (!ParseType()) - return false; - Write(' '); - - int insert_cookie = GetStartCookie(); - Write('('); - bool first_param = true; - int qualifiers = QualifierNone; - while (true) - { - switch (*m_read_ptr) - { - case 'E': - ++m_read_ptr; - Write(')'); - break; - case 'v': - ++m_read_ptr; - continue; - case 'R': - case 'O': - if (*(m_read_ptr + 1) == 'E') - { - qualifiers = TryParseQualifiers (false, true); - Parse('E'); - break; - } - // fallthrough - default: - { - if (first_param) - first_param = false; - else WriteCommaSpace(); - - if (!ParseType()) - return false; - continue; - } - } - break; - } - - if (qualifiers) - { - WriteQualifiers (qualifiers); - EndSubstitution (return_type_start_cookie); - } - - if (inner_qualifiers) - { - int qualifier_start_cookie = GetStartCookie(); - Write ('('); - WriteQualifiers (inner_qualifiers); - Write (')'); - ReorderRange (EndRange (qualifier_start_cookie), insert_cookie); - } - return true; -#endif // TODO - } - - // ::= A _ - // ::= A [] _ - - bool ParseArrayType(int qualifiers = QualifierNone) { -#ifdef DEBUG_FAILURES - printf("*** Array type unsupported\n"); -#endif - // TODO: We fail horribly when recalling these as substitutions or - // templates and trying to constify them eg: - // _ZN4llvm2cl5applyIA28_cNS0_3optIbLb0ENS0_6parserIbEEEEEEvRKT_PT0_ - // - // TODO: Chances are we don't do any better with references and pointers - // that should be type (&) [] instead of type & [] - - return false; - -#if 0 // TODO - if (*m_read_ptr == '_') - { - ++m_read_ptr; - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - WRITE(" []"); - return true; - } - else - { - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - { - const char *after_digits = m_read_ptr; - if (!Parse('_')) - return false; - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - Write(' '); - Write('['); - Write(before_digits, after_digits - before_digits); - } - else - { - int type_insertion_cookie = GetStartCookie(); - if (!ParseExpression()) - return false; - if (!Parse('_')) - return false; - - int type_start_cookie = GetStartCookie(); - if (!ParseType()) - return false; - if (qualifiers) - WriteQualifiers(qualifiers); - Write(' '); - Write('['); - ReorderRange (EndRange (type_start_cookie), type_insertion_cookie); - } - Write(']'); - return true; - } -#endif // TODO - } - - // ::= M - - // TODO: Determine how to handle pointers to function members correctly, - // currently not an issue because we don't have function types at all... - bool ParsePointerToMemberType() { - int insertion_cookie = GetStartCookie(); - Write(' '); - if (!ParseType()) - return false; - WRITE("::*"); - - int type_cookie = GetStartCookie(); - if (!ParseType()) - return false; - ReorderRange(EndRange(type_cookie), insertion_cookie); - return true; - } - - // ::= T_ # first template parameter - // ::= T _ - - bool ParseTemplateParam() { - int count = TryParseNumber(); - if (!Parse('_')) - return false; - - // When no number is present we get -1, which is convenient since T_ is the - // zeroth element T0_ is element 1, and so on - return RewriteTemplateArg(count + 1); - } - - // - // Dv _ - bool TryParseVectorType() { - const int dimension = TryParseNumber(); - if (dimension == -1) - return false; - - if (*m_read_ptr++ != '_') - return false; - - char vec_dimens[32] = {'\0'}; - ::snprintf(vec_dimens, sizeof vec_dimens - 1, " __vector(%d)", dimension); - ParseType(); - Write(vec_dimens); - return true; - } - - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= - // ::= P # pointer-to - // ::= R # reference-to - // ::= O # rvalue reference-to (C++0x) - // ::= C # complex pair (C 2000) - // ::= G # imaginary (C 2000) - // ::= Dp # pack expansion (C++0x) - // ::= U # vendor extended type qualifier - // extension := U # objc-type extension - // := # starts with Dv - - // ::= objcproto # k0 = 9 + - // + k1 := # - // PU<11+>objcproto 11objc_object 11objc_object -> id - - bool ParseType() { -#ifdef DEBUG_FAILURES - const char *failed_type = m_read_ptr; -#endif - int type_start_cookie = GetStartCookie(); - bool suppress_substitution = false; - - int qualifiers = TryParseQualifiers(true, false); - switch (*m_read_ptr) { - case 'D': - ++m_read_ptr; - switch (*m_read_ptr++) { - case 'p': - if (!ParseType()) - return false; - break; - case 'v': - if (!TryParseVectorType()) - return false; - break; - case 'T': - case 't': - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported type: %.3s\n", failed_type); -#endif - return false; - } - break; - case 'T': - ++m_read_ptr; - if (!ParseTemplateParam()) - return false; - break; - case 'M': - ++m_read_ptr; - if (!ParsePointerToMemberType()) - return false; - break; - case 'A': - ++m_read_ptr; - if (!ParseArrayType()) - return false; - break; - case 'F': - ++m_read_ptr; - if (!ParseFunctionType()) - return false; - break; - case 'S': - if (*++m_read_ptr == 't') { - ++m_read_ptr; - WriteStdPrefix(); - if (!ParseName()) - return false; - } else { - suppress_substitution = true; - if (!ParseSubstitution()) - return false; - } - break; - case 'P': { - switch (*++m_read_ptr) { - case 'F': - ++m_read_ptr; - if (!ParseFunctionType(QualifierPointer)) - return false; - break; - default: - if (!ParseType()) - return false; - Write('*'); - break; - } - break; - } - case 'R': { - ++m_read_ptr; - if (!ParseType()) - return false; - Write('&'); - break; - } - case 'O': { - ++m_read_ptr; - if (!ParseType()) - return false; - Write('&'); - Write('&'); - break; - } - case 'C': - case 'G': - case 'U': -#ifdef DEBUG_FAILURES - printf("*** Unsupported type: %.3s\n", failed_type); -#endif - return false; - // Test for common cases to avoid TryParseBuiltinType() overhead - case 'N': - case 'Z': - case 'L': - if (!ParseName()) - return false; - break; - default: - if (const char *builtin = TryParseBuiltinType()) { - Write(builtin); - suppress_substitution = true; - } else { - if (!ParseName()) - return false; - } - break; - } - - // Allow base substitutions to be suppressed, but always record - // substitutions for the qualified variant - if (!suppress_substitution) - EndSubstitution(type_start_cookie); - if (qualifiers) { - WriteQualifiers(qualifiers, false); - EndSubstitution(type_start_cookie); - } - return true; - } - - // ::= Ut [ ] _ - // ::= - // - // ::= Ul E [ ] _ - // - // ::= + # Parameter types or "v" if the lambda - // has no parameters - - bool ParseUnnamedTypeName(NameState &name_state) { - switch (*m_read_ptr++) { - case 't': { - int cookie = GetStartCookie(); - WRITE("'unnamed"); - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - Write(before_digits, m_read_ptr - before_digits); - if (!Parse('_')) - return false; - Write('\''); - name_state.last_name_range = EndRange(cookie); - return true; - } - case 'b': { - int cookie = GetStartCookie(); - WRITE("'block"); - const char *before_digits = m_read_ptr; - if (TryParseNumber() != -1) - Write(before_digits, m_read_ptr - before_digits); - if (!Parse('_')) - return false; - Write('\''); - name_state.last_name_range = EndRange(cookie); - return true; - } - case 'l': -#ifdef DEBUG_FAILURES - printf("*** Lambda type names unsupported\n"); -#endif - return false; - } -#ifdef DEBUG_FAILURES - printf("*** Unknown unnamed type %.3s\n", m_read_ptr - 2); -#endif - return false; - } - - // ::= C1 # complete object constructor - // ::= C2 # base object constructor - // ::= C3 # complete object allocating constructor - - bool ParseCtor(NameState &name_state) { - char next = *m_read_ptr; - if (next == '1' || next == '2' || next == '3' || next == '5') { - RewriteRange(name_state.last_name_range); - name_state.has_no_return_type = true; - ++m_read_ptr; - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Broken constructor\n"); -#endif - return false; - } - - // ::= D0 # deleting destructor - // ::= D1 # complete object destructor - // ::= D2 # base object destructor - - bool ParseDtor(NameState &name_state) { - char next = *m_read_ptr; - if (next == '0' || next == '1' || next == '2' || next == '5') { - Write('~'); - RewriteRange(name_state.last_name_range); - name_state.has_no_return_type = true; - ++m_read_ptr; - return true; - } -#ifdef DEBUG_FAILURES - printf("*** Broken destructor\n"); -#endif - return false; - } - - // See TryParseOperator() - - bool ParseOperatorName(NameState &name_state) { -#ifdef DEBUG_FAILURES - const char *operator_ptr = m_read_ptr; -#endif - Operator parsed_operator = TryParseOperator(); - if (parsed_operator.name) { - WRITE("operator"); - Write(parsed_operator.name); - return true; - } - - // Handle special operators - switch (parsed_operator.kind) { - case OperatorKind::Vendor: - WRITE("operator "); - return ParseSourceName(); - case OperatorKind::ConversionOperator: - ResetTemplateArgs(); - name_state.has_no_return_type = true; - WRITE("operator "); - return ParseType(); - default: -#ifdef DEBUG_FAILURES - printf("*** Unknown operator: %.2s\n", operator_ptr); -#endif - return false; - } - } - - // ::= - - bool ParseSourceName() { - int count = TryParseNumber(); - if (count == -1) { -#ifdef DEBUG_FAILURES - printf("*** Malformed source name, missing length count\n"); -#endif - return false; - } - - const char *next_m_read_ptr = m_read_ptr + count; - if (next_m_read_ptr > m_read_end) { -#ifdef DEBUG_FAILURES - printf("*** Malformed source name, premature termination\n"); -#endif - return false; - } - - if (count >= 10 && strncmp(m_read_ptr, "_GLOBAL__N", 10) == 0) - WRITE("(anonymous namespace)"); - else - Write(m_read_ptr, count); - - m_read_ptr = next_m_read_ptr; - return true; - } - - // ::= - // ::= - // ::= - // ::= - - bool ParseUnqualifiedName(NameState &name_state) { - // Note that these are detected directly in ParseNestedName for performance - // rather than switching on the same options twice - char next = *m_read_ptr; - switch (next) { - case 'C': - ++m_read_ptr; - return ParseCtor(name_state); - case 'D': - ++m_read_ptr; - return ParseDtor(name_state); - case 'U': - ++m_read_ptr; - return ParseUnnamedTypeName(name_state); - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': { - int name_start_cookie = GetStartCookie(); - if (!ParseSourceName()) - return false; - name_state.last_name_range = EndRange(name_start_cookie); - return true; - } - default: - return ParseOperatorName(name_state); - }; - } - - // ::= - // ::= St # ::std:: - // extension ::= StL - - bool ParseUnscopedName(NameState &name_state) { - if (*m_read_ptr == 'S' && *(m_read_ptr + 1) == 't') { - WriteStdPrefix(); - if (*(m_read_ptr += 2) == 'L') - ++m_read_ptr; - } - return ParseUnqualifiedName(name_state); - } - - bool ParseIntegerLiteral(const char *prefix, const char *suffix, - bool allow_negative) { - if (prefix) - Write(prefix); - if (!ParseNumber(allow_negative)) - return false; - if (suffix) - Write(suffix); - return Parse('E'); - } - - bool ParseBooleanLiteral() { - switch (*m_read_ptr++) { - case '0': - WRITE("false"); - break; - case '1': - WRITE("true"); - break; - default: -#ifdef DEBUG_FAILURES - printf("*** Boolean literal not 0 or 1\n"); -#endif - return false; - } - return Parse('E'); - } - - // ::= L E # - // integer literal - // ::= L E # - // floating literal - // ::= L E # - // string literal - // ::= L E # - // nullptr literal (i.e., "LDnE") - // ::= L _ E # - // complex floating point literal (C 2000) - // ::= L E # - // external name - - bool ParseExpressionPrimary() { - switch (*m_read_ptr++) { - case 'b': - return ParseBooleanLiteral(); - case 'x': - return ParseIntegerLiteral(nullptr, "ll", true); - case 'l': - return ParseIntegerLiteral(nullptr, "l", true); - case 'i': - return ParseIntegerLiteral(nullptr, nullptr, true); - case 'n': - return ParseIntegerLiteral("(__int128)", nullptr, true); - case 'j': - return ParseIntegerLiteral(nullptr, "u", false); - case 'm': - return ParseIntegerLiteral(nullptr, "ul", false); - case 'y': - return ParseIntegerLiteral(nullptr, "ull", false); - case 'o': - return ParseIntegerLiteral("(unsigned __int128)", nullptr, false); - case '_': - if (*m_read_ptr++ == 'Z') { - if (!ParseEncoding()) - return false; - return Parse('E'); - } - --m_read_ptr; - LLVM_FALLTHROUGH; - case 'w': - case 'c': - case 'a': - case 'h': - case 's': - case 't': - case 'f': - case 'd': - case 'e': -#ifdef DEBUG_FAILURES - printf("*** Unsupported primary expression %.5s\n", m_read_ptr - 1); -#endif - return false; - case 'T': -// Invalid mangled name per -// http://sourcerytools.com/pipermail/cxx-abi-dev/2011-August/002422.html -#ifdef DEBUG_FAILURES - printf("*** Invalid primary expr encoding\n"); -#endif - return false; - default: - --m_read_ptr; - Write('('); - if (!ParseType()) - return false; - Write(')'); - if (!ParseNumber()) - return false; - return Parse('E'); - } - } - - // ::= - // ::= - // ::= - - bool ParseUnresolvedType() { - int type_start_cookie = GetStartCookie(); - switch (*m_read_ptr++) { - case 'T': - if (!ParseTemplateParam()) - return false; - EndSubstitution(type_start_cookie); - return true; - case 'S': { - if (*m_read_ptr != 't') - return ParseSubstitution(); - - ++m_read_ptr; - WriteStdPrefix(); - NameState type_name = {}; - if (!ParseUnqualifiedName(type_name)) - return false; - EndSubstitution(type_start_cookie); - return true; - } - case 'D': - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported unqualified type: %3s\n", m_read_ptr - 1); -#endif - return false; - } - } - - // ::= # - // unresolved name - // extension ::= # - // unresolved operator-function-id - // extension ::= # - // unresolved operator template-id - // ::= on # - // unresolved operator-function-id - // ::= on # - // unresolved operator template-id - // ::= dn # - // destructor or pseudo-destructor; - // # - // e.g. - // ~X - // or - // ~X - - bool ParseBaseUnresolvedName() { -#ifdef DEBUG_FAILURES - printf("*** Base unresolved name unsupported\n"); -#endif - return false; - } - - // - // extension ::= srN [] - // * E - // ::= [gs] # x - // or (with "gs") ::x - // ::= [gs] sr + E - // - // # - // A::x, - // N::y, - // A::z; - // "gs" - // means - // leading - // "::" - // ::= sr # - // T::x / decltype(p)::x - // extension ::= sr - // - // # - // T::N::x - // /decltype(p)::N::x - // (ignored) ::= srN + - // E - - bool ParseUnresolvedName() { -#ifdef DEBUG_FAILURES - printf("*** Unresolved names not supported\n"); -#endif - // TODO: grammar for all of this seems unclear... - return false; - -#if 0 // TODO - if (*m_read_ptr == 'g' && *(m_read_ptr + 1) == 's') - { - m_read_ptr += 2; - WriteNamespaceSeparator(); - } -#endif // TODO - } - - // ::= - // ::= - // ::= - // - // ::= cl + E # - // call - // ::= cv # - // conversion with one argument - // ::= cv _ * E # - // conversion with a different number of arguments - // ::= [gs] nw * _ E # new - // (expr-list) type - // ::= [gs] nw * _ # new - // (expr-list) type (init) - // ::= [gs] na * _ E # - // new[] (expr-list) type - // ::= [gs] na * _ # - // new[] (expr-list) type (init) - // ::= [gs] dl # - // delete expression - // ::= [gs] da # - // delete[] expression - // ::= pp_ # - // prefix ++ - // ::= mm_ # - // prefix -- - // ::= ti # - // typeid (type) - // ::= te # - // typeid (expression) - // ::= dc # - // dynamic_cast (expression) - // ::= sc # - // static_cast (expression) - // ::= cc # - // const_cast (expression) - // ::= rc # - // reinterpret_cast (expression) - // ::= st # - // sizeof (a type) - // ::= sz # - // sizeof (an expression) - // ::= at # - // alignof (a type) - // ::= az # - // alignof (an expression) - // ::= nx # - // noexcept (expression) - // ::= - // ::= - // ::= dt # - // expr.name - // ::= pt # - // expr->name - // ::= ds # - // expr.*expr - // ::= sZ # - // size of a parameter pack - // ::= sZ # - // size of a function parameter pack - // ::= sp # - // pack expansion - // ::= tw # - // throw expression - // ::= tr # - // throw with no operand (rethrow) - // ::= # - // f(p), N::f(p), ::f(p), - // # - // freestanding - // dependent - // name - // (e.g., - // T::x), - // # - // objectless - // nonstatic - // member - // reference - // ::= - - bool ParseExpression() { - Operator expression_operator = TryParseOperator(); - switch (expression_operator.kind) { - case OperatorKind::Unary: - Write(expression_operator.name); - Write('('); - if (!ParseExpression()) - return false; - Write(')'); - return true; - case OperatorKind::Binary: - if (!ParseExpression()) - return false; - Write(expression_operator.name); - return ParseExpression(); - case OperatorKind::Ternary: - if (!ParseExpression()) - return false; - Write('?'); - if (!ParseExpression()) - return false; - Write(':'); - return ParseExpression(); - case OperatorKind::NoMatch: - break; - case OperatorKind::Other: - default: -#ifdef DEBUG_FAILURES - printf("*** Unsupported operator: %s\n", expression_operator.name); -#endif - return false; - } - - switch (*m_read_ptr++) { - case 'T': - return ParseTemplateParam(); - case 'L': - return ParseExpressionPrimary(); - case 's': - if (*m_read_ptr++ == 'r') - return ParseUnresolvedName(); - --m_read_ptr; - LLVM_FALLTHROUGH; - default: - return ParseExpressionPrimary(); - } - } - - // ::= # - // type or template - // ::= X E # - // expression - // ::= # - // simple expressions - // ::= J * E # - // argument pack - // ::= LZ E # - // extension - - bool ParseTemplateArg() { - switch (*m_read_ptr) { - case 'J': -#ifdef DEBUG_FAILURES - printf("*** Template argument packs unsupported\n"); -#endif - return false; - case 'X': - ++m_read_ptr; - if (!ParseExpression()) - return false; - return Parse('E'); - case 'L': - ++m_read_ptr; - return ParseExpressionPrimary(); - default: - return ParseType(); - } - } - - // ::= I * E - // extension, the abi says + - - bool ParseTemplateArgs(bool record_template_args = false) { - if (record_template_args) - ResetTemplateArgs(); - - bool first_arg = true; - while (*m_read_ptr != 'E') { - if (first_arg) - first_arg = false; - else - WriteCommaSpace(); - - int template_start_cookie = GetStartCookie(); - if (!ParseTemplateArg()) - return false; - if (record_template_args) - EndTemplateArg(template_start_cookie); - } - ++m_read_ptr; - return true; - } - - // ::= N [] [] - // E - // ::= N [] [] - // E - // - // ::= - // ::= - // ::= - // ::= - // ::= # empty - // ::= - // ::= - // extension ::= L - // - // ::=